+}
+
+void Renderer::begin()
+{
+ if(current_state)
+ throw invalid_operation("Renderer::begin");
+
+ state_stack.push_back(State());
+ current_state = &state_stack.back();
+
+ RendererBackend::begin();
+
+ add_shader_data(standard_shdata);
+}
+
+void Renderer::end()
+{
+ if(!current_state || state_stack.size()>1)
+ throw invalid_operation("Renderer::end");
+
+ RendererBackend::end();
+
+ current_state = 0;
+ state_stack.clear();
+ texture_stack.clear();
+ shdata_stack.clear();
+}
+
+void Renderer::push_state()
+{
+ if(state_stack.empty())
+ throw invalid_operation("Renderer::push_state");
+
+ state_stack.push_back(state_stack.back());
+ current_state = &state_stack.back();
+}
+
+void Renderer::pop_state()
+{
+ if(state_stack.size()==1)
+ throw stack_underflow("Renderer::pop_state");
+
+ state_stack.pop_back();
+ current_state = &state_stack.back();
+ changed |= MATRIX;
+}
+
+Renderer::State &Renderer::get_state() const
+{
+#ifdef DEBUG
+ if(!current_state)
+ throw invalid_operation("Renderer::get_state");
+#endif
+ return *current_state;