8 #include "programdata.h"
9 #include "renderable.h"
12 #include "texturing.h"
13 #include "vertexarray.h"
14 #include "windingtest.h"
21 Renderer::Renderer(const Camera *c):
26 lighting_changed(false),
30 state_stack.reserve(16);
31 shdata_stack.reserve(32);
32 state = &state_stack.back();
34 MatrixStack::modelview().push();
37 MatrixStack::projection().push();
39 mtx_stack.load(camera->get_matrix());
42 mtx_stack.load(MatrixStack::modelview().top());
48 MatrixStack::projection().pop();
49 MatrixStack::modelview().pop();
52 Texture::unbind_from(0);
56 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
57 WindingTest::unbind();
60 void Renderer::set_texture(const Texture *t)
66 void Renderer::set_texturing(const Texturing *t)
72 void Renderer::set_material(const Material *m)
77 void Renderer::set_lighting(const Lighting *l)
80 state->lighting_matrix = mtx_stack.top();
81 lighting_changed = true;
84 void Renderer::set_shader_program(const Program *p, const ProgramData *d)
90 /* Even if we have no new shdata, the existing ones need to be re-applied
92 shdata_changed = true;
95 void Renderer::add_shader_data(const ProgramData &d)
97 shdata_stack.push_back(&d);
98 state->shdata_count = shdata_stack.size();
99 shdata_changed = true;
102 void Renderer::set_vertex_array(const VertexArray *a)
107 void Renderer::set_element_buffer(const Buffer *b)
112 void Renderer::set_winding_test(const WindingTest *w)
114 state->winding_test = w;
117 void Renderer::set_reverse_winding(bool r)
119 state->reverse_winding = r;
122 void Renderer::push_state()
124 state_stack.push_back(state_stack.back());
125 state = &state_stack.back();
129 void Renderer::pop_state()
131 if(state_stack.size()==1)
132 throw stack_underflow("Renderer::pop_state");
134 state_stack.pop_back();
135 state = &state_stack.back();
136 if(shdata_stack.size()>state->shdata_count)
137 shdata_stack.erase(shdata_stack.begin()+state->shdata_count, shdata_stack.end());
140 shdata_changed = true;
143 void Renderer::escape()
146 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
149 void Renderer::exclude(const Renderable &renderable)
151 excluded.insert(&renderable);
154 void Renderer::include(const Renderable &renderable)
156 excluded.erase(&renderable);
159 void Renderer::render(const Renderable &renderable, const Tag &tag)
161 if(!excluded.count(&renderable))
162 renderable.render(*this, tag);
165 void Renderer::draw(const Batch &batch)
168 throw invalid_operation("Renderer::draw");
172 vertex_array->apply();
175 element_buffer->bind_to(ELEMENT_ARRAY_BUFFER);
177 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
182 void Renderer::apply_state()
184 /* We (mostly) let the objects themselves figure out if the binding has
188 state->texturing->bind();
193 state->texture->bind_to(0);
195 Texture::unbind_from(0);
199 state->material->bind();
207 MatrixStack::modelview() = state->lighting_matrix;
208 state->lighting->bind();
210 lighting_changed = false;
218 state->shprog->bind();
221 for(vector<const ProgramData *>::const_iterator i=shdata_stack.begin(); i!=shdata_stack.end(); ++i)
223 shdata_changed = false;
229 if(state->winding_test)
231 if(state->reverse_winding)
232 state->winding_test->get_reverse().bind();
234 state->winding_test->bind();
237 WindingTest::unbind();
241 MatrixStack::modelview() = mtx_stack.top();
247 Renderer::State::State():
258 Renderer::MtxStack::MtxStack(Renderer &r):
262 void Renderer::MtxStack::update()
264 renderer.mtx_changed = true;