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),
29 state_stack.reserve(16);
30 shdata_stack.reserve(32);
31 state = &state_stack.back();
33 MatrixStack::modelview().push();
36 MatrixStack::projection().push();
38 mtx_stack.load(camera->get_matrix());
41 mtx_stack.load(MatrixStack::modelview().top());
47 MatrixStack::projection().pop();
48 MatrixStack::modelview().pop();
51 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_element_buffer(const Buffer *b)
106 void Renderer::set_winding_test(const WindingTest *w)
108 state->winding_test = w;
111 void Renderer::set_reverse_winding(bool r)
113 state->reverse_winding = r;
116 void Renderer::push_state()
118 state_stack.push_back(state_stack.back());
119 state = &state_stack.back();
123 void Renderer::pop_state()
125 if(state_stack.size()==1)
126 throw stack_underflow("Renderer::pop_state");
128 state_stack.pop_back();
129 state = &state_stack.back();
130 if(shdata_stack.size()>state->shdata_count)
131 shdata_stack.erase(shdata_stack.begin()+state->shdata_count, shdata_stack.end());
134 shdata_changed = true;
137 void Renderer::escape()
140 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
143 void Renderer::exclude(const Renderable &renderable)
145 excluded.insert(&renderable);
148 void Renderer::include(const Renderable &renderable)
150 excluded.erase(&renderable);
153 void Renderer::render(const Renderable &renderable, const Tag &tag)
155 if(!excluded.count(&renderable))
156 renderable.render(*this, tag);
159 void Renderer::draw(const Batch &batch)
164 element_buffer->bind_to(ELEMENT_ARRAY_BUFFER);
166 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
171 void Renderer::apply_state()
173 /* We (mostly) let the objects themselves figure out if the binding has
177 state->texturing->bind();
182 state->texture->bind_to(0);
184 Texture::unbind_from(0);
188 state->material->bind();
196 MatrixStack::modelview() = state->lighting_matrix;
197 state->lighting->bind();
199 lighting_changed = false;
207 state->shprog->bind();
210 for(vector<const ProgramData *>::const_iterator i=shdata_stack.begin(); i!=shdata_stack.end(); ++i)
212 shdata_changed = false;
218 if(state->winding_test)
220 if(state->reverse_winding)
221 state->winding_test->get_reverse().bind();
223 state->winding_test->bind();
226 WindingTest::unbind();
230 MatrixStack::modelview() = mtx_stack.top();
236 Renderer::State::State():
247 Renderer::MtxStack::MtxStack(Renderer &r):
251 void Renderer::MtxStack::update()
253 renderer.mtx_changed = true;