1 #pragma once
2 
3 #include "irender.h"
4 #include <vector>
5 
6 class XYRenderer: public Renderer {
7 		struct state_type {
state_typestate_type8 				state_type() :
9 					m_highlight(0), m_state(0) {
10 				}
11 				unsigned int m_highlight;
12 				Shader* m_state;
13 		};
14 	public:
XYRenderer(RenderStateFlags globalstate,Shader * selected)15 		XYRenderer(RenderStateFlags globalstate, Shader* selected) :
16 			m_globalstate(globalstate), m_state_selected(selected) {
17 			ASSERT_NOTNULL(selected);
18 			m_state_stack.push_back(state_type());
19 		}
20 
SetState(Shader * state,EStyle style)21 		void SetState(Shader* state, EStyle style) {
22 			ASSERT_NOTNULL(state);
23 			if (style == eWireframeOnly)
24 				m_state_stack.back().m_state = state;
25 		}
26 
getStyle()27 		EStyle getStyle() const {
28 			return eWireframeOnly;
29 		}
30 
PushState()31 		void PushState() {
32 			m_state_stack.push_back(m_state_stack.back());
33 		}
34 
PopState()35 		void PopState() {
36 			ASSERT_MESSAGE(!m_state_stack.empty(), "popping empty stack");
37 			m_state_stack.pop_back();
38 		}
39 
40 		void Highlight(EHighlightMode mode, bool bEnable = true) {
41 			(bEnable) ? m_state_stack.back().m_highlight |= mode : m_state_stack.back().m_highlight
42 					&= ~mode;
43 		}
44 
addRenderable(const OpenGLRenderable & renderable,const Matrix4 & localToWorld)45 		void addRenderable(const OpenGLRenderable& renderable, const Matrix4& localToWorld) {
46 			if (m_state_stack.back().m_highlight & ePrimitive) {
47 				m_state_selected->addRenderable(renderable, localToWorld);
48 			} else {
49 				m_state_stack.back().m_state->addRenderable(renderable, localToWorld);
50 			}
51 		}
52 
render(const Matrix4 & modelview,const Matrix4 & projection)53 		void render(const Matrix4& modelview, const Matrix4& projection) {
54 			GlobalShaderCache().render(m_globalstate, modelview, projection);
55 		}
56 
57 	private:
58 		std::vector<state_type> m_state_stack;
59 		RenderStateFlags m_globalstate;
60 		Shader* m_state_selected;
61 };
62