3 This file is part of libmspgl
4 Copyright © 2011 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
8 #include <msp/core/except.h>
14 #include "programdata.h"
17 #include "texturing.h"
18 #include "vertexarray.h"
19 #include "windingtest.h"
26 Renderer::Renderer(const Camera *c):
31 state(&state_stack.back()),
33 vertex_array_changed(false),
36 MatrixStack::modelview().push();
39 MatrixStack::projection().push();
41 mtx_stack.load(camera->get_matrix());
44 mtx_stack.load(MatrixStack::modelview().top());
50 MatrixStack::projection().pop();
51 MatrixStack::modelview().pop();
54 Texture::unbind_from(0);
57 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
58 WindingTest::unbind();
61 void Renderer::set_texture(const Texture *t)
67 void Renderer::set_texturing(const Texturing *t)
73 void Renderer::set_material(const Material *m)
78 void Renderer::set_shader(const Program *p, const ProgramData *d)
82 state->shdata.assign(1, d);
84 state->shdata.clear();
87 void Renderer::add_shader_data(const ProgramData *d)
90 throw InvalidState("No shader program");
92 state->shdata.push_back(d);
95 void Renderer::set_vertex_array(const VertexArray *a)
97 vertex_array_changed = (a!=vertex_array);
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::push_state()
113 state_stack.push_back(state_stack.back());
114 state = &state_stack.back();
118 void Renderer::pop_state()
120 if(state_stack.size()==1)
121 throw InvalidState("Can't pop the last state");
123 state_stack.pop_back();
124 state = &state_stack.back();
129 void Renderer::escape()
132 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
135 void Renderer::draw(const Batch &batch)
138 throw InvalidState("Can't draw without a vertex array");
142 // Until VertexArray acquires VAO support and becomes Bindable
143 if(vertex_array_changed)
145 vertex_array->apply();
146 vertex_array_changed = false;
150 element_buffer->bind_to(ELEMENT_ARRAY_BUFFER);
152 Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
157 void Renderer::apply_state()
159 // We let the objects themselves figure out if the binding has changed
162 state->texturing->bind();
167 state->texture->bind_to(0);
169 Texture::unbind_from(0);
173 state->material->bind();
179 state->shprog->bind();
180 for(vector<const ProgramData *>::const_iterator i=state->shdata.begin(); i!=state->shdata.end(); ++i)
186 if(state->winding_test)
187 state->winding_test->bind();
189 WindingTest::unbind();
193 MatrixStack::modelview() = mtx_stack.top();
199 Renderer::State::State():
208 Renderer::MtxStack::MtxStack(Renderer &r):
212 void Renderer::MtxStack::update()
214 renderer.mtx_changed = true;