From 31f4e9f522ba3009cfa74467bec380a263eabf73 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 7 Sep 2013 17:12:15 +0300 Subject: [PATCH] Use Renderer to bind Lighting This fixes a problem where the matrix left behind by a pipeline pass could interfere with the lighting of the next pass. It's also required for eventually supporting OpenGL 3.0+ without fixed-function lighting. --- source/pipeline.cpp | 2 +- source/renderer.cpp | 25 ++++++++++++++++++++++++- source/renderer.h | 7 +++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/source/pipeline.cpp b/source/pipeline.cpp index c6260f0e..0df03ca7 100644 --- a/source/pipeline.cpp +++ b/source/pipeline.cpp @@ -153,7 +153,7 @@ void Pipeline::render(Renderer &renderer, const Tag &tag) const { Bind bind_depth_test(i->get_depth_test()); Bind bind_blend(i->get_blend()); - Bind bind_lighting(i->get_lighting()); + renderer.set_lighting(i->get_lighting()); for(vector::const_iterator j=renderables.begin(); j!=renderables.end(); ++j) if(j->passes.empty() || j->passes.count(i->get_tag())) diff --git a/source/renderer.cpp b/source/renderer.cpp index 44272813..3a44dcd3 100644 --- a/source/renderer.cpp +++ b/source/renderer.cpp @@ -2,6 +2,7 @@ #include "buffer.h" #include "camera.h" #include "error.h" +#include "lighting.h" #include "material.h" #include "program.h" #include "programdata.h" @@ -71,6 +72,13 @@ void Renderer::set_material(const Material *m) state->material = m; } +void Renderer::set_lighting(const Lighting *l) +{ + state->lighting = l; + state->lighting_matrix = mtx_stack.top(); + lighting_changed = true; +} + void Renderer::set_shader_program(const Program *p, const ProgramData *d) { state->shprog = p; @@ -166,7 +174,8 @@ void Renderer::draw(const Batch &batch) void Renderer::apply_state() { - // We let the objects themselves figure out if the binding has changed + /* We (mostly) let the objects themselves figure out if the binding has + changed */ if(state->texturing) state->texturing->bind(); @@ -184,6 +193,19 @@ void Renderer::apply_state() else Material::unbind(); + if(lighting_changed) + { + if(state->lighting) + { + MatrixStack::modelview() = state->lighting_matrix; + state->lighting->bind(); + mtx_changed = true; + lighting_changed = false; + } + else + Lighting::unbind(); + } + if(state->shprog) { state->shprog->bind(); @@ -214,6 +236,7 @@ Renderer::State::State(): texture(0), texturing(0), material(0), + lighting(0), shprog(0), shdata_count(0), winding_test(0) diff --git a/source/renderer.h b/source/renderer.h index 088b5710..00f97004 100644 --- a/source/renderer.h +++ b/source/renderer.h @@ -13,6 +13,7 @@ class Batch; class Buffer; class Camera; class Material; +class Lighting; class Program; class ProgramData; class Renderable; @@ -65,9 +66,12 @@ private: const Texture *texture; const Texturing *texturing; const Material *material; + const Lighting *lighting; + Matrix lighting_matrix; const Program *shprog; unsigned shdata_count; const WindingTest *winding_test; + bool reverse_winding; State(); }; @@ -88,6 +92,7 @@ private: const Camera *camera; std::vector state_stack; State *state; + bool lighting_changed; std::vector shdata_stack; bool shdata_changed; const VertexArray *vertex_array; @@ -106,6 +111,8 @@ public: void set_texturing(const Texturing *); void set_material(const Material *); + void set_lighting(const Lighting *); + /** Sets the shader program to use. An initial set of data can be set as well, with the same semantics as add_shader_data. */ void set_shader_program(const Program *prog, const ProgramData *data = 0); -- 2.43.0