]> git.tdb.fi Git - libs/gl.git/blobdiff - source/renderer.cpp
Roll the various changed flags into a single mask
[libs/gl.git] / source / renderer.cpp
index af0d087398da9010816a0cce0f8bf563dc1f69d0..54d12051c9945066badc10231685e43398aad0f1 100644 (file)
@@ -22,21 +22,18 @@ namespace GL {
 
 Renderer::Renderer(const Camera *c):
        mtx_stack(*this),
-       mtx_changed(false),
+       changed(MATRIX),
+       matrices_loaded(false),
        camera(c),
        state_stack(1),
-       lighting_changed(false),
        element_buffer(0)
 {
        state_stack.reserve(16);
        shdata_stack.reserve(32);
        state = &state_stack.back();
 
-       MatrixStack::modelview().push();
        if(camera)
        {
-               MatrixStack::projection().push();
-               camera->apply();
                mtx_stack.load(camera->get_matrix());
                standard_shdata.uniform("projection_matrix", camera->get_projection_matrix());
        }
@@ -49,18 +46,7 @@ Renderer::Renderer(const Camera *c):
 
 Renderer::~Renderer()
 {
-       if(camera)
-               MatrixStack::projection().pop();
-       MatrixStack::modelview().pop();
-
-       Mesh::unbind();
-       Texturing::unbind();
-       Texture::unbind_from(0);
-       Material::unbind();
-       Lighting::unbind();
-       Program::unbind();
-       Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
-       WindingTest::unbind();
+       end();
 }
 
 void Renderer::set_texture(const Texture *t)
@@ -90,10 +76,8 @@ void Renderer::set_lighting(const Lighting *l)
        state->lighting = l;
        state->lighting_matrix = mtx_stack.top();
        if(l)
-               /* XXX I'm not happy with this, but can't come up with anything better
-               right now. */
-               const_cast<Lighting *>(l)->update_shader_data(mtx_stack.top());
-       lighting_changed = true;
+               l->update_shader_data(standard_shdata, mtx_stack.top());
+       changed |= LIGHTING;
 }
 
 void Renderer::set_shader_program(const Program *p, const ProgramData *d)
@@ -111,7 +95,7 @@ void Renderer::add_shader_data(const ProgramData &d)
 {
        shdata_stack.push_back(&d);
        state->shdata_count = shdata_stack.size();
-       shdata_changed = true;
+       changed |= SHADER_DATA;
 }
 
 void Renderer::set_mesh(const Mesh *m)
@@ -151,14 +135,39 @@ void Renderer::pop_state()
        if(shdata_stack.size()>state->shdata_count)
                shdata_stack.erase(shdata_stack.begin()+state->shdata_count, shdata_stack.end());
        mtx_stack.pop();
-       mtx_changed = true;
-       shdata_changed = true;
+       changed |= MATRIX|SHADER_DATA;
 }
 
 void Renderer::escape()
 {
        apply_state();
        Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
+       matrices_loaded = false;
+}
+
+void Renderer::end()
+{
+       if(state_stack.size()>1)
+               throw invalid_operation("Renderer::end");
+
+       if(matrices_loaded)
+       {
+               if(camera)
+                       MatrixStack::projection().pop();
+               MatrixStack::modelview().pop();
+               matrices_loaded = false;
+       }
+
+       Mesh::unbind();
+       Texturing::unbind();
+       Texture::unbind_from(0);
+       Material::unbind();
+       Lighting::unbind();
+       Program::unbind();
+       Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
+       WindingTest::unbind();
+
+       *state = State();
 }
 
 void Renderer::exclude(const Renderable &renderable)
@@ -218,14 +227,13 @@ void Renderer::apply_state()
                else
                        Material::unbind();
 
-               if(lighting_changed)
+               if(changed&LIGHTING)
                {
                        if(state->lighting)
                        {
                                MatrixStack::modelview() = state->lighting_matrix;
                                state->lighting->bind();
-                               mtx_changed = true;
-                               lighting_changed = false;
+                               changed = (changed&~LIGHTING)|MATRIX;
                        }
                        else
                                Lighting::unbind();
@@ -246,18 +254,16 @@ void Renderer::apply_state()
                                        nm(i, j) = m(i, j);
                        nm = transpose(invert(nm));
                        standard_shdata.uniform_matrix3("eye_obj_normal_matrix", &nm(0, 0));
-                       if(state->lighting)
-                               state->lighting->get_shader_data().apply();
                        if(state->material)
                                state->material->get_shader_data().apply();
                        standard_shdata.apply();
                }
 
-               if(shdata_changed)
+               if(changed&SHADER_DATA)
                {
                        for(vector<const ProgramData *>::const_iterator i=shdata_stack.begin(); i!=shdata_stack.end(); ++i)
                                (*i)->apply();
-                       shdata_changed = false;
+                       changed &= ~SHADER_DATA;
                }
        }
        else
@@ -286,10 +292,24 @@ void Renderer::apply_state()
        else
                WindingTest::unbind();
 
-       if(legacy_bindings && mtx_changed)
+       if(legacy_bindings)
        {
-               MatrixStack::modelview() = mtx_stack.top();
-               mtx_changed = false;
+               if(!matrices_loaded)
+               {
+                       MatrixStack::modelview().push();
+                       if(camera)
+                       {
+                               MatrixStack::projection().push();
+                               camera->apply();
+                       }
+                       matrices_loaded = true;
+               }
+
+               if(changed&MATRIX)
+               {
+                       MatrixStack::modelview() = mtx_stack.top();
+                       changed &= ~MATRIX;
+               }
        }
 }
 
@@ -314,7 +334,7 @@ Renderer::MtxStack::MtxStack(Renderer &r):
 
 void Renderer::MtxStack::update()
 {
-       renderer.mtx_changed = true;
+       renderer.changed |= MATRIX;
 }
 
 } // namespace GL