From: Mikko Rasa Date: Sun, 15 Dec 2013 23:26:55 +0000 (+0200) Subject: Integrate modern shaders and VAOs with Renderer X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=9d6c244eb728336c64ee23d5c55e45c6696aa65c Integrate modern shaders and VAOs with Renderer --- diff --git a/source/mesh.cpp b/source/mesh.cpp index d474a27f..26d66044 100644 --- a/source/mesh.cpp +++ b/source/mesh.cpp @@ -169,7 +169,9 @@ void Mesh::draw() const void Mesh::draw(Renderer &renderer) const { - vertices.apply(); + refresh(); + + renderer.set_mesh(this); renderer.set_element_buffer(ibuf); renderer.set_winding_test(winding); diff --git a/source/renderer.cpp b/source/renderer.cpp index 8199d3a6..5108ff4c 100644 --- a/source/renderer.cpp +++ b/source/renderer.cpp @@ -4,6 +4,7 @@ #include "error.h" #include "lighting.h" #include "material.h" +#include "mesh.h" #include "program.h" #include "programdata.h" #include "renderable.h" @@ -36,9 +37,13 @@ Renderer::Renderer(const Camera *c): MatrixStack::projection().push(); camera->apply(); mtx_stack.load(camera->get_matrix()); + standard_shdata.uniform("projection_matrix", camera->get_projection_matrix()); } else + { + standard_shdata.uniform("projection_matrix", MatrixStack::projection().top()); mtx_stack.load(MatrixStack::modelview().top()); + } } Renderer::~Renderer() @@ -47,6 +52,7 @@ Renderer::~Renderer() MatrixStack::projection().pop(); MatrixStack::modelview().pop(); + Mesh::unbind(); Texturing::unbind(); Texture::unbind_from(0); Material::unbind(); @@ -77,6 +83,10 @@ 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(l)->update_shader_data(mtx_stack.top()); lighting_changed = true; } @@ -98,6 +108,11 @@ void Renderer::add_shader_data(const ProgramData &d) shdata_changed = true; } +void Renderer::set_mesh(const Mesh *m) +{ + state->mesh = m; +} + void Renderer::set_element_buffer(const Buffer *b) { element_buffer = b; @@ -160,10 +175,14 @@ void Renderer::draw(const Batch &batch) { apply_state(); - if(element_buffer) - element_buffer->bind_to(ELEMENT_ARRAY_BUFFER); - else - Buffer::unbind_from(ELEMENT_ARRAY_BUFFER); + bool legacy_bindings = (!state->shprog || state->shprog->uses_legacy_variables()); + if(legacy_bindings) + { + if(element_buffer) + element_buffer->bind_to(ELEMENT_ARRAY_BUFFER); + else + Buffer::unbind_from(ELEMENT_ARRAY_BUFFER); + } batch.draw(); } @@ -173,6 +192,8 @@ void Renderer::apply_state() /* We (mostly) let the objects themselves figure out if the binding has changed */ + bool legacy_bindings = (!state->shprog || state->shprog->uses_legacy_variables()); + if(state->texturing) state->texturing->bind(); else @@ -184,27 +205,48 @@ void Renderer::apply_state() Texture::unbind_from(0); } - if(state->material) - state->material->bind(); - else - Material::unbind(); - - if(lighting_changed) + if(legacy_bindings) { - if(state->lighting) + if(state->material) + state->material->bind(); + else + Material::unbind(); + + if(lighting_changed) { - MatrixStack::modelview() = state->lighting_matrix; - state->lighting->bind(); - mtx_changed = true; - lighting_changed = false; + if(state->lighting) + { + MatrixStack::modelview() = state->lighting_matrix; + state->lighting->bind(); + mtx_changed = true; + lighting_changed = false; + } + else + Lighting::unbind(); } - else - Lighting::unbind(); } if(state->shprog) { state->shprog->bind(); + + if(!legacy_bindings) + { + const Matrix &m = mtx_stack.top(); + standard_shdata.uniform("eye_obj_matrix", mtx_stack.top()); + LinAl::SquareMatrix nm; + for(unsigned i=0; i<3; ++i) + for(unsigned j=0; j<3; ++j) + 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) { for(vector::const_iterator i=shdata_stack.begin(); i!=shdata_stack.end(); ++i) @@ -215,6 +257,19 @@ void Renderer::apply_state() else Program::unbind(); + if(state->mesh) + { + if(legacy_bindings) + { + Mesh::unbind(); + state->mesh->get_vertices().apply(); + } + else + state->mesh->bind(); + } + else + Mesh::unbind(); + if(state->winding_test) { if(state->reverse_winding) @@ -225,7 +280,7 @@ void Renderer::apply_state() else WindingTest::unbind(); - if(mtx_changed) + if(legacy_bindings && mtx_changed) { MatrixStack::modelview() = mtx_stack.top(); mtx_changed = false; @@ -240,6 +295,7 @@ Renderer::State::State(): lighting(0), shprog(0), shdata_count(0), + mesh(0), winding_test(0) { } diff --git a/source/renderer.h b/source/renderer.h index a45b2943..f736447e 100644 --- a/source/renderer.h +++ b/source/renderer.h @@ -4,6 +4,7 @@ #include #include #include "matrix.h" +#include "programdata.h" #include "tag.h" namespace Msp { @@ -13,9 +14,9 @@ class Batch; class Buffer; class Camera; class Material; +class Mesh; class Lighting; class Program; -class ProgramData; class Renderable; class Texture; class Texturing; @@ -69,6 +70,7 @@ private: Matrix lighting_matrix; const Program *shprog; unsigned shdata_count; + const Mesh *mesh; const WindingTest *winding_test; bool reverse_winding; @@ -92,6 +94,7 @@ private: std::vector state_stack; State *state; bool lighting_changed; + ProgramData standard_shdata; std::vector shdata_stack; bool shdata_changed; const Buffer *element_buffer; @@ -120,6 +123,7 @@ public: Renderer state is popped. */ void add_shader_data(const ProgramData &data); + void set_mesh(const Mesh *); void set_element_buffer(const Buffer *); void set_winding_test(const WindingTest *); void set_reverse_winding(bool);