diff options
author | Matthias Schiffer <matthias@gamezock.de> | 2009-12-24 03:24:53 +0100 |
---|---|---|
committer | Matthias Schiffer <matthias@gamezock.de> | 2009-12-24 03:24:53 +0100 |
commit | 2a6009e8f24be3909239a5ab6e6d6fb53d0c5845 (patch) | |
tree | c2ec60984761ad8bc930338f035e8ad8da8dfb38 /src | |
parent | 6d3965b35edf5f03cd065d42af31867acf1f4637 (diff) | |
download | zoom++-2a6009e8f24be3909239a5ab6e6d6fb53d0c5845.tar zoom++-2a6009e8f24be3909239a5ab6e6d6fb53d0c5845.zip |
Working shadow volumes! :-D
Diffstat (limited to 'src')
-rw-r--r-- | src/Game.cpp | 34 | ||||
-rw-r--r-- | src/Game.h | 1 | ||||
-rw-r--r-- | src/Renderer.h | 63 |
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); } } @@ -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(); |