summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-12-24 03:24:53 +0100
committerMatthias Schiffer <matthias@gamezock.de>2009-12-24 03:24:53 +0100
commit2a6009e8f24be3909239a5ab6e6d6fb53d0c5845 (patch)
treec2ec60984761ad8bc930338f035e8ad8da8dfb38
parent6d3965b35edf5f03cd065d42af31867acf1f4637 (diff)
downloadzoom++-2a6009e8f24be3909239a5ab6e6d6fb53d0c5845.tar
zoom++-2a6009e8f24be3909239a5ab6e6d6fb53d0c5845.zip
Working shadow volumes! :-D
-rw-r--r--src/Game.cpp34
-rw-r--r--src/Game.h1
-rw-r--r--src/Renderer.h63
3 files changed, 53 insertions, 45 deletions
diff --git a/src/Game.cpp b/src/Game.cpp
index 1b23222..d265e83 100644
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -55,6 +55,8 @@ Game::Game() : playerPos(vmml::vec3f::ZERO), playerRotY(vmml::mat4f::IDENTITY),
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
+ glEnable(GL_STENCIL_TEST);
+
loadLevel("level.xml");
triangles.insert(triangles.end(), level->getRooms().front().walls.begin(), level->getRooms().front().walls.end());
std::sort(triangles.begin(), triangles.end(), Renderer::TextureSorter());
@@ -137,7 +139,7 @@ void Game::render() {
light.z() = -8.0;
}
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
vmml::mat4f transform(playerRotY), inverse;
transform.rotate_x(playerRotX);
@@ -147,36 +149,6 @@ void Game::render() {
glLoadMatrixf(inverse.array);
renderer.render(triangles, light);
-
- Shader::disable();
- glDepthMask(GL_FALSE);
- glBlendFunc(GL_ONE, GL_ONE);
- glBlendEquation(GL_FUNC_ADD);
- glDepthFunc(GL_GREATER);
- glColor3f(0.05, 0.05, 0.05);
- glFrontFace(GL_CCW);
-
- glBegin(GL_TRIANGLES);
- for(std::vector<BSPTree::TriangleRecord>::iterator t = triangles.begin(); t != triangles.end(); ++t) {
- ShadowVolume v(t->triangle, light);
- v.render();
- }
- glEnd();
-
- glFrontFace(GL_CW);
- glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
-
- glBegin(GL_TRIANGLES);
- for(std::vector<BSPTree::TriangleRecord>::iterator t = triangles.begin(); t != triangles.end(); ++t) {
- ShadowVolume v(t->triangle, light);
- v.render();
- }
- glEnd();
-
- glFrontFace(GL_CCW);
- glDepthMask(GL_TRUE);
- glDepthFunc(GL_LEQUAL);
- glBlendEquation(GL_FUNC_ADD);
}
}
diff --git a/src/Game.h b/src/Game.h
index 7f936b4..cb90c42 100644
--- a/src/Game.h
+++ b/src/Game.h
@@ -21,6 +21,7 @@
#define ZOOM_GAME_H_
#include "Renderer.h"
+
#include <boost/shared_ptr.hpp>
#include <string>
diff --git a/src/Renderer.h b/src/Renderer.h
index eed65bb..8c531a5 100644
--- a/src/Renderer.h
+++ b/src/Renderer.h
@@ -23,6 +23,7 @@
#include "gl.h"
#include "BSPTree.h"
#include "Shader.h"
+#include "ShadowVolume.h"
#include <limits>
@@ -36,38 +37,72 @@ class Renderer {
template <typename T>
void render(const T &triangles, const vmml::vec3f &lightPos) {
+ if(triangles.empty())
+ return;
+
+ // Create shadow volumes
+ std::vector<ShadowVolume> shadowVolumes;
+ for(typename T::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
+ shadowVolumes.push_back(ShadowVolume(t->triangle, lightPos));
+ }
+
+
glLightfv(GL_LIGHT0, GL_POSITION, vmml::vec4f(lightPos, 1).array);
+ // Render with ambient light
Shader::enable(ambientShader);
glBlendFunc(GL_ONE, GL_ZERO);
glDepthFunc(GL_LEQUAL);
- //glStencilFunc(GL_ALWAYS, 0, std::numeric_limits<GLuint>::max());
- //glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
+ glStencilFunc(GL_ALWAYS, 0, std::numeric_limits<GLuint>::max());
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- typename T::const_iterator t = triangles.begin();
- if(t == triangles.end())
- return;
-
- useTexture(t->triangle.getTexture());
+ useTexture(triangles.front().triangle.getTexture());
glBegin(GL_TRIANGLES);
- for(; t != triangles.end(); ++t) {
+ for(typename T::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
renderTriangle(t->triangle);
}
glEnd();
+ // Render shadow volumes
+ glClear(GL_STENCIL_BUFFER_BIT);
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ glDepthMask(GL_FALSE);
+ Shader::disable();
+
+ glFrontFace(GL_CCW);
+ glStencilOp(GL_KEEP, GL_INCR_WRAP, GL_KEEP);
+
+ glBegin(GL_TRIANGLES);
+ for(std::vector<ShadowVolume>::iterator v = shadowVolumes.begin(); v != shadowVolumes.end(); ++v) {
+ v->render();
+ }
+ glEnd();
+
+ glFrontFace(GL_CW);
+ glStencilOp(GL_KEEP, GL_DECR_WRAP, GL_KEEP);
+
+ glBegin(GL_TRIANGLES);
+ for(std::vector<ShadowVolume>::iterator v = shadowVolumes.begin(); v != shadowVolumes.end(); ++v) {
+ v->render();
+ }
+ glEnd();
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glDepthMask(GL_TRUE);
+ glFrontFace(GL_CCW);
+
+ // Render with point light
Shader::enable(lightShader);
glBlendFunc(GL_ONE, GL_ONE);
glDepthFunc(GL_EQUAL);
- //glStencilFunc(GL_EQUAL, 0, std::numeric_limits<GLuint>::max());
- //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-
- t = triangles.begin();
+ glStencilFunc(GL_EQUAL, 0, std::numeric_limits<GLuint>::max());
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- useTexture(t->triangle.getTexture());
+ useTexture(triangles.front().triangle.getTexture());
glBegin(GL_TRIANGLES);
- for(; t != triangles.end(); ++t) {
+ for(typename T::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
renderTriangle(t->triangle);
}
glEnd();