summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-12-18 13:31:07 +0100
committerMatthias Schiffer <matthias@gamezock.de>2009-12-18 13:31:07 +0100
commit4e3efa239c9bcb5dd26b4ad9a4d43d4d6a266e6f (patch)
treee39e9698513687a3213ecae7eab942bce88b12d6
parentb3b74dc2afe4c67a6b74c2a681aa7bbad7077511 (diff)
downloadzoom++-4e3efa239c9bcb5dd26b4ad9a4d43d4d6a266e6f.tar
zoom++-4e3efa239c9bcb5dd26b4ad9a4d43d4d6a266e6f.zip
Use multi-pass rendering with seperate ambient and light shaders
-rw-r--r--shader/ambient.frag8
-rw-r--r--shader/ambient.vert8
-rw-r--r--shader/light.frag (renamed from shader/default.frag)12
-rw-r--r--shader/light.vert (renamed from shader/default.vert)3
-rw-r--r--src/Game.cpp8
-rw-r--r--src/Renderer.cpp6
-rw-r--r--src/Renderer.h25
-rw-r--r--src/Shader.cpp60
-rw-r--r--src/Shader.h29
-rw-r--r--src/zoom.cpp41
10 files changed, 150 insertions, 50 deletions
diff --git a/shader/ambient.frag b/shader/ambient.frag
new file mode 100644
index 0000000..cef0a3b
--- /dev/null
+++ b/shader/ambient.frag
@@ -0,0 +1,8 @@
+uniform sampler2D tex;
+
+varying vec4 ambient;
+
+
+void main() {
+ gl_FragColor = ambient * texture2D(tex, gl_TexCoord[0].st);
+}
diff --git a/shader/ambient.vert b/shader/ambient.vert
new file mode 100644
index 0000000..41a36e7
--- /dev/null
+++ b/shader/ambient.vert
@@ -0,0 +1,8 @@
+varying vec4 ambient;
+
+void main() {
+ ambient = gl_LightModel.ambient * gl_FrontMaterial.ambient;
+
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_Position = ftransform();
+}
diff --git a/shader/default.frag b/shader/light.frag
index e2acad0..c3cdbfb 100644
--- a/shader/default.frag
+++ b/shader/light.frag
@@ -1,6 +1,6 @@
uniform sampler2D tex;
-varying vec4 diffuse, ambientGlobal, ambient;
+varying vec4 diffuse, ambient;
varying vec3 normal, pos;
@@ -10,8 +10,6 @@ void main() {
vec4 color, specularColor;
float dist, att, specularFactor;
- color = ambientGlobal;
-
n = normalize(normal);
l = gl_LightSource[0].position.xyz - pos;
@@ -26,7 +24,7 @@ void main() {
att = 1.0 / (gl_LightSource[0].constantAttenuation +
gl_LightSource[0].linearAttenuation * dist +
gl_LightSource[0].quadraticAttenuation * dist * dist);
- color += att * (diffuse * NdotL + ambient);
+ color = att * (diffuse * NdotL + ambient);
refl = normalize(reflect(-l, n));
eye = normalize(-pos);
@@ -34,10 +32,10 @@ void main() {
RdotE = max(dot(refl, eye), 0.0);
specularFactor = att * pow(RdotE, gl_FrontMaterial.shininess);
specularColor = specularFactor * gl_FrontMaterial.specular * gl_LightSource[0].specular;
+
+ gl_FragColor = color * texture2D(tex, gl_TexCoord[0].st) + specularColor;
}
else {
- specularColor = vec4(0, 0, 0, 1);
+ gl_FragColor = vec4(0, 0, 0, 1);
}
-
- gl_FragColor = color * texture2D(tex, gl_TexCoord[0].st) + specularColor;
}
diff --git a/shader/default.vert b/shader/light.vert
index 00b8118..b97da78 100644
--- a/shader/default.vert
+++ b/shader/light.vert
@@ -1,4 +1,4 @@
-varying vec4 diffuse, ambientGlobal, ambient;
+varying vec4 diffuse, ambient;
varying vec3 normal, pos;
@@ -10,7 +10,6 @@ void main() {
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
- ambientGlobal = gl_LightModel.ambient * gl_FrontMaterial.ambient;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
diff --git a/src/Game.cpp b/src/Game.cpp
index 93b13c4..625d4d4 100644
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -34,9 +34,9 @@ Game::Game(bool multisample) : playerPos(vmml::vec3f::ZERO), playerRotY(vmml::ma
glClearColor(0.0, 0.0, 0.0, 1.0);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
+ //glDepthFunc(GL_LEQUAL);
- //glEnable(GL_BLEND);
+ glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#ifndef _WIN32
@@ -50,7 +50,7 @@ Game::Game(bool multisample) : playerPos(vmml::vec3f::ZERO), playerRotY(vmml::ma
glLightfv(GL_LIGHT0, GL_SPECULAR, vmml::vec4f::ONE.array);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.2);
- glEnable(GL_LIGHT0);
+ glDisable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
@@ -61,8 +61,6 @@ Game::Game(bool multisample) : playerPos(vmml::vec3f::ZERO), playerRotY(vmml::ma
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
- Shader::loadProgram("default.vert", "default.frag");
-
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());
diff --git a/src/Renderer.cpp b/src/Renderer.cpp
index ad4849b..8b3d689 100644
--- a/src/Renderer.cpp
+++ b/src/Renderer.cpp
@@ -18,9 +18,15 @@
*/
#include "Renderer.h"
+#include "Shader.h"
namespace Zoom {
+Renderer::Renderer() : activeTexture(0), renderVisitor(this) {
+ ambientShader = boost::shared_ptr<Shader>(Shader::load("ambient.vert", "ambient.frag"));
+ lightShader = boost::shared_ptr<Shader>(Shader::load("light.vert", "light.frag"));
+}
+
void Renderer::render(const BSPTree &tree) {
vmml::mat4f transform, inverseTransform;
glGetFloatv(GL_MODELVIEW_MATRIX, transform.array);
diff --git a/src/Renderer.h b/src/Renderer.h
index fb98e38..ae9af4a 100644
--- a/src/Renderer.h
+++ b/src/Renderer.h
@@ -20,19 +20,25 @@
#ifndef ZOOM_RENDERER_H_
#define ZOOM_RENDERER_H_
-#include "BSPTree.h"
#include "gl.h"
+#include "BSPTree.h"
+#include "Shader.h"
+
namespace Zoom {
class Renderer {
public:
- Renderer() : activeTexture(0), renderVisitor(this) {}
+ Renderer();
void render(const BSPTree &tree);
template <typename T>
void render(const T &triangles) {
+ Shader::enable(ambientShader);
+ glBlendFunc(GL_ONE, GL_ZERO);
+ glDepthFunc(GL_LEQUAL);
+
typename T::const_iterator t = triangles.begin();
if(t == triangles.end())
return;
@@ -44,6 +50,20 @@ class Renderer {
renderTriangle(t->triangle);
}
glEnd();
+
+ Shader::enable(lightShader);
+ glBlendFunc(GL_ONE, GL_ONE);
+ glDepthFunc(GL_EQUAL);
+
+ t = triangles.begin();
+
+ useTexture(t->triangle.getTexture());
+
+ glBegin(GL_TRIANGLES);
+ for(; t != triangles.end(); ++t) {
+ renderTriangle(t->triangle);
+ }
+ glEnd();
}
struct TextureSorter {
@@ -68,6 +88,7 @@ class Renderer {
Renderer *renderer;
};
+ boost::shared_ptr<Shader> ambientShader, lightShader;
unsigned activeTexture;
const RenderVisitor renderVisitor;
diff --git a/src/Shader.cpp b/src/Shader.cpp
index 420b6c6..545d193 100644
--- a/src/Shader.cpp
+++ b/src/Shader.cpp
@@ -18,6 +18,7 @@
*/
#include "Shader.h"
+
#include <iostream>
#include <fstream>
#include <vector>
@@ -25,8 +26,9 @@
namespace Zoom {
-bool Shader::loadProgram(const std::string &vertexShader, const std::string &fragmentShader) {
+boost::shared_ptr<Shader> Shader::load(const std::string &vertexShader, const std::string &fragmentShader) {
GLhandleARB program, vs = 0, fs = 0;
+ bool ok = false;
if(!vertexShader.empty())
vs = loadShader(vertexShader, GL_VERTEX_SHADER_ARB);
@@ -36,25 +38,41 @@ bool Shader::loadProgram(const std::string &vertexShader, const std::string &fra
program = glCreateProgramObjectARB();
- if(vs)
- glAttachObjectARB(program, vs);
+ if(program) {
+ if(vs)
+ glAttachObjectARB(program, vs);
+
+ if(fs)
+ glAttachObjectARB(program, fs);
- if(fs)
- glAttachObjectARB(program, fs);
+ glLinkProgramARB(program);
+ if(glGetError()) {
+ printInfoLog(program);
+ }
+ else {
+ ok = true;
+ }
- glLinkProgramARB(program);
- printInfoLog(program);
+ if(vs) {
+ glDeleteObjectARB(vs);
+ }
- glUseProgramObjectARB(program);
+ if(fs) {
+ glDeleteObjectARB(fs);
+ }
+ }
- return true;
+ if(ok)
+ return boost::shared_ptr<Shader>(new Shader(program));
+ else
+ return boost::shared_ptr<Shader>();
}
GLhandleARB Shader::loadShader(const std::string &name, GLenum type) {
std::vector<std::string> lines;
std::ifstream file(("shader/" + name).c_str(), std::ios_base::in);
if(!file.good())
- throw std::ios::failure("Can't read file '" + name + "'");
+ return 0;
while(file.good() && !file.eof()) {
std::string line;
@@ -69,12 +87,26 @@ GLhandleARB Shader::loadShader(const std::string &name, GLenum type) {
strings[i] = lines[i].c_str();
}
+ bool ok = false;
GLhandleARB shader = glCreateShaderObjectARB(type);
- glShaderSourceARB(shader, lines.size(), strings.get(), 0);
- glCompileShaderARB(shader);
- printInfoLog(shader);
- return shader;
+ if(shader) {
+ glShaderSourceARB(shader, lines.size(), strings.get(), 0);
+ glCompileShaderARB(shader);
+ if(glGetError()) {
+ printInfoLog(shader);
+
+ glDeleteObjectARB(shader);
+ }
+ else {
+ ok = true;
+ }
+ }
+
+ if(ok)
+ return shader;
+ else
+ return 0;
}
void Shader::printInfoLog(GLhandleARB obj) {
diff --git a/src/Shader.h b/src/Shader.h
index 8111f0c..e1fdde9 100644
--- a/src/Shader.h
+++ b/src/Shader.h
@@ -21,19 +21,42 @@
#define ZOOM_SHADER_H_
#include "gl.h"
+
#include <string>
+#include <boost/shared_ptr.hpp>
namespace Zoom {
class Shader {
public:
- static bool loadProgram(const std::string &vertexShader, const std::string &fragmentShader);
+ static boost::shared_ptr<Shader> load(const std::string &vertexShader, const std::string &fragmentShader);
- private:
- Shader();
+ static void enable(boost::shared_ptr<Shader> shader) {
+ if(shader)
+ glUseProgramObjectARB(shader->handle);
+ else
+ glUseProgramObjectARB(0);
+ }
+
+ static void disable() {
+ enable(boost::shared_ptr<Shader>());
+ }
+
+ ~Shader() {
+ glDeleteObjectARB(handle);
+ }
+ private:
static GLhandleARB loadShader(const std::string &name, GLenum type);
static void printInfoLog(GLhandleARB obj);
+
+ Shader(GLhandleARB handle0) : handle(handle0) {}
+
+ // Prevent shallow copy
+ Shader(const Shader &o);
+ Shader& operator=(const Shader &o);
+
+ GLhandleARB handle;
};
}
diff --git a/src/zoom.cpp b/src/zoom.cpp
index e0050c5..8193d6a 100644
--- a/src/zoom.cpp
+++ b/src/zoom.cpp
@@ -22,6 +22,8 @@
#include "config.h"
#include "gl.h"
+#include <cstdio>
+
#ifdef _WIN32
#else
@@ -69,7 +71,7 @@ bool WGLInit(HINSTANCE hInstance, HWND *hWnd, HDC *hDC, HGLRC *hRC) {
if (!RegisterClass(&wc)) {
MessageBox(0, "Failed To Register The Window Class.", "ERROR", MB_OK|MB_ICONEXCLAMATION);
- return false; // Exit And Return FALSE
+ return false;
}
DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
@@ -421,24 +423,29 @@ int main() {
case GenericEvent:
if(event.xcookie.extension == xi_opcode && XGetEventData(disp, &event.xcookie)) {
- XIRawEvent *rawEvent = reinterpret_cast<XIRawEvent*>(event.xcookie.data);
-
- float deltaX = 0, deltaY = 0;
- double *rawValuator = rawEvent->raw_values;
-
- if(XIMaskIsSet(rawEvent->valuators.mask, 0)) {
- deltaX = (float)*rawValuator;
- ++rawValuator;
+ switch(event.xcookie.evtype) {
+ case XI_RawMotion:
+ XIRawEvent *rawEvent = reinterpret_cast<XIRawEvent*>(event.xcookie.data);
+
+ float deltaX = 0, deltaY = 0;
+ double *rawValuator = rawEvent->raw_values;
+
+ if(rawEvent->valuators.mask_len >= 1) {
+ if(XIMaskIsSet(rawEvent->valuators.mask, 0)) {
+ deltaX = (float)*rawValuator;
+ ++rawValuator;
+ }
+
+ if(XIMaskIsSet(rawEvent->valuators.mask, 1)) {
+ deltaY = (float)*rawValuator;
+ ++rawValuator;
+ }
+ }
+
+ if(deltaX != 0 || deltaY != 0)
+ game.turn(deltaX, deltaY);
}
- if(XIMaskIsSet(rawEvent->valuators.mask, 1)) {
- deltaY = (float)*rawValuator;
- ++rawValuator;
- }
-
- if(deltaX != 0 || deltaY != 0)
- game.turn(deltaX, deltaY);
-
XFreeEventData(disp, &event.xcookie);
}
}