summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Game.cpp81
-rw-r--r--src/Game.h4
-rw-r--r--src/Renderer.cpp4
-rw-r--r--src/Renderer.h11
-rw-r--r--src/ShadowVolume.cpp36
-rw-r--r--src/ShadowVolume.h5
-rw-r--r--src/zoom.cpp30
7 files changed, 106 insertions, 65 deletions
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<BSPTree::TriangleRecord>::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<BSPTree::TriangleRecord>::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);
}
}
diff --git a/src/Game.h b/src/Game.h
index f6b775b..7f936b4 100644
--- a/src/Game.h
+++ b/src/Game.h
@@ -38,10 +38,12 @@ class Game {
RIGHT = (1 << 3)
};
- Game(bool multisample);
+ Game();
bool loadLevel(const std::string &name);
+ void resize(int width, int height);
+
void setInput(unsigned input) {
this->input = input;
}
diff --git a/src/Renderer.cpp b/src/Renderer.cpp
index 8b3d689..8aaf9c5 100644
--- a/src/Renderer.cpp
+++ b/src/Renderer.cpp
@@ -27,7 +27,7 @@ Renderer::Renderer() : activeTexture(0), renderVisitor(this) {
lightShader = boost::shared_ptr<Shader>(Shader::load("light.vert", "light.frag"));
}
-void Renderer::render(const BSPTree &tree) {
+/*void Renderer::render(const BSPTree &tree) {
vmml::mat4f transform, inverseTransform;
glGetFloatv(GL_MODELVIEW_MATRIX, transform.array);
@@ -39,7 +39,7 @@ void Renderer::render(const BSPTree &tree) {
tree.visit(renderVisitor, viewPoint);
glEnd();
-}
+}*/
void Renderer::renderTriangle(const Triangle &t) {
glColor4fv(t.getColor().array);
diff --git a/src/Renderer.h b/src/Renderer.h
index ae9af4a..eed65bb 100644
--- a/src/Renderer.h
+++ b/src/Renderer.h
@@ -23,6 +23,7 @@
#include "gl.h"
#include "BSPTree.h"
#include "Shader.h"
+#include <limits>
namespace Zoom {
@@ -31,13 +32,17 @@ class Renderer {
public:
Renderer();
- void render(const BSPTree &tree);
+ //void render(const BSPTree &tree);
template <typename T>
- void render(const T &triangles) {
+ void render(const T &triangles, const vmml::vec3f &lightPos) {
+ glLightfv(GL_LIGHT0, GL_POSITION, vmml::vec4f(lightPos, 1).array);
+
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);
typename T::const_iterator t = triangles.begin();
if(t == triangles.end())
@@ -54,6 +59,8 @@ class Renderer {
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);
t = triangles.begin();
diff --git a/src/ShadowVolume.cpp b/src/ShadowVolume.cpp
index b0c25ca..67a44db 100644
--- a/src/ShadowVolume.cpp
+++ b/src/ShadowVolume.cpp
@@ -20,19 +20,19 @@
#include "ShadowVolume.h"
#include "MathUtil.h"
+#include "gl.h"
+
namespace Zoom {
-ShadowVolume::ShadowVolume(const Triangle &t, const vmml::vec3f &lightPos) {
+ShadowVolume::ShadowVolume(const Triangle &t, const vmml::vec3f &lightPos) : visible(true) {
MathUtil::Plane trianglePlane(t);
for(int i = 0; i < 3; ++i) {
rays[i].p = t.getVertex(i);
}
- if(trianglePlane.isBehind(lightPos)) {
- for(int i = 0; i < 3; ++i) {
- rays[i].dir = vmml::vec3f::ZERO;
- }
+ if(trianglePlane.isInFront(lightPos)) {
+ visible = false;
return;
}
@@ -42,4 +42,30 @@ ShadowVolume::ShadowVolume(const Triangle &t, const vmml::vec3f &lightPos) {
}
}
+void ShadowVolume::render() const {
+ if(!visible)
+ return;
+
+ glVertex3fv(rays[0].p.array);
+ glVertex3fv(rays[1].p.array);
+ glVertex3fv(rays[2].p.array);
+
+ for(int i = 0; i < 3; ++i) {
+ const Ray &r1 = rays[i];
+ const Ray &r2 = rays[(i+1)%3];
+
+ glVertex3fv(r1.p.array);
+ glVertex4fv(vmml::vec4f(r1.dir, 0).array);
+ glVertex3fv(r2.p.array);
+
+ glVertex3fv(r2.p.array);
+ glVertex4fv(vmml::vec4f(r1.dir, 0).array);
+ glVertex4fv(vmml::vec4f(r2.dir, 0).array);
+ }
+
+ glVertex4fv(vmml::vec4f(rays[2].dir, 0).array);
+ glVertex4fv(vmml::vec4f(rays[1].dir, 0).array);
+ glVertex4fv(vmml::vec4f(rays[0].dir, 0).array);
+}
+
}
diff --git a/src/ShadowVolume.h b/src/ShadowVolume.h
index e33e19c..81a0a33 100644
--- a/src/ShadowVolume.h
+++ b/src/ShadowVolume.h
@@ -21,6 +21,7 @@
#define ZOOM_SHADOWVOLUME_H_
#include <vmmlib/vector.hpp>
+#include <vmmlib/matrix.hpp>
namespace Zoom {
@@ -39,7 +40,11 @@ class ShadowVolume {
return rays[i].dir;
}
+ void render() const;
+
private:
+ bool visible;
+
struct Ray {
vmml::vec3f p;
vmml::vec3f dir;
diff --git a/src/zoom.cpp b/src/zoom.cpp
index 8193d6a..8467816 100644
--- a/src/zoom.cpp
+++ b/src/zoom.cpp
@@ -35,20 +35,6 @@
#include <unistd.h>
#endif
-void resize(int width, int height) {
- if(height == 0) {
- height = 1;
- }
-
-
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(Zoom::MathUtil::perspective(50.0f, (float)width/(float)height, 0.1).array);
-
- glMatrixMode(GL_MODELVIEW);
-
- glViewport(0, 0, width, height);
-}
-
#ifdef _WIN32
@@ -250,12 +236,13 @@ bool XIInit(Display *disp, int *opcode) {
return true;
}
-bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, bool *multisample, int *xi_opcode, int *pointer) {
+bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, int *xi_opcode, int *pointer) {
static const int msAttributeList[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_X_RENDERABLE, True,
GLX_DOUBLEBUFFER, True,
GLX_DEPTH_SIZE, 1,
+ GLX_STENCIL_SIZE, 1,
GLX_SAMPLE_BUFFERS, 1,
GLX_SAMPLES, 4,
None};
@@ -265,13 +252,13 @@ bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, bool *mul
GLX_X_RENDERABLE, True,
GLX_DOUBLEBUFFER, True,
GLX_DEPTH_SIZE, 1,
+ GLX_STENCIL_SIZE, 1,
None};
if(!XIInit(disp, xi_opcode))
return false;
bool ok = false;
- *multisample = true;
int nElements;
GLXFBConfig *fbConfig = glXChooseFBConfig(disp, DefaultScreen(disp), msAttributeList, &nElements);
@@ -280,7 +267,6 @@ bool GLXinit(Display *disp, Atom windele, Window *wnd, GLXContext *gc, bool *mul
XFree(fbConfig);
}
- *multisample = false;
fbConfig = glXChooseFBConfig(disp, DefaultScreen(disp), attributeList, &nElements);
}
@@ -362,17 +348,15 @@ int main() {
Window wnd;
GLXContext gc;
- bool multisample;
int xi_opcode;
int pointer;
- if(!GLXinit(disp, windele, &wnd, &gc, &multisample, &xi_opcode, &pointer))
+ if(!GLXinit(disp, windele, &wnd, &gc, &xi_opcode, &pointer))
return 1;
glewInit();
- resize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
-
- Zoom::Game game(multisample);
+ Zoom::Game game;
+ game.resize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
GLint samples;
glGetIntegerv(GL_SAMPLES, &samples);
@@ -394,7 +378,7 @@ int main() {
XNextEvent(disp, &event);
switch(event.type) {
case ConfigureNotify:
- resize(event.xconfigure.width, event.xconfigure.height);
+ game.resize(event.xconfigure.width, event.xconfigure.height);
break;
case ClientMessage: