From 2a6009e8f24be3909239a5ab6e6d6fb53d0c5845 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 24 Dec 2009 03:24:53 +0100 Subject: Working shadow volumes! :-D --- src/Game.cpp | 34 +++---------------------------- src/Game.h | 1 + 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::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::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 #include 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 @@ -36,38 +37,72 @@ class Renderer { template void render(const T &triangles, const vmml::vec3f &lightPos) { + if(triangles.empty()) + return; + + // Create shadow volumes + std::vector 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::max()); - //glStencilOp(GL_KEEP, GL_INCR, GL_KEEP); + glStencilFunc(GL_ALWAYS, 0, std::numeric_limits::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::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::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::max()); - //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - - t = triangles.begin(); + glStencilFunc(GL_EQUAL, 0, std::numeric_limits::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(); -- cgit v1.2.3