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);
55 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
56 WindingTest::unbind();
59 void Renderer::set_texture(const Texture *t)
65 void Renderer::set_texturing(const Texturing *t)
71 void Renderer::set_material(const Material *m)
76 void Renderer::set_lighting(const Lighting *l)
79 state->lighting_matrix = mtx_stack.top();
80 lighting_changed = true;
83 void Renderer::set_shader_program(const Program *p, const ProgramData *d)
89 /* Even if we have no new shdata, the existing ones need to be re-applied
91 shdata_changed = true;
94 void Renderer::add_shader_data(const ProgramData &d)
96 shdata_stack.push_back(&d);
97 state->shdata_count = shdata_stack.size();
98 shdata_changed = true;
101 void Renderer::set_vertex_array(const VertexArray *a)
106 void Renderer::set_element_buffer(const Buffer *b)
111 void Renderer::set_winding_test(const WindingTest *w)
113 state->winding_test = w;
116 void Renderer::set_reverse_winding(bool r)
118 state->reverse_winding = r;
121 void Renderer::push_state()
123 state_stack.push_back(state_stack.back());
124 state = &state_stack.back();
128 void Renderer::pop_state()
130 if(state_stack.size()==1)
131 throw stack_underflow("Renderer::pop_state");
133 state_stack.pop_back();
134 state = &state_stack.back();
135 if(shdata_stack.size()>state->shdata_count)
136 shdata_stack.erase(shdata_stack.begin()+state->shdata_count, shdata_stack.end());
139 shdata_changed = true;
142 void Renderer::escape()
145 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
148 void Renderer::exclude(const Renderable &renderable)
150 excluded.insert(&renderable);
153 void Renderer::include(const Renderable &renderable)
155 excluded.erase(&renderable);
158 void Renderer::render(const Renderable &renderable, const Tag &tag)
160 if(!excluded.count(&renderable))
161 renderable.render(*this, tag);
164 void Renderer::draw(const Batch &batch)
167 throw invalid_operation("Renderer::draw");
171 vertex_array->apply();
174 element_buffer->bind_to(ELEMENT_ARRAY_BUFFER);
176 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
181 void Renderer::apply_state()
183 /* We (mostly) let the objects themselves figure out if the binding has
187 state->texturing->bind();
192 state->texture->bind_to(0);
194 Texture::unbind_from(0);
198 state->material->bind();
206 MatrixStack::modelview() = state->lighting_matrix;
207 state->lighting->bind();
209 lighting_changed = false;
217 state->shprog->bind();
220 for(vector<const ProgramData *>::const_iterator i=shdata_stack.begin(); i!=shdata_stack.end(); ++i)
222 shdata_changed = false;
228 if(state->winding_test)
230 if(state->reverse_winding)
231 state->winding_test->get_reverse().bind();
233 state->winding_test->bind();
236 WindingTest::unbind();
240 MatrixStack::modelview() = mtx_stack.top();
246 Renderer::State::State():
257 Renderer::MtxStack::MtxStack(Renderer &r):
261 void Renderer::MtxStack::update()
263 renderer.mtx_changed = true;