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);
|
glEnable(GL_CULL_FACE);
|
||||||
glFrontFace(GL_CCW);
|
glFrontFace(GL_CCW);
|
||||||
|
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
|
||||||
loadLevel("level.xml");
|
loadLevel("level.xml");
|
||||||
triangles.insert(triangles.end(), level->getRooms().front().walls.begin(), level->getRooms().front().walls.end());
|
triangles.insert(triangles.end(), level->getRooms().front().walls.begin(), level->getRooms().front().walls.end());
|
||||||
std::sort(triangles.begin(), triangles.end(), Renderer::TextureSorter());
|
std::sort(triangles.begin(), triangles.end(), Renderer::TextureSorter());
|
||||||
|
@ -137,7 +139,7 @@ void Game::render() {
|
||||||
light.z() = -8.0;
|
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;
|
vmml::mat4f transform(playerRotY), inverse;
|
||||||
transform.rotate_x(playerRotX);
|
transform.rotate_x(playerRotX);
|
||||||
|
@ -147,36 +149,6 @@ void Game::render() {
|
||||||
glLoadMatrixf(inverse.array);
|
glLoadMatrixf(inverse.array);
|
||||||
|
|
||||||
renderer.render(triangles, light);
|
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_
|
#define ZOOM_GAME_H_
|
||||||
|
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "gl.h"
|
#include "gl.h"
|
||||||
#include "BSPTree.h"
|
#include "BSPTree.h"
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
|
#include "ShadowVolume.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,38 +37,72 @@ class Renderer {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void render(const T &triangles, const vmml::vec3f &lightPos) {
|
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);
|
glLightfv(GL_LIGHT0, GL_POSITION, vmml::vec4f(lightPos, 1).array);
|
||||||
|
|
||||||
|
// Render with ambient light
|
||||||
Shader::enable(ambientShader);
|
Shader::enable(ambientShader);
|
||||||
glBlendFunc(GL_ONE, GL_ZERO);
|
glBlendFunc(GL_ONE, GL_ZERO);
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
//glStencilFunc(GL_ALWAYS, 0, std::numeric_limits<GLuint>::max());
|
glStencilFunc(GL_ALWAYS, 0, std::numeric_limits<GLuint>::max());
|
||||||
//glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
|
|
||||||
typename T::const_iterator t = triangles.begin();
|
useTexture(triangles.front().triangle.getTexture());
|
||||||
if(t == triangles.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
useTexture(t->triangle.getTexture());
|
|
||||||
|
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
for(; t != triangles.end(); ++t) {
|
for(typename T::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
|
||||||
renderTriangle(t->triangle);
|
renderTriangle(t->triangle);
|
||||||
}
|
}
|
||||||
glEnd();
|
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);
|
Shader::enable(lightShader);
|
||||||
glBlendFunc(GL_ONE, GL_ONE);
|
glBlendFunc(GL_ONE, GL_ONE);
|
||||||
glDepthFunc(GL_EQUAL);
|
glDepthFunc(GL_EQUAL);
|
||||||
//glStencilFunc(GL_EQUAL, 0, std::numeric_limits<GLuint>::max());
|
glStencilFunc(GL_EQUAL, 0, std::numeric_limits<GLuint>::max());
|
||||||
//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
|
|
||||||
t = triangles.begin();
|
useTexture(triangles.front().triangle.getTexture());
|
||||||
|
|
||||||
useTexture(t->triangle.getTexture());
|
|
||||||
|
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
for(; t != triangles.end(); ++t) {
|
for(typename T::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
|
||||||
renderTriangle(t->triangle);
|
renderTriangle(t->triangle);
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
Reference in a new issue