From 4e3efa239c9bcb5dd26b4ad9a4d43d4d6a266e6f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 18 Dec 2009 13:31:07 +0100 Subject: Use multi-pass rendering with seperate ambient and light shaders --- src/Game.cpp | 8 +++----- src/Renderer.cpp | 6 ++++++ src/Renderer.h | 25 +++++++++++++++++++++-- src/Shader.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++------------- src/Shader.h | 29 ++++++++++++++++++++++++--- src/zoom.cpp | 41 ++++++++++++++++++++++---------------- 6 files changed, 128 insertions(+), 41 deletions(-) (limited to 'src') 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::load("ambient.vert", "ambient.frag")); + lightShader = boost::shared_ptr(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 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 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 #include #include @@ -25,8 +26,9 @@ namespace Zoom { -bool Shader::loadProgram(const std::string &vertexShader, const std::string &fragmentShader) { +boost::shared_ptr 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(new Shader(program)); + else + return boost::shared_ptr(); } GLhandleARB Shader::loadShader(const std::string &name, GLenum type) { std::vector 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 +#include namespace Zoom { class Shader { public: - static bool loadProgram(const std::string &vertexShader, const std::string &fragmentShader); + static boost::shared_ptr load(const std::string &vertexShader, const std::string &fragmentShader); - private: - Shader(); + static void enable(boost::shared_ptr shader) { + if(shader) + glUseProgramObjectARB(shader->handle); + else + glUseProgramObjectARB(0); + } + + static void disable() { + enable(boost::shared_ptr()); + } + + ~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 + #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(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(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); } } -- cgit v1.2.3