Working shadow volumes! :-D
This commit is contained in:
parent
6d3965b35e
commit
2a6009e8f2
3 changed files with 53 additions and 45 deletions
34
src/Game.cpp
34
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>
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Reference in a new issue