From 6d3965b35edf5f03cd065d42af31867acf1f4637 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 24 Dec 2009 02:47:35 +0100 Subject: Make shadow volumes visible --- src/Game.cpp | 81 ++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 32 deletions(-) (limited to 'src/Game.cpp') diff --git a/src/Game.cpp b/src/Game.cpp index 205125a..1b23222 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -30,27 +30,21 @@ namespace Zoom { -Game::Game(bool multisample) : playerPos(vmml::vec3f::ZERO), playerRotY(vmml::mat4f::IDENTITY), playerRotX(0), +Game::Game() : playerPos(vmml::vec3f::ZERO), playerRotY(vmml::mat4f::IDENTITY), playerRotX(0), input(0), lightPos(0) { - glClearColor(0.0, 0.0, 0.0, 1.0); - glClearDepth(1.0); glEnable(GL_DEPTH_TEST); + glEnable(GL_STENCIL_TEST); glEnable(GL_BLEND); -#ifndef _WIN32 - if(multisample) - glEnable(GL_MULTISAMPLE_ARB); -#endif + glEnable(GL_MULTISAMPLE_ARB); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, vmml::vec4f(0.1, 0.1, 0.1, 1).array); glLightfv(GL_LIGHT0, GL_AMBIENT, vmml::vec4f::ZERO.array); glLightfv(GL_LIGHT0, GL_DIFFUSE, vmml::vec4f::ONE.array); glLightfv(GL_LIGHT0, GL_SPECULAR, vmml::vec4f::ONE.array); - glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0); glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.2); - glDisable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); @@ -72,6 +66,20 @@ bool Game::loadLevel(const std::string &name) { return level; } +void Game::resize(int width, int height) { + if(height == 0) { + height = 1; + } + + + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(MathUtil::perspective(50.0f, (float)width/(float)height, 0.1).array); + + glMatrixMode(GL_MODELVIEW); + + glViewport(0, 0, width, height); +} + void Game::turn(float x, float y) { playerRotY.rotate_y(-x*M_PI/180/10); @@ -107,29 +115,29 @@ void Game::run(int delta) { void Game::render() { int i; - float light[] = {0, 0, 0, 1}; + vmml::vec3f light(vmml::vec3f::ZERO); if(lightPos < 12000) i = lightPos; else i = 24000 - lightPos; if(i < 4000) { - light[0] = 0.0; - light[2] = -i * 0.001; + light.x() = 0.0; + light.z() = -i * 0.001; } else if(i < 8000) { - light[0] = (i-4000) * 0.001; - light[2] = -4.0; + light.x() = (i-4000) * 0.001; + light.z() = -4.0; } else if(i < 12000) { - light[0] = 4.0; - light[2] = -4.0 - (i-8000) * 0.001; + light.x() = 4.0; + light.z() = -4.0 - (i-8000) * 0.001; } else { - light[0] = 4.0; - light[2] = -8.0; + light.x() = 4.0; + light.z() = -8.0; } - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); vmml::mat4f transform(playerRotY), inverse; transform.rotate_x(playerRotX); @@ -138,28 +146,37 @@ void Game::render() { glLoadMatrixf(inverse.array); - glLightfv(GL_LIGHT0, GL_POSITION, light); - - renderer.render(triangles); + renderer.render(triangles, light); Shader::disable(); - glDepthFunc(GL_LEQUAL); - glBlendFunc(GL_ONE, GL_ZERO); + 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_LINES); + glBegin(GL_TRIANGLES); + for(std::vector::iterator t = triangles.begin(); t != triangles.end(); ++t) { + ShadowVolume v(t->triangle, light); + v.render(); + } + glEnd(); - glColor3f(1, 1, 0); + 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); - - for(int i = 0; i < 3; ++i) { - glVertex3fv(v.getVertex(i).array); - glVertex3fv((v.getVertex(i)+v.getDirection(i)).array); - } + v.render(); } - glEnd(); + + glFrontFace(GL_CCW); + glDepthMask(GL_TRUE); + glDepthFunc(GL_LEQUAL); + glBlendEquation(GL_FUNC_ADD); } } -- cgit v1.2.3