Working shadow volumes! :-D

This commit is contained in:
Matthias Schiffer 2009-12-24 03:24:53 +01:00
parent 6d3965b35e
commit 2a6009e8f2
3 changed files with 53 additions and 45 deletions

View file

@ -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);
}
}

View file

@ -21,6 +21,7 @@
#define ZOOM_GAME_H_
#include "Renderer.h"
#include <boost/shared_ptr.hpp>
#include <string>

View file

@ -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);
glStencilFunc(GL_EQUAL, 0, std::numeric_limits<GLuint>::max());
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
t = triangles.begin();
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();