Просмотр исходного кода

Use double RenderContext system in Renderer in order to support a main thread and a render thread

Daniele Bartolini 12 лет назад
Родитель
Сommit
c259c8b43f
3 измененных файлов с 749 добавлено и 514 удалено
  1. 407 44
      engine/renderers/Renderer.h
  2. 342 382
      engine/renderers/gl/GLRenderer.cpp
  3. 0 88
      engine/renderers/gl/GLRenderer.h

+ 407 - 44
engine/renderers/Renderer.h

@@ -43,133 +43,496 @@ enum RenderTargetFormat
 	RTF_D24			///< Depth
 };
 
-enum ShaderType
-{
-	SHADER_VERTEX,
-	SHADER_FRAGMENT
-};
+class RendererImplementation;
 
 class Renderer
 {
 public:
 
-	static Renderer*		create(Allocator& a);
-	static void				destroy(Allocator& a, Renderer* renderer);
+	Renderer(Allocator& a);
+	~Renderer();
+
+	void init_impl();
+	void shutdown_impl();
+	void render_impl();
+
+	void create_vertex_buffer_impl(VertexBufferId id, size_t count, VertexFormat format, const void* vertices);
+	void update_vertex_buffer_impl(VertexBufferId id, size_t offset, size_t count, const void* vertices);
+	void destroy_vertex_buffer_impl(VertexBufferId id);
+
+	void create_index_buffer_impl(IndexBufferId id, size_t count, const void* indices);
+	void destroy_index_buffer_impl(IndexBufferId id);
+
+	void create_texture_impl(TextureId id, uint32_t width, uint32_t height, PixelFormat format, const void* data);
+	void update_texture_impl(TextureId id, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const void* data);
+	void destroy_texture_impl(TextureId id);
+
+	void create_shader_impl(ShaderId id, ShaderType type, const char* text);
+	void destroy_shader_impl(ShaderId id);
+
+	void create_gpu_program_impl(GPUProgramId id, ShaderId vertex, ShaderId pixel);
+	void destroy_gpu_program_impl(GPUProgramId id);
+
+	void create_uniform_impl(UniformId id, const char* name, UniformType type);
+	void destroy_uniform_impl(UniformId id);
 
-	virtual 				~Renderer() {};
+	void create_render_target_impl(RenderTargetId id, uint16_t width, uint16_t height, RenderTargetFormat format);
+	void destroy_render_target_impl(RenderTargetId id);
 
-	virtual void			init() = 0;
-	virtual void			shutdown() = 0;
+	inline void init()
+	{
+		m_submit->m_commands.write(COMMAND_INIT_RENDERER);
+	}
+
+	inline void shutdown()
+	{
+		m_submit->m_commands.write(COMMAND_SHUTDOWN_RENDERER);
+	}
 
 	/// Creates a new vertex buffer optimized for rendering static vertex data.
 	/// @a vertices is the array containig @a count vertex data elements of the given @a format.
-	virtual VertexBufferId	create_vertex_buffer(size_t count, VertexFormat format, const void* vertices) = 0;
+	inline VertexBufferId create_vertex_buffer(size_t count, VertexFormat format, const void* vertices)
+	{
+		const VertexBufferId id = m_vertex_buffers.create();
+
+		m_submit->m_commands.write(COMMAND_CREATE_VERTEX_BUFFER);
+		m_submit->m_commands.write(id);
+		m_submit->m_commands.write(count);
+		m_submit->m_commands.write(format);
+		m_submit->m_commands.write(vertices);
+
+		return id;
+	}
 
 	/// Updates the data associated with the given vertex buffer @a id.
 	/// @a vertices is the array containig @a count vertex data elements of the format
 	/// specified at the creation of the buffer.
 	/// @note
 	/// @a count and @a offset together do not have to exceed the number of elements specified
-	/// at the creation of the buffer.	
-	virtual void			update_vertex_buffer(VertexBufferId id, size_t offset, size_t count, const void* vertices) = 0;
+	/// at the creation of the buffer.
+	inline void update_vertex_buffer(VertexBufferId id, size_t offset, size_t count, const void* vertices)
+	{
+		m_submit->m_commands.write(COMMAND_UPDATE_VERTEX_BUFFER);
+		m_submit->m_commands.write(id);
+		m_submit->m_commands.write(offset);
+		m_submit->m_commands.write(count);
+		m_submit->m_commands.write(vertices);			
+	}
 
-	/// Destroys the @a id vertex buffer.
-	virtual void			destroy_vertex_buffer(VertexBufferId id) = 0;
+	/// Destroys the given vertex buffer @a id.
+	inline void destroy_vertex_buffer(VertexBufferId id)
+	{
+		m_submit->m_commands.write(COMMAND_DESTROY_VERTEX_BUFFER);
+		m_submit->m_commands.write(id);
+	}
 
 	/// Creates a new index buffer optimized for rendering static index buffers.
 	/// @a indices is the array containing @a count index data elements.
-	virtual IndexBufferId	create_index_buffer(size_t count, const void* indices) = 0;
+	inline IndexBufferId create_index_buffer(size_t count, const void* indices)
+	{
+		const IndexBufferId id = m_index_buffers.create();
+
+		m_submit->m_commands.write(COMMAND_CREATE_INDEX_BUFFER);
+		m_submit->m_commands.write(id);
+		m_submit->m_commands.write(count);
+		m_submit->m_commands.write(indices);
+
+		return id;
+	}
 
 	/// Destroys the @a id index buffer.
-	virtual void			destroy_index_buffer(IndexBufferId id) = 0;
+	inline void destroy_index_buffer(IndexBufferId id)
+	{
+		m_submit->m_commands.write(COMMAND_DESTROY_INDEX_BUFFER);
+		m_submit->m_commands.write(id);
+	}
 
-	virtual TextureId		create_texture(uint32_t width, uint32_t height, PixelFormat format, const void* data) = 0;
-	virtual void			update_texture(TextureId id, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const void* data) = 0;
-	virtual void			destroy_texture(TextureId id) = 0;
+	inline TextureId create_texture(uint32_t width, uint32_t height, PixelFormat format, const void* data)
+	{
+		const TextureId id = m_textures.create();
 
-	virtual ShaderId		create_shader(ShaderType type, const char* text) = 0;
-	virtual void			destroy_shader(ShaderId id) = 0;
+		m_submit->m_commands.write(COMMAND_CREATE_TEXTURE);
+		m_submit->m_commands.write(id);
+		m_submit->m_commands.write(width);
+		m_submit->m_commands.write(height);
+		m_submit->m_commands.write(format);
+		m_submit->m_commands.write(data);
 
-	virtual GPUProgramId	create_gpu_program(ShaderId vertex, ShaderId pixel) = 0;
-	virtual void			destroy_gpu_program(GPUProgramId id) = 0;
+		return id;
+	}
 
-	virtual UniformId		create_uniform(const char* name, UniformType type) = 0;
-	virtual void			destroy_uniform(UniformId id) = 0;
+	inline void update_texture(TextureId id, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const void* data)
+	{
+		m_submit->m_commands.write(COMMAND_UPDATE_TEXTURE);
+		m_submit->m_commands.write(id);
+		m_submit->m_commands.write(x);
+		m_submit->m_commands.write(y);
+		m_submit->m_commands.write(width);
+		m_submit->m_commands.write(height);
+		m_submit->m_commands.write(data);
+	}
 
-	virtual RenderTargetId	create_render_target(uint16_t width, uint16_t height, RenderTargetFormat format) = 0;
-	virtual void			destroy_render_target(RenderTargetId id) = 0;
+	inline void destroy_texture(TextureId id)
+	{
+		m_submit->m_commands.write(COMMAND_DESTROY_TEXTURE);
+		m_submit->m_commands.write(id);
+	}
 
-	///	Tasks to perform before a frame is rendered.
-	virtual void			frame() = 0;
+	inline ShaderId create_shader(ShaderType type, const char* text)
+	{
+		const ShaderId id = m_shaders.create();
+
+		m_submit->m_commands.write(COMMAND_CREATE_SHADER);
+		m_submit->m_commands.write(id);
+		m_submit->m_commands.write(type);
+		m_submit->m_commands.write(text);
+
+		return id;
+	}
+
+	inline void destroy_shader(ShaderId id)
+	{
+		m_submit->m_commands.write(COMMAND_DESTROY_SHADER);
+		m_submit->m_commands.write(id);
+	}
+
+	inline GPUProgramId create_gpu_program(ShaderId vertex, ShaderId pixel)
+	{
+		const GPUProgramId id = m_gpu_programs.create();
+
+		m_submit->m_commands.write(COMMAND_CREATE_GPU_PROGRAM);
+		m_submit->m_commands.write(id);
+		m_submit->m_commands.write(vertex);
+		m_submit->m_commands.write(pixel);
+
+		return id;
+	}
+
+	inline void destroy_gpu_program(GPUProgramId id)
+	{
+		m_submit->m_commands.write(COMMAND_DESTROY_GPU_PROGRAM);
+		m_submit->m_commands.write(id);
+	}
+
+	// UniformId create_uniform(const char* name, UniformType type)
+	// {
+
+	// }
+	// void destroy_uniform(UniformId id)
+	// {
+
+	// }
+	// 
+	// RenderTargetId create_render_target(uint16_t width, uint16_t height, RenderTargetFormat format)
+	// {
+
+	// }
+	// void destroy_render_target(RenderTargetId id)
+	// {
+
+	// }
+
+	//-----------------------------------------------------------------------------
+	inline void execute_commands(CommandBuffer& cmds)
+	{
+		bool end = false;
+
+		do
+		{
+			CommandType command;
+			cmds.read(command);
+
+			switch (command)
+			{
+				case COMMAND_INIT_RENDERER:
+				{
+					init_impl();
+					m_is_initialized = true;
+					break;
+				}
+				case COMMAND_SHUTDOWN_RENDERER:
+				{
+					shutdown_impl();
+					m_is_initialized = false;
+					break;
+				}
+				case COMMAND_CREATE_VERTEX_BUFFER:
+				{
+					VertexBufferId id;
+					size_t count;
+					VertexFormat format;
+					void* vertices;
+
+					cmds.read(id);
+					cmds.read(count);
+					cmds.read(format);
+					cmds.read(vertices);
+
+					create_vertex_buffer_impl(id, count, format, vertices);
+					break;
+				}
+				case COMMAND_UPDATE_VERTEX_BUFFER:
+				{
+					VertexBufferId id;
+					size_t offset;
+					size_t count;
+					void* vertices;
+
+					cmds.read(id);
+					cmds.read(offset);
+					cmds.read(count);
+					cmds.read(vertices);
+
+					update_vertex_buffer_impl(id, offset, count, vertices);			
+					break;
+				}
+				case COMMAND_DESTROY_VERTEX_BUFFER:
+				{
+					VertexBufferId id;
+					cmds.read(id);
+
+					destroy_vertex_buffer_impl(id);
+					break;
+				}
+				case COMMAND_CREATE_INDEX_BUFFER:
+				{
+					IndexBufferId id;
+					size_t count;
+					void* indices;
+
+					cmds.read(id);
+					cmds.read(count);
+					cmds.read(indices);
+
+					create_index_buffer_impl(id, count, indices);
+					break;
+				}
+				case COMMAND_DESTROY_INDEX_BUFFER:
+				{
+					IndexBufferId id;
+					cmds.read(id);
+
+					destroy_index_buffer_impl(id);
+					break;
+				}
+				case COMMAND_CREATE_TEXTURE:
+				{
+					TextureId id;
+					uint32_t width;
+					uint32_t height;
+					PixelFormat format;
+					void* data;
+
+					cmds.read(id);
+					cmds.read(width);
+					cmds.read(height);
+					cmds.read(format);
+					cmds.read(data);
+
+					create_texture_impl(id, width, height, format, data);
+					break;
+				}
+				case COMMAND_UPDATE_TEXTURE:
+				{
+					TextureId id;
+					uint32_t x;
+					uint32_t y;
+					uint32_t width;
+					uint32_t height;
+					void* data;
+
+					cmds.read(id);
+					cmds.read(x);
+					cmds.read(y);
+					cmds.read(width);
+					cmds.read(height);
+					cmds.read(data);
+
+					update_texture_impl(id, x, y, width, height, data);
+					break;
+				}
+				case COMMAND_DESTROY_TEXTURE:
+				{
+					TextureId id;
+					cmds.read(id);
+
+					destroy_texture_impl(id);
+					break;
+				}
+				case COMMAND_CREATE_SHADER:
+				{
+					ShaderId id;
+					ShaderType type;
+					char* text;
+
+					cmds.read(id);
+					cmds.read(type);
+					cmds.read(text);
+
+					create_shader_impl(id, type, text);
+					break;
+				}
+				case COMMAND_DESTROY_SHADER:
+				{
+					ShaderId id;
+					cmds.read(id);
+
+					destroy_shader_impl(id);
+					break;
+				}
+				case COMMAND_CREATE_GPU_PROGRAM:
+				{
+					GPUProgramId id;
+					ShaderId vertex;
+					ShaderId pixel;
+
+					cmds.read(id);
+					cmds.read(vertex);
+					cmds.read(pixel);
+
+					create_gpu_program_impl(id, vertex, pixel);
+					break;
+				}
+				case COMMAND_DESTROY_GPU_PROGRAM:
+				{
+					GPUProgramId id;
+					cmds.read(id);
+
+					destroy_gpu_program_impl(id);
+					break;
+				}
+				case COMMAND_CREATE_UNIFORM:
+				{
+					break;
+				}
+				case COMMAND_DESTROY_UNIFORM:
+				{
+					break;
+				}
+				case COMMAND_END:
+				{
+					end = true;
+					break;
+				}
+				default:
+				{
+					CE_ASSERT(false, "Oops, unknown command");
+					break;
+				}
+			}
+		}
+		while (!end);
+
+		cmds.clear();
+	}
 
 	inline void set_state(uint64_t flags)
 	{
-		m_render_context.set_state(flags);
+		m_submit->set_state(flags);
 	}
 
 	inline void set_pose(const Mat4& pose)
 	{
-		m_render_context.set_pose(pose);
+		m_submit->set_pose(pose);
 	}
 
 	inline void set_program(GPUProgramId program)
 	{
-		m_render_context.set_program(program);
+		m_submit->set_program(program);
 	}
 
 	inline void set_vertex_buffer(VertexBufferId vb)
 	{
-		m_render_context.set_vertex_buffer(vb);
+		m_submit->set_vertex_buffer(vb);
 	}
 
 	inline void set_index_buffer(IndexBufferId ib)
 	{
-		m_render_context.set_index_buffer(ib);
+		m_submit->set_index_buffer(ib);
 	}
 
 	inline void set_texture(uint8_t unit, TextureId texture, uint32_t flags)
 	{
-		m_render_context.set_texture(unit, texture, flags);
+		m_submit->set_texture(unit, texture, flags);
 	}
 
 	inline void set_layer_render_target(uint8_t layer, RenderTargetId target)
 	{
-		m_render_context.set_layer_render_target(layer, target);
+		m_submit->set_layer_render_target(layer, target);
 	}
 
 	inline void set_layer_clear(uint8_t layer, uint8_t flags, const Color4& color, float depth)
 	{
-		m_render_context.set_layer_clear(layer, flags, color, depth);
+		m_submit->set_layer_clear(layer, flags, color, depth);
 	}
 
 	inline void set_layer_view(uint8_t layer, const Mat4& view)
 	{
-		 m_render_context.set_layer_view(layer, view);
+		m_submit->set_layer_view(layer, view);
 	}
 
 	inline void set_layer_projection(uint8_t layer, const Mat4& projection)
 	{
-		m_render_context.set_layer_projection(layer, projection);
+		m_submit->set_layer_projection(layer, projection);
 	}
 
 	inline void set_layer_viewport(uint8_t layer, uint16_t x, uint16_t y, uint16_t width, uint16_t height)
 	{
-		m_render_context.set_layer_viewport(layer, x, y, width, height);
+		m_submit->set_layer_viewport(layer, x, y, width, height);
 	}
 
 	inline void set_layer_scissor(uint8_t layer, uint16_t x, uint16_t y, uint16_t width, uint16_t height)
 	{
-		m_render_context.set_layer_scissor(layer, x, y, width, height);
+		m_submit->set_layer_scissor(layer, x, y, width, height);
 	}
 
 	inline void commit(uint8_t layer)
 	{
-		m_render_context.commit(layer);
+		m_submit->commit(layer);
+	}
+
+	inline void swap_contexts()
+	{
+		// Ensure COMMAND_END at the end of submit command buffer
+		m_submit->push();
+
+		RenderContext* temp = m_submit;
+		m_submit = m_draw;
+		m_draw = temp;
+	}
+
+	// Do all the processing needed to render a frame
+	inline void frame()
+	{
+		swap_contexts();
+
+		execute_commands(m_draw->m_commands);
+
+		if (m_is_initialized)
+		{
+			render_impl();
+		}
 	}
 
 protected:
 
-	RenderContext m_render_context;
+	Allocator& m_allocator;
+	RendererImplementation* m_impl;
+
+	RenderContext m_contexts[2];
+	RenderContext* m_submit;
+	RenderContext* m_draw;
+
+	// Id tables
+	IdTable<CROWN_MAX_VERTEX_BUFFERS> m_vertex_buffers;
+	IdTable<CROWN_MAX_INDEX_BUFFERS> m_index_buffers;
+	IdTable<CROWN_MAX_TEXTURES> m_textures;
+	IdTable<CROWN_MAX_SHADERS> m_shaders;
+	IdTable<CROWN_MAX_GPU_PROGRAMS> m_gpu_programs;
+	// IdTable<CROWN_MAX_UNIFORMS> m_uniforms;
+	// IdTable<CROWN_MAX_RENDER_TARGETS> m_render_targets;
+
+	bool m_is_initialized;
 };
 
 } // namespace crown

+ 342 - 382
engine/renderers/gl/GLRenderer.cpp

@@ -82,476 +82,436 @@ const GLenum TEXTURE_WRAP_TABLE[] =
 	GL_REPEAT
 };
 
-//-----------------------------------------------------------------------------
-GLRenderer::GLRenderer() :
-	m_max_texture_size(0),
-	m_max_texture_units(0),
-	m_max_vertex_indices(0),
-	m_max_vertex_vertices(0),
-	m_max_anisotropy(0.0f),
-
-	m_textures_id_table(m_allocator, CROWN_MAX_TEXTURES),
-	m_vertex_buffers_id_table(m_allocator, CROWN_MAX_VERTEX_BUFFERS),
-	m_index_buffers_id_table(m_allocator, CROWN_MAX_INDEX_BUFFERS),
-	m_shaders_id_table(m_allocator, CROWN_MAX_SHADERS),
-	m_gpu_programs_id_table(m_allocator, CROWN_MAX_GPU_PROGRAMS),
-	m_uniforms_id_table(m_allocator, CROWN_MAX_UNIFORMS),
-	m_render_targets_id_table(m_allocator, CROWN_MAX_RENDER_TARGETS)
+/// OpenGL renderer
+class RendererImplementation
 {
-	m_min_max_point_size[0] = 0.0f;
-	m_min_max_point_size[1] = 0.0f;
-	m_min_max_line_width[0] = 0.0f;
-	m_min_max_line_width[1] = 0.0f;
-}
+public:
 
-//-----------------------------------------------------------------------------
-GLRenderer::~GLRenderer()
-{
-}
+	//-----------------------------------------------------------------------------
+	RendererImplementation()
+		: m_max_texture_size(0), m_max_texture_units(0), m_max_vertex_indices(0), m_max_vertex_vertices(0),
+			m_max_anisotropy(0.0f)
+	{
+		m_min_max_point_size[0] = 0.0f;
+		m_min_max_point_size[1] = 0.0f;
+		m_min_max_line_width[0] = 0.0f;
+		m_min_max_line_width[1] = 0.0f;
+	}
 
-//-----------------------------------------------------------------------------
-void GLRenderer::init()
-{
-	m_context.create_context();
+	//-----------------------------------------------------------------------------
+	~RendererImplementation()
+	{
+	}
 
-	GLenum err = glewInit();
-	CE_ASSERT(err == GLEW_OK, "Failed to initialize GLEW");
+	//-----------------------------------------------------------------------------
+	void init()
+	{
+		m_gl_context.create_context();
 
-	GL_CHECK(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size));
-	GL_CHECK(glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &m_max_texture_units));
-	GL_CHECK(glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &m_max_vertex_indices));
-	GL_CHECK(glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &m_max_vertex_vertices));
+		GLenum err = glewInit();
+		CE_ASSERT(err == GLEW_OK, "Failed to initialize GLEW");
 
-	GL_CHECK(glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, &m_min_max_point_size[0]));
-	GL_CHECK(glGetFloatv(GL_LINE_WIDTH_RANGE, &m_min_max_line_width[0]));
+		GL_CHECK(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size));
+		GL_CHECK(glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &m_max_texture_units));
+		GL_CHECK(glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &m_max_vertex_indices));
+		GL_CHECK(glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &m_max_vertex_vertices));
 
-	Log::i("OpenGL Vendor        : %s", glGetString(GL_VENDOR));
-	Log::i("OpenGL Renderer      : %s", glGetString(GL_RENDERER));
-	Log::i("OpenGL Version       : %s", glGetString(GL_VERSION));
-	Log::i("GLSL Version         : %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
+		GL_CHECK(glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, &m_min_max_point_size[0]));
+		GL_CHECK(glGetFloatv(GL_LINE_WIDTH_RANGE, &m_min_max_line_width[0]));
 
-	Log::d("Min Point Size       : %f", m_min_max_point_size[0]);
-	Log::d("Max Point Size       : %f", m_min_max_point_size[1]);
-	Log::d("Min Line Width       : %f", m_min_max_line_width[0]);
-	Log::d("Max Line Width       : %f", m_min_max_line_width[1]);
-	Log::d("Max Texture Size     : %dx%d", m_max_texture_size, m_max_texture_size);
-	Log::d("Max Texture Units    : %d", m_max_texture_units);
-	Log::d("Max Vertex Indices   : %d", m_max_vertex_indices);
-	Log::d("Max Vertex Vertices  : %d", m_max_vertex_vertices);
+		Log::i("OpenGL Vendor        : %s", glGetString(GL_VENDOR));
+		Log::i("OpenGL Renderer      : %s", glGetString(GL_RENDERER));
+		Log::i("OpenGL Version       : %s", glGetString(GL_VERSION));
+		Log::i("GLSL Version         : %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
 
-	GL_CHECK(glDisable(GL_BLEND));
-	GL_CHECK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
-	GL_CHECK(glBlendEquation(GL_FUNC_ADD));
+		Log::d("Min Point Size       : %f", m_min_max_point_size[0]);
+		Log::d("Max Point Size       : %f", m_min_max_point_size[1]);
+		Log::d("Min Line Width       : %f", m_min_max_line_width[0]);
+		Log::d("Max Line Width       : %f", m_min_max_line_width[1]);
+		Log::d("Max Texture Size     : %dx%d", m_max_texture_size, m_max_texture_size);
+		Log::d("Max Texture Units    : %d", m_max_texture_units);
+		Log::d("Max Vertex Indices   : %d", m_max_vertex_indices);
+		Log::d("Max Vertex Vertices  : %d", m_max_vertex_vertices);
 
-	GL_CHECK(glShadeModel(GL_SMOOTH));
+		GL_CHECK(glDisable(GL_BLEND));
+		GL_CHECK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
+		GL_CHECK(glBlendEquation(GL_FUNC_ADD));
 
-	// Enable depth test
-	GL_CHECK(glEnable(GL_DEPTH_TEST));
-	GL_CHECK(glDepthFunc(GL_LEQUAL));
-	GL_CHECK(glClearDepth(1.0));
+		GL_CHECK(glShadeModel(GL_SMOOTH));
 
-	// Point sprites enabled by default
-	GL_CHECK(glEnable(GL_POINT_SPRITE));
-	GL_CHECK(glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE));
+		// Enable depth test
+		GL_CHECK(glEnable(GL_DEPTH_TEST));
+		GL_CHECK(glDepthFunc(GL_LEQUAL));
+		GL_CHECK(glClearDepth(1.0));
 
-	Log::i("OpenGL Renderer initialized.");
-}
+		// Point sprites enabled by default
+		GL_CHECK(glEnable(GL_POINT_SPRITE));
+		GL_CHECK(glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE));
 
-//-----------------------------------------------------------------------------
-void GLRenderer::shutdown()
-{
-	m_context.destroy_context();
-}
+		Log::i("OpenGL Renderer initialized.");
+	}
 
-//-----------------------------------------------------------------------------
-VertexBufferId GLRenderer::create_vertex_buffer(size_t count, VertexFormat format, const void* vertices)
-{
-	const VertexBufferId id = m_vertex_buffers_id_table.create();
+	//-----------------------------------------------------------------------------
+	void shutdown()
+	{
+		m_gl_context.destroy_context();
+	}
 
-	VertexBuffer& buffer = m_vertex_buffers[id.index];
-	buffer.create(count, format, vertices);
+	//-----------------------------------------------------------------------------
+	void render(RenderContext& context)
+	{
+		//RenderTargetId old_rt;
+		//old_rt.id = INVALID_ID;
+		uint8_t layer = 0xFF;
 
-	return id;
-}
+		for (uint32_t s = 0; s < context.m_num_states; s++)
+		{
+			const uint64_t key_s = context.m_keys[s];
+			RenderKey key;
+			key.decode(key_s);
+			const RenderState& cur_state = context.m_states[s];
+			const uint64_t flags = cur_state.m_flags;
+			//const RenderTargetId& cur_rt = context.m_targets[layer];
+
+			// Check if layer changed
+			if (key.m_layer != layer)
+			{
+				layer = key.m_layer;
+
+				// Viewport
+				const ViewRect& viewport = context.m_viewports[layer];
+				GL_CHECK(glViewport(viewport.m_x, viewport.m_y, viewport.m_width, viewport.m_height));
+
+				// Clear frame/depth buffer
+				const ClearState& clear = context.m_clears[layer];
+				if (clear.m_flags & (CLEAR_COLOR | CLEAR_DEPTH))
+				{
+					GLbitfield gl_clear = (clear.m_flags & CLEAR_COLOR) ? GL_COLOR_BUFFER_BIT : 0;
+					gl_clear |= (clear.m_flags & CLEAR_DEPTH) ? GL_DEPTH_BUFFER_BIT : 0;
+					GL_CHECK(glClearColor(clear.m_color.r, clear.m_color.g, clear.m_color.b, clear.m_color.a));
+					GL_CHECK(glClearDepth(clear.m_depth));
+					GL_CHECK(glClear(gl_clear));
+				}
+			}
+
+			// Scissor
+			const ViewRect& scissor = context.m_scissors[layer];
+			if (scissor.area() != 0)
+			{
+				GL_CHECK(glEnable(GL_SCISSOR_TEST));
+				GL_CHECK(glScissor(scissor.m_x, scissor.m_y, scissor.m_width, scissor.m_height));
+			}
+			else
+			{
+				GL_CHECK(glDisable(GL_SCISSOR_TEST));
+			}
+
+			// Depth write
+			if (flags & (STATE_DEPTH_WRITE))
+			{
+				GL_CHECK(glDepthMask(flags & STATE_DEPTH_WRITE));
+			}
+
+			// Color/Alpha write
+			if (flags & (STATE_COLOR_WRITE | STATE_ALPHA_WRITE))
+			{
+				GLboolean cw = !!(flags & STATE_COLOR_WRITE);
+				GLboolean aw = !!(flags & STATE_ALPHA_WRITE);
+				GL_CHECK(glColorMask(cw, cw, cw, aw));
+			}
+
+			// Face culling
+			if (flags & (STATE_CULL_CW | STATE_CULL_CCW))
+			{
+				if (flags & STATE_CULL_CW)
+				{
+					GL_CHECK(glEnable(GL_CULL_FACE));
+					GL_CHECK(glCullFace(GL_BACK));
+				}
+				else if (flags & STATE_CULL_CCW)
+				{
+					GL_CHECK(glEnable(GL_CULL_FACE));
+					GL_CHECK(glCullFace(GL_FRONT));
+				}
+			}
+			else
+			{
+				GL_CHECK(glDisable(GL_CULL_FACE));
+			}
+
+			// Bind GPU program
+			if (cur_state.program.id != INVALID_ID)
+			{
+				const GPUProgram& gpu_program = m_gpu_programs[cur_state.program.index];
+				GL_CHECK(glUseProgram(gpu_program.m_id));
+
+				for (uint8_t uniform = 0; uniform < gpu_program.m_num_stock_uniforms; uniform++)
+				{
+					const GLint& uniform_location = gpu_program.m_stock_uniform_locations[uniform];
+					const Mat4& view = context.m_view_matrices[layer];
+					const Mat4& projection = context.m_projection_matrices[layer];
+
+					switch (gpu_program.m_stock_uniforms[uniform])
+					{
+						case UNIFORM_VIEW:
+						{
+							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, view.to_float_ptr()));
+							break;
+						}
+						case UNIFORM_MODEL:
+						{
+							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, cur_state.pose.to_float_ptr()));
+							break;
+						}
+						case UNIFORM_MODEL_VIEW:
+						{
+							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, (view *
+															cur_state.pose).to_float_ptr()));
+							break;
+						}
+						case UNIFORM_MODEL_VIEW_PROJECTION:
+						{
+							GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, (projection * view *
+															cur_state.pose).to_float_ptr()));
+							break;
+						}
+						case UNIFORM_TIME_SINCE_START:
+						{
+							GL_CHECK(glUniform1f(uniform_location, device()->time_since_start()));
+							break;
+						}
+						default:
+						{
+							CE_ASSERT(false, "Oops, wrong stock uniform!");
+							break;
+						}
+					}
+				}
+			}
+			else
+			{
+				GL_CHECK(glUseProgram(0));
+			}
+
+			// Bind array buffers
+			const VertexBufferId& vb = cur_state.vb;
+			if (vb.id != INVALID_ID)
+			{
+				const VertexBuffer& vertex_buffer = m_vertex_buffers[vb.index];
+				glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer.m_id);
+
+				const GPUProgram& gpu_program = m_gpu_programs[cur_state.program.index];
+				gpu_program.bind_attributes(vertex_buffer.m_format);
+			}
+			else
+			{
+				GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
+			}
+
+			const IndexBufferId& ib = cur_state.ib;
+			if (ib.id != INVALID_ID)
+			{
+				const IndexBuffer& index_buffer = m_index_buffers[ib.index];
+				uint32_t prim_type = (flags & STATE_PRIMITIVE_MASK) >> STATE_PRIMITIVE_SHIFT;
+				GLenum gl_prim_type = PRIMITIVE_TYPE_TABLE[prim_type];
+				GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer.m_id));
+				GL_CHECK(glDrawElements(gl_prim_type, index_buffer.m_index_count, GL_UNSIGNED_SHORT, 0));
+			}
+			else
+			{
+				GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+			}
+
+			// Bind textures
+			{
+				uint64_t flags = STATE_TEXTURE_0;
+				for (uint32_t unit = 0; unit < STATE_MAX_TEXTURES; unit++)
+				{
+					const Sampler& sampler = cur_state.samplers[unit];
+
+					if (sampler.sampler_id.id != INVALID_ID)
+					{
+						switch (sampler.flags & SAMPLER_MASK)
+						{
+							case SAMPLER_TEXTURE:
+							{
+								Texture& texture = m_textures[sampler.sampler_id.index];
+								texture.commit(unit, sampler.flags);
+								break;
+							}
+							default:
+							{
+								CE_ASSERT(false, "Oops, sampler unknown");
+								break;
+							}
+						}
+					}
+
+					flags <<= 1;
+				}
+			}
+		}
+
+		GL_CHECK(glFinish());
+
+		context.clear();
+		m_gl_context.swap_buffers();
+	}
+
+private:
+
+	GLContext			m_gl_context;
+
+	// Limits
+	int32_t				m_max_texture_size;
+	int32_t				m_max_texture_units;
+	int32_t				m_max_vertex_indices;
+	int32_t				m_max_vertex_vertices;
+
+	float				m_max_anisotropy;
+	float				m_min_max_point_size[2];
+	float				m_min_max_line_width[2];
+
+	VertexBuffer		m_vertex_buffers[CROWN_MAX_VERTEX_BUFFERS];
+	IndexBuffer			m_index_buffers[CROWN_MAX_INDEX_BUFFERS];
+	Texture				m_textures[CROWN_MAX_TEXTURES];
+	Shader				m_shaders[CROWN_MAX_SHADERS];
+	GPUProgram			m_gpu_programs[CROWN_MAX_GPU_PROGRAMS];
+	Uniform				m_uniforms[CROWN_MAX_UNIFORMS];
+	RenderTarget		m_render_targets[CROWN_MAX_RENDER_TARGETS];
+
+private:
+
+	friend class		Renderer;
+};
 
 //-----------------------------------------------------------------------------
-void GLRenderer::update_vertex_buffer(VertexBufferId id, size_t offset, size_t count, const void* vertices)
+Renderer::Renderer(Allocator& a)
+	: m_allocator(a), m_impl(NULL), m_submit(&m_contexts[0]), m_draw(&m_contexts[1]), m_is_initialized(false)
 {
-	CE_ASSERT(m_vertex_buffers_id_table.has(id), "Vertex buffer does not exist");
-
-	VertexBuffer& buffer = m_vertex_buffers[id.index];
-	buffer.update(offset, count, vertices);
+	m_impl = CE_NEW(a, RendererImplementation);
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::destroy_vertex_buffer(VertexBufferId id)
+Renderer::~Renderer()
 {
-	CE_ASSERT(m_vertex_buffers_id_table.has(id), "Vertex buffer does not exist");
-
-	VertexBuffer& buffer = m_vertex_buffers[id.index];
-	buffer.destroy();
-
-	m_vertex_buffers_id_table.destroy(id);
+	CE_DELETE(m_allocator, m_impl);
 }
 
 //-----------------------------------------------------------------------------
-IndexBufferId GLRenderer::create_index_buffer(size_t count, const void* indices)
+void Renderer::init_impl()
 {
-	const IndexBufferId id = m_index_buffers_id_table.create();
-
-	IndexBuffer& buffer = m_index_buffers[id.index];
-	buffer.create(count, indices);
-
-	return id;
+	m_impl->init();
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::destroy_index_buffer(IndexBufferId id)
+void Renderer::shutdown_impl()
 {
-	CE_ASSERT(m_index_buffers_id_table.has(id), "Index buffer does not exist");
-
-	IndexBuffer& buffer = m_index_buffers[id.index];
-	buffer.destroy();
-
-	m_index_buffers_id_table.destroy(id);
+	m_impl->shutdown();
 }
 
 //-----------------------------------------------------------------------------
-TextureId GLRenderer::create_texture(uint32_t width, uint32_t height, PixelFormat format, const void* data)
+void Renderer::render_impl()
 {
-	const TextureId id = m_textures_id_table.create();
-	Texture& texture = m_textures[id.index];
-
-	texture.create(width, height, format, data);
-
-	return id;
+	m_impl->render(*m_draw);
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::update_texture(TextureId id, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const void* data)
+void Renderer::create_vertex_buffer_impl(VertexBufferId id, size_t count, VertexFormat format, const void* vertices)
 {
-	CE_ASSERT(m_textures_id_table.has(id), "Texture does not exist");
-
-	Texture& texture = m_textures[id.index];
-	texture.update(x, y, width, height, data);
+	m_impl->m_vertex_buffers[id.index].create(count, format, vertices);
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::destroy_texture(TextureId id)
+void Renderer::update_vertex_buffer_impl(VertexBufferId id, size_t offset, size_t count, const void* vertices)
 {
-	CE_ASSERT(m_textures_id_table.has(id), "Texture does not exist");
-
-	Texture& texture = m_textures[id.index];
-	texture.destroy();
-
-	m_textures_id_table.destroy(id);
+	m_impl->m_vertex_buffers[id.index].update(offset, count, vertices);
 }
 
 //-----------------------------------------------------------------------------
-ShaderId GLRenderer::create_shader(ShaderType type, const char* text)
+void Renderer::destroy_vertex_buffer_impl(VertexBufferId id)
 {
-	CE_ASSERT_NOT_NULL(text);
-
-	const ShaderId& id = m_shaders_id_table.create();
-
-	Shader& shader = m_shaders[id.index];
-	shader.create(type, text);
-
-	return id;	
+	m_impl->m_vertex_buffers[id.index].destroy();
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::destroy_shader(ShaderId id)
+void Renderer::create_index_buffer_impl(IndexBufferId id, size_t count, const void* indices)
 {
-	CE_ASSERT(m_shaders_id_table.has(id), "Shader does not exist");
-
-	Shader& shader = m_shaders[id.index];
-	shader.destroy();
-
-	m_shaders_id_table.destroy(id);
+	m_impl->m_index_buffers[id.index].create(count, indices);
 }
 
 //-----------------------------------------------------------------------------
-GPUProgramId GLRenderer::create_gpu_program(ShaderId vertex, ShaderId pixel)
+void Renderer::destroy_index_buffer_impl(IndexBufferId id)
 {
-	CE_ASSERT(m_shaders_id_table.has(vertex), "Vertex shader does not exist");
-	CE_ASSERT(m_shaders_id_table.has(pixel), "Pixel shader does not exist");
-
-	const GPUProgramId id = m_gpu_programs_id_table.create();
-	GPUProgram& program = m_gpu_programs[id.index];
-
-	program.create(m_shaders[vertex.index], m_shaders[pixel.index]);
-
-	return id;
+	m_impl->m_index_buffers[id.index].destroy();
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::destroy_gpu_program(GPUProgramId id)
+void Renderer::create_texture_impl(TextureId id, uint32_t width, uint32_t height, PixelFormat format, const void* data)
 {
-	CE_ASSERT(m_gpu_programs_id_table.has(id), "GPU program does not exist");
-
-	GPUProgram& program = m_gpu_programs[id.index];
-
-	program.destroy();
-
-	m_gpu_programs_id_table.destroy(id);
+	m_impl->m_textures[id.index].create(width, height, format, data);
 }
 
 //-----------------------------------------------------------------------------
-UniformId GLRenderer::create_uniform(const char* name, UniformType type)
+void Renderer::update_texture_impl(TextureId id, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const void* data)
 {
-	const UniformId id = m_uniforms_id_table.create(); 
-	Uniform& uniform = m_uniforms[id.index];
-
-	uniform.m_name = hash::murmur2_32(name, string::strlen(name), 0);
-	uniform.m_type = type;
-
-	return id;
+	m_impl->m_textures[id.index].update(x, y, width, height, data);	
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::destroy_uniform(UniformId id)
+void Renderer::destroy_texture_impl(TextureId id)
 {
-	CE_ASSERT(m_uniforms_id_table.has(id), "Uniform does not exist");
-
-	m_uniforms_id_table.destroy(id);
+	m_impl->m_textures[id.index].destroy();
 }
 
 //-----------------------------------------------------------------------------
-RenderTargetId GLRenderer::create_render_target(uint16_t width, uint16_t height, RenderTargetFormat format)
+void Renderer::create_shader_impl(ShaderId id, ShaderType type, const char* text)
 {
-	const RenderTargetId id = m_render_targets_id_table.create();
-	RenderTarget& target = m_render_targets[id.index];
-
-	target.create(width, height, format);
-
-	return id;
+	m_impl->m_shaders[id.index].create(type, text);
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::destroy_render_target(RenderTargetId id)
+void Renderer::destroy_shader_impl(ShaderId id)
 {
-	CE_ASSERT(m_render_targets_id_table.has(id), "Render target does not exist");
-
-	RenderTarget& target = m_render_targets[id.index];
-
-	target.destroy();
-
-	m_render_targets_id_table.destroy(id);
+	m_impl->m_shaders[id.index].destroy();
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::frame()
+void Renderer::create_gpu_program_impl(GPUProgramId id, ShaderId vertex, ShaderId pixel)
 {
-	//RenderTargetId old_rt;
-	//old_rt.id = INVALID_ID;
-	uint8_t layer = 0xFF;
-
-	for (uint32_t s = 0; s < m_render_context.m_num_states; s++)
-	{
-		const uint64_t key_s = m_render_context.m_keys[s];
-		RenderKey key;
-		key.decode(key_s);
-		const RenderState& cur_state = m_render_context.m_states[s];
-		const uint64_t flags = cur_state.m_flags;
-		//const RenderTargetId& cur_rt = m_render_context.m_targets[layer];
-
-		// Check if layer changed
-		if (key.m_layer != layer)
-		{
-			layer = key.m_layer;
-
-			// Viewport
-			const ViewRect& viewport = m_render_context.m_viewports[layer];
-			GL_CHECK(glViewport(viewport.m_x, viewport.m_y, viewport.m_width, viewport.m_height));
-
-			// Clear frame/depth buffer
-			const ClearState& clear = m_render_context.m_clears[layer];
-			if (clear.m_flags & (CLEAR_COLOR | CLEAR_DEPTH))
-			{
-				GLbitfield gl_clear = (clear.m_flags & CLEAR_COLOR) ? GL_COLOR_BUFFER_BIT : 0;
-				gl_clear |= (clear.m_flags & CLEAR_DEPTH) ? GL_DEPTH_BUFFER_BIT : 0;
-				GL_CHECK(glClearColor(clear.m_color.r, clear.m_color.g, clear.m_color.b, clear.m_color.a));
-				GL_CHECK(glClearDepth(clear.m_depth));
-				GL_CHECK(glClear(gl_clear));
-			}
-		}
-
-		// Scissor
-		const ViewRect& scissor = m_render_context.m_scissors[layer];
-		if (scissor.area() != 0)
-		{
-			GL_CHECK(glEnable(GL_SCISSOR_TEST));
-			GL_CHECK(glScissor(scissor.m_x, scissor.m_y, scissor.m_width, scissor.m_height));
-		}
-		else
-		{
-			GL_CHECK(glDisable(GL_SCISSOR_TEST));
-		}
-
-		// Depth write
-		if (flags & (STATE_DEPTH_WRITE))
-		{
-			GL_CHECK(glDepthMask(flags & STATE_DEPTH_WRITE));
-		}
-
-		// Color/Alpha write
-		if (flags & (STATE_COLOR_WRITE | STATE_ALPHA_WRITE))
-		{
-			GLboolean cw = !!(flags & STATE_COLOR_WRITE);
-			GLboolean aw = !!(flags & STATE_ALPHA_WRITE);
-			GL_CHECK(glColorMask(cw, cw, cw, aw));
-		}
-
-		// Face culling
-		if (flags & (STATE_CULL_CW | STATE_CULL_CCW))
-		{
-			if (flags & STATE_CULL_CW)
-			{
-				GL_CHECK(glEnable(GL_CULL_FACE));
-				GL_CHECK(glCullFace(GL_BACK));
-			}
-			else if (flags & STATE_CULL_CCW)
-			{
-				GL_CHECK(glEnable(GL_CULL_FACE));
-				GL_CHECK(glCullFace(GL_FRONT));
-			}
-		}
-		else
-		{
-			GL_CHECK(glDisable(GL_CULL_FACE));
-		}
-
-		// Bind GPU program
-		if (cur_state.program.id != INVALID_ID)
-		{
-			const GPUProgram& gpu_program = m_gpu_programs[cur_state.program.index];
-			GL_CHECK(glUseProgram(gpu_program.m_id));
-
-			for (uint8_t uniform = 0; uniform < gpu_program.m_num_stock_uniforms; uniform++)
-			{
-				const GLint& uniform_location = gpu_program.m_stock_uniform_locations[uniform];
-				const Mat4& view = m_render_context.m_view_matrices[layer];
-				const Mat4& projection = m_render_context.m_projection_matrices[layer];
-
-				switch (gpu_program.m_stock_uniforms[uniform])
-				{
-					case UNIFORM_VIEW:
-					{
-						GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, view.to_float_ptr()));
-						break;
-					}
-					case UNIFORM_MODEL:
-					{
-						GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, cur_state.pose.to_float_ptr()));
-						break;
-					}
-					case UNIFORM_MODEL_VIEW:
-					{
-						GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, (view *
-														cur_state.pose).to_float_ptr()));
-						break;
-					}
-					case UNIFORM_MODEL_VIEW_PROJECTION:
-					{
-						GL_CHECK(glUniformMatrix4fv(uniform_location, 1, GL_FALSE, (projection * view *
-														cur_state.pose).to_float_ptr()));
-						break;
-					}
-					case UNIFORM_TIME_SINCE_START:
-					{
-						GL_CHECK(glUniform1f(uniform_location, device()->time_since_start()));
-						break;
-					}
-					default:
-					{
-						CE_ASSERT(false, "Oops, wrong stock uniform!");
-						break;
-					}
-				}
-			}
-		}
-		else
-		{
-			GL_CHECK(glUseProgram(0));
-		}
-
-		// Bind array buffers
-		const VertexBufferId& vb = cur_state.vb;
-		if (vb.id != INVALID_ID)
-		{
-			const VertexBuffer& vertex_buffer = m_vertex_buffers[vb.index];
-			glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer.m_id);
+	Shader& vs = m_impl->m_shaders[vertex.index];
+	Shader& ps = m_impl->m_shaders[pixel.index];
+	m_impl->m_gpu_programs[id.index].create(vs, ps);
+}
 
-			const GPUProgram& gpu_program = m_gpu_programs[cur_state.program.index];
-			gpu_program.bind_attributes(vertex_buffer.m_format);
-		}
-		else
-		{
-			GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
-		}
+//-----------------------------------------------------------------------------
+void Renderer::destroy_gpu_program_impl(GPUProgramId id)
+{
+	m_impl->m_gpu_programs[id.index].destroy();
+}
 
-		const IndexBufferId& ib = cur_state.ib;
-		if (ib.id != INVALID_ID)
-		{
-			const IndexBuffer& index_buffer = m_index_buffers[ib.index];
-			uint32_t prim_type = (flags & STATE_PRIMITIVE_MASK) >> STATE_PRIMITIVE_SHIFT;
-			GLenum gl_prim_type = PRIMITIVE_TYPE_TABLE[prim_type];
-			GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer.m_id));
-			GL_CHECK(glDrawElements(gl_prim_type, index_buffer.m_index_count, GL_UNSIGNED_SHORT, 0));
-		}
-		else
-		{
-			GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
-		}
+// //-----------------------------------------------------------------------------
+// void Renderer::create_uniform_impl(UniformId id, const char* name, UniformType type)
+// {
 
-		// Bind textures
-		{
-			uint64_t flags = STATE_TEXTURE_0;
-			for (uint32_t unit = 0; unit < STATE_MAX_TEXTURES; unit++)
-			{
-				const Sampler& sampler = cur_state.samplers[unit];
+// }
 
-				if (sampler.sampler_id.id != INVALID_ID)
-				{
-					switch (sampler.flags & SAMPLER_MASK)
-					{
-						case SAMPLER_TEXTURE:
-						{
-							Texture& texture = m_textures[sampler.sampler_id.index];
-							texture.commit(unit, sampler.flags);
-							break;
-						}
-						default:
-						{
-							CE_ASSERT(false, "Oops, sampler unknown");
-							break;
-						}
-					}
-				}
+// //-----------------------------------------------------------------------------
+// void Renderer::destroy_uniform_impl(UniformId id)
+// {
 
-				flags <<= 1;
-			}
-		}
-	}
+// }
 
-	GL_CHECK(glFinish());
+// //-----------------------------------------------------------------------------
+// void Renderer::create_render_target_impl(RenderTargetId id, uint16_t width, uint16_t height, RenderTargetFormat format)
+// {
 
-	m_render_context.clear();
-	m_context.swap_buffers();
-}
+// }
 
-//-----------------------------------------------------------------------------
-Renderer* Renderer::create(Allocator& a)
-{
-	return CE_NEW(a, GLRenderer);
-}
+// //-----------------------------------------------------------------------------
+// void Renderer::destroy_render_target_impl(RenderTargetId id)
+// {
 
-//-----------------------------------------------------------------------------
-void Renderer::destroy(Allocator& a, Renderer* renderer)
-{
-	CE_DELETE(a, renderer);
-}
+// }
 
 } // namespace crown
-

+ 0 - 88
engine/renderers/gl/GLRenderer.h

@@ -478,92 +478,4 @@ struct RenderTarget
 	GLuint m_gl_rbo;
 };
 
-/// OpenGL renderer
-class GLRenderer : public Renderer
-{
-public:
-
-						GLRenderer();
-						~GLRenderer();
-
-	void				init();
-	void				shutdown();
-
-	// Vertex buffers
-	VertexBufferId		create_vertex_buffer(size_t count, VertexFormat format, const void* vertices);
-	void				update_vertex_buffer(VertexBufferId id, size_t offset, size_t count, const void* vertices);
-	void				destroy_vertex_buffer(VertexBufferId id);
-
-	// Index buffers
-	IndexBufferId		create_index_buffer(size_t count, const void* indices);
-	void				destroy_index_buffer(IndexBufferId id);
-
-	// Textures
-	TextureId			create_texture(uint32_t width, uint32_t height, PixelFormat format, const void* data);
-	void				update_texture(TextureId id, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const void* data);
-	void				destroy_texture(TextureId id);
-
-	// Vertex shaders
-	ShaderId			create_shader(ShaderType type, const char* text);
-	void				destroy_shader(ShaderId id);
-
-	// GPU programs
-	GPUProgramId		create_gpu_program(ShaderId vertex, ShaderId pixel);
-	void				destroy_gpu_program(GPUProgramId id);
-
-	UniformId			create_uniform(const char* name, UniformType type);
-	void				destroy_uniform(UniformId id);
-
-	// Render Targets
-	RenderTargetId		create_render_target(uint16_t width, uint16_t height, RenderTargetFormat format);
-	void				destroy_render_target(RenderTargetId id);
-
-	// Draws a complete frame
-	void				frame();
-
-private:
-
-	HeapAllocator		m_allocator;
-
-	// Limits
-	int32_t				m_max_texture_size;
-	int32_t				m_max_texture_units;
-	int32_t				m_max_vertex_indices;
-	int32_t				m_max_vertex_vertices;
-
-	float				m_max_anisotropy;
-	float				m_min_max_point_size[2];
-	float				m_min_max_line_width[2];
-
-	// Texture management
-	IdTable 			m_textures_id_table;
-	Texture				m_textures[CROWN_MAX_TEXTURES];
-
-	// Vertex/Index buffer management
-	IdTable				m_vertex_buffers_id_table;
-	VertexBuffer		m_vertex_buffers[CROWN_MAX_VERTEX_BUFFERS];
-
-	IdTable				m_index_buffers_id_table;
-	IndexBuffer			m_index_buffers[CROWN_MAX_INDEX_BUFFERS];
-
-	// Vertex shader management
-	IdTable 			m_shaders_id_table;
-	Shader				m_shaders[CROWN_MAX_SHADERS];
-
-	// GPU program management
-	IdTable 			m_gpu_programs_id_table;
-	GPUProgram			m_gpu_programs[CROWN_MAX_GPU_PROGRAMS];
-
-	IdTable				m_uniforms_id_table;
-	Uniform				m_uniforms[CROWN_MAX_UNIFORMS];
-
-	// Render buffer management
-	IdTable				m_render_targets_id_table;
-	RenderTarget		m_render_targets[CROWN_MAX_RENDER_TARGETS];
-
-	// Context management
-	GLContext			m_context;
-};
-
 } // namespace crown
-