Renderer::Renderer(const Camera *c):
mtx_stack(*this),
- changed(MATRIX),
+ changed(0),
matrices_loaded(false),
shdata_applied(0),
- camera(c),
+ camera(0),
state_stack(1),
element_buffer(0)
{
shdata_stack.reserve(32);
state = &state_stack.back();
+ begin(c);
+}
+
+Renderer::~Renderer()
+{
+ end();
+}
+
+void Renderer::begin(const Camera *c)
+{
+ if(state_stack.size()>1)
+ throw invalid_operation("Renderer::begin");
+
+ reset_state();
+ excluded.clear();
+ camera = c;
+
if(camera)
{
mtx_stack.load(camera->get_matrix());
}
else
{
- standard_shdata.uniform("projection_matrix", MatrixStack::projection().top());
mtx_stack.load(MatrixStack::modelview().top());
+ standard_shdata.uniform("projection_matrix", MatrixStack::projection().top());
}
}
-Renderer::~Renderer()
-{
- end();
-}
-
void Renderer::set_texture(const Texture *t)
{
state->texture = t;
if(state_stack.size()>1)
throw invalid_operation("Renderer::end");
- if(matrices_loaded)
- {
- if(camera)
- MatrixStack::projection().pop();
- MatrixStack::modelview().pop();
- matrices_loaded = false;
- }
+ reset_state();
Mesh::unbind();
Texturing::unbind();
Program::unbind();
Buffer::unbind_from(ELEMENT_ARRAY_BUFFER);
WindingTest::unbind();
-
- *state = State();
}
void Renderer::exclude(const Renderable &renderable)
}
}
+void Renderer::reset_state()
+{
+ if(!matrices_loaded)
+ return;
+
+ if(camera)
+ MatrixStack::projection().pop();
+ MatrixStack::modelview().pop();
+ matrices_loaded = false;
+ changed |= MATRIX;
+
+ *state = State();
+}
+
Renderer::State::State():
texture(0),
Renderer(const Camera *);
~Renderer();
+ /** Resets all internal state and restarts rendering. There must be no
+ unpopped state in the stack. It is permissible to call begin() multiple
+ times without an intervening end(). */
+ void begin(const Camera *);
+
MatrixStack &matrix_stack() { return mtx_stack; }
const Camera *get_camera() const { return camera; }
Renderer. DEPRECATED. */
void escape();
- /** Ends rendering, unbinding all objects and resetting state. There must
- be no unpopped state in the stack. */
+ /** Unbinds all objects and resets related state. There must be no unpopped
+ state in the stack. Rendering with the same camera can be restarted without
+ an explicit begin() call. */
void end();
void exclude(const Renderable &);
private:
void apply_state();
+ void reset_state();
};
} // namespace GL