Răsfoiți Sursa

Properly support vertex/index buffers

Daniele Bartolini 12 ani în urmă
părinte
comite
a68409c8af

+ 3 - 23
src/renderers/IndexBuffer.h

@@ -30,28 +30,8 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
-/**
-	Represents an index buffer to stream indexes to the GPU.
-*/
-class IndexBuffer
-{
-
-public:
-
-					IndexBuffer() {}
-	virtual			~IndexBuffer() {}
-
-					//! Set the index data
-	virtual void	SetIndexData(const uint16_t* indexData, uint32_t indexCount) = 0;
-					//! Replaces a subset of the index data
-	virtual void	SetIndexSubData(const uint16_t* indexData, uint32_t indexOffset, uint32_t indexCount) = 0;
-					//! Selects the index buffer as current index buffer
-
-	virtual uint32_t	GetIndexCount() const = 0;
-
-	virtual void	Bind() const = 0;
-	virtual void	Unbind() const = 0;
-};
+// Max number of index buffers a renderer can hold.
+const uint32_t MAX_INDEX_BUFFERS = 4096;
 
-}
+} // namespace crown
 

+ 47 - 14
src/renderers/Renderer.h

@@ -28,9 +28,14 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Types.h"
 #include "Color4.h"
 #include "Mat4.h"
-#include "Point2.h"
-#include "Material.h"
+#include "VertexBuffer.h"
+#include "IndexBuffer.h"
+#include "RenderBuffer.h"
 #include "Texture.h"
+#include "Material.h"
+#include "PixelFormat.h"
+#include "VertexFormat.h"
+#include "IdTable.h"
 
 namespace crown
 {
@@ -58,12 +63,10 @@ enum LightType
 	LT_SPOT			= 2
 };
 
-enum DrawMode
-{
-	DM_NO_DRAW		= 0,
-	DM_BORDER		= 1,
-	DM_FILL			= 2
-};
+typedef Id VertexBufferId;
+typedef Id IndexBufferId;
+typedef Id RenderBufferId;
+typedef Id TextureId;
 
 class Renderer
 {
@@ -72,6 +75,35 @@ public:
 	Renderer() {}
 	virtual ~Renderer() {}
 
+	/// Creates a new vertex buffer optimized for rendering static vertex data.
+	/// @vertices is the array containig @count vertex data elements of the given @format.
+	virtual VertexBufferId	create_vertex_buffer(const void* vertices, size_t count, VertexFormat format) = 0;
+
+	/// Creates a new vertex buffer optimized for rendering dynamic vertex data.
+	/// @vertices is the array containig @count vertex data elements of the given @format.
+	virtual VertexBufferId	create_dynamic_vertex_buffer(const void* vertices, size_t count, VertexFormat format) = 0;
+
+	/// Updates the data associated with the given vertex buffer @id.
+	/// @vertices is the array containig @count vertex data elements of the format
+	/// specified at the creation of the buffer.
+	/// @note
+	/// @count and @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, const void* vertices, size_t count, size_t offset) = 0;
+
+	/// Destroys the @id vertex buffer.
+	virtual void			destroy_vertex_buffer(VertexBufferId id) = 0;
+
+	/// Creates a new index buffer optimized for rendering static index buffers.
+	/// @indices is the array containing @count index data elements.
+	virtual IndexBufferId	create_index_buffer(const void* indices, size_t count) = 0;
+
+	/// Destroys the @id index buffer.
+	virtual void			destroy_index_buffer(IndexBufferId id) = 0;
+
+	//virtual RenderBufferId	create_render_buffer(uint32_t width, uint32_t height, PixelFormat format) = 0;
+	//virtual void			destroy_render_buffer(RenderBufferId id) = 0;
+
 	///	Tasks to perform before a frame is rendered.
 	virtual void begin_frame() = 0;
 
@@ -91,12 +123,12 @@ public:
 	/// Sets the global ambient light @color.
 	virtual void set_ambient_light(const Color4& color) = 0;
 
+	//! Sets the texture to use in the specified layer
+	virtual void bind_texture(uint32_t layer, TextureId texture) = 0;
+
 	/// Set whether the given texture @unit is enabled.
 	virtual void set_texturing(uint32_t unit, bool texturing) = 0;
 
-	//! Sets the texture to use in the specified layer
-	virtual void set_texture(uint32_t layer, TextureId texture) = 0;
-
 	/// Sets the texture @mode for the given texture @unit.
 	virtual void set_texture_mode(uint32_t unit, TextureMode mode, const Color4& blendColor) = 0;
 
@@ -175,11 +207,12 @@ public:
 	virtual Mat4 get_matrix(MatrixType type) const = 0;
 	virtual void set_matrix(MatrixType type, const Mat4& matrix) = 0;
 
-	virtual void draw_vertex_index_buffer(const VertexBuffer* vertices, const IndexBuffer* indices) = 0;
-	virtual void draw_point_buffer(const VertexBuffer* buffer) = 0;
+	virtual void bind_vertex_buffer(VertexBufferId vb) const = 0;
+	virtual void bind_render_buffer(RenderBufferId id) const = 0;
+
+	virtual void draw_triangles(IndexBufferId id) const = 0;
 
 	virtual void draw_lines(const float* vertices, const float* colors, uint32_t count) = 0;
-	virtual void draw_triangles(const float* vertices, const float* normals, const float* uvs, const uint16_t* indices, uint32_t count) = 0;
 
 	virtual TextureId	load_texture(TextureResource* texture) = 0;
 	virtual void		unload_texture(TextureResource* texture) = 0;

+ 3 - 6
src/renderers/Texture.h

@@ -30,6 +30,9 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+// Max number of textures a renderer can hold.
+const uint32_t MAX_TEXTURES = 4096;
+
 enum TextureMode
 {
 	TM_MODULATE	= 0,	// Multiplies texel color by the geometry color after lighting
@@ -61,10 +64,4 @@ enum TextureWrap
 	TW_COUNT
 };
 
-struct TextureId
-{
-	uint16_t	index;
-	uint16_t	id;
-};
-
 } // namespace crown

+ 4 - 32
src/renderers/VertexBuffer.h

@@ -30,6 +30,9 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+// Max number of vertex buffers a renderer can hold.
+const uint32_t MAX_VERTEX_BUFFERS = 4096;
+
 enum VertexBufferMode
 {
 	VBM_VERTEX_ONLY		= 0,
@@ -38,36 +41,5 @@ enum VertexBufferMode
 	VBM_COLOR_COORDS	= 4
 };
 
-/**
-	Represents a vertex buffer to stream vertexes to the GPU.
-*/
-class VertexBuffer
-{
-
-public:
-
-						VertexBuffer() : mMode(VBM_VERTEX_ONLY) {}
-	virtual				~VertexBuffer() { }
-
-	inline bool			HasTextureCoords() const { return (mMode & VBM_TEXTURE_COORDS) != 0; }
-	inline bool			HasNormalCoords() const { return (mMode & VBM_NORMAL_COORDS) != 0; }
-	inline bool			HasColorCoords() const { return (mMode & VBM_COLOR_COORDS) != 0; }
-
-						//! Set the vertex data, the order of coordinates is Vertex, [Normals], [Texture], [Color]
-	virtual void		SetVertexData(VertexBufferMode mode, const void* vertexData, uint32_t vertexCount) = 0;
-						//! Replaces a subset of the vertex data, the order of coordinates is Vertex, [Normals], [Texture], [Color]
-	virtual void		SetVertexSubData(const void* vertexData, uint32_t vertexOffset, uint32_t vertexCount) = 0;
-
-	virtual uint32_t		GetSize() const = 0;			//!< Returns the size of the buffer
-	virtual uint32_t		GetVertexCount() const = 0;		//!< Returns the number of vertices in the buffer
-
-	virtual void		Bind() const = 0;
-	virtual void		Unbind() const = 0;
-
-protected:
-	
-	VertexBufferMode	mMode;
-};
-
-}
+} // namespace crown
 

+ 0 - 4
src/renderers/gl/CMakeLists.txt

@@ -3,19 +3,15 @@ cmake_minimum_required(VERSION 2.8)
 project(crown-gl)
 
 set (GL_SRC
-	GLIndexBuffer.cpp
 	GLOcclusionQuery.cpp
 	GLRenderer.cpp
 	GLUtils.cpp
-	GLVertexBuffer.cpp
 )
 
 set (GL_HEADERS
-	GLIndexBuffer.h
 	GLOcclusionQuery.h
 	GLRenderer.h
 	GLUtils.h
-	GLVertexBuffer.h
 )
 
 link_libraries(GL GLEW)

+ 0 - 67
src/renderers/gl/GLIndexBuffer.cpp

@@ -1,67 +0,0 @@
-/*
-Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "GLIndexBuffer.h"
-#include <GL/glew.h>
-#include "Types.h"
-
-namespace crown
-{
-
-GLIndexBuffer::GLIndexBuffer()
-{
-	glGenBuffers(1, &mBufferID);
-}
-
-GLIndexBuffer::~GLIndexBuffer()
-{
-	glDeleteBuffers(1, &mBufferID);
-}
-
-void GLIndexBuffer::SetIndexData(const uint16_t* indexData, uint32_t indexCount)
-{
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferID);
-	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(uint16_t), indexData, GL_DYNAMIC_DRAW);
-	mCount = indexCount;
-}
-
-void GLIndexBuffer::SetIndexSubData(const uint16_t* indexData, uint32_t indexOffset, uint32_t indexCount)
-{
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferID);
-	glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, indexOffset * sizeof(uint16_t), indexCount * sizeof(uint16_t), indexData);
-}
-
-void GLIndexBuffer::Bind() const
-{
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferID);
-}
-
-void GLIndexBuffer::Unbind() const
-{
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-}
-
-}
-

+ 0 - 58
src/renderers/gl/GLIndexBuffer.h

@@ -1,58 +0,0 @@
-/*
-Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#pragma once
-
-#include "Types.h"
-#include "IndexBuffer.h"
-#include <GL/glew.h>
-
-namespace crown
-{
-
-class GLIndexBuffer: public IndexBuffer
-{
-
-public:
-
-				GLIndexBuffer();
-				~GLIndexBuffer();
-
-	void		SetIndexData(const uint16_t* indexData, uint32_t indexCount);
-	void		SetIndexSubData(const uint16_t* indexData, uint32_t indexOffset, uint32_t indexCount);
-
-	uint32_t	GetIndexCount() const { return mCount; }
-
-	void		Bind() const;
-	void		Unbind() const;
-
-private:
-	
-	GLuint			mBufferID;
-	uint32_t		mCount;
-};
-
-}
-

+ 236 - 90
src/renderers/gl/GLRenderer.cpp

@@ -28,16 +28,15 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include <GL/glew.h>
 #include <cassert>
 #include <algorithm>
+
 #include "Types.h"
-#include "GLIndexBuffer.h"
 #include "GLOcclusionQuery.h"
 #include "GLRenderer.h"
 #include "GLUtils.h"
-#include "GLVertexBuffer.h"
 #include "Log.h"
 #include "Material.h"
-#include "Allocator.h"
 #include "TextureResource.h"
+#include "Vec3.h"
 
 #if defined(WINDOWS)
 	//Define the missing constants in vs' gl.h
@@ -61,8 +60,12 @@ GLRenderer::GLRenderer() :
 	m_max_vertex_vertices(0),
 	m_max_anisotropy(0.0f),
 
-	m_texture_count(0),
-	m_active_texture_unit(0)
+	m_textures_id_table(m_allocator, MAX_TEXTURES),
+	m_active_texture_unit(0),
+
+	m_vertex_buffers_id_table(m_allocator, MAX_VERTEX_BUFFERS),
+	m_index_buffers_id_table(m_allocator, MAX_INDEX_BUFFERS),
+	m_render_buffers_id_table(m_allocator, MAX_RENDER_BUFFERS)
 {
 	m_min_max_point_size[0] = 0.0f;
 	m_min_max_point_size[1] = 0.0f;
@@ -185,6 +188,134 @@ GLRenderer::~GLRenderer()
 {
 }
 
+//-----------------------------------------------------------------------------
+VertexBufferId GLRenderer::create_vertex_buffer(const void* vertices, size_t count, VertexFormat format)
+{
+	const VertexBufferId id = m_vertex_buffers_id_table.create();
+
+	GLVertexBuffer& buffer = m_vertex_buffers[id.index];
+
+	glGenBuffers(1, &buffer.gl_object);
+
+	glBindBuffer(GL_ARRAY_BUFFER, buffer.gl_object);
+	glBufferData(GL_ARRAY_BUFFER, count * Vertex::bytes_per_vertex(format), vertices, GL_STATIC_DRAW);
+
+	buffer.count = count;
+	buffer.format = format;
+
+	return id;
+}
+
+//-----------------------------------------------------------------------------
+VertexBufferId GLRenderer::create_dynamic_vertex_buffer(const void* vertices, size_t count, VertexFormat format)
+{
+	const VertexBufferId id = m_vertex_buffers_id_table.create();
+
+	GLVertexBuffer& buffer = m_vertex_buffers[id.index];
+
+	glGenBuffers(1, &buffer.gl_object);
+
+	glBindBuffer(GL_ARRAY_BUFFER, buffer.gl_object);
+	glBufferData(GL_ARRAY_BUFFER, count * Vertex::bytes_per_vertex(format), vertices, GL_STREAM_DRAW);
+
+	buffer.count = count;
+	buffer.format = format;
+
+	return id;
+}
+
+//-----------------------------------------------------------------------------
+void GLRenderer::update_vertex_buffer(VertexBufferId id, const void* vertices, size_t count, size_t offset)
+{
+	assert(m_vertex_buffers_id_table.has(id));
+
+	GLVertexBuffer& buffer = m_vertex_buffers[id.index];
+
+	glBindBuffer(GL_ARRAY_BUFFER, buffer.gl_object);
+	glBufferSubData(GL_ARRAY_BUFFER, offset * Vertex::bytes_per_vertex(buffer.format),
+					count * Vertex::bytes_per_vertex(buffer.format), vertices);
+}
+
+//-----------------------------------------------------------------------------
+void GLRenderer::destroy_vertex_buffer(VertexBufferId id)
+{
+	assert(m_vertex_buffers_id_table.has(id));
+
+	GLVertexBuffer& buffer = m_vertex_buffers[id.index];
+
+	glDeleteBuffers(1, &buffer.gl_object);
+
+	m_vertex_buffers_id_table.destroy(id);
+}
+
+//-----------------------------------------------------------------------------
+IndexBufferId GLRenderer::create_index_buffer(const void* indices, size_t count)
+{
+	const IndexBufferId id = m_index_buffers_id_table.create();
+
+	GLIndexBuffer& buffer = m_index_buffers[id.index];
+
+	glGenBuffers(1, &buffer.gl_object);
+
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.gl_object);
+	glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(GLushort), indices, GL_STATIC_DRAW);
+
+	buffer.index_count = count;
+
+	return id;
+}
+
+//-----------------------------------------------------------------------------
+void GLRenderer::destroy_index_buffer(IndexBufferId id)
+{
+	assert(m_index_buffers_id_table.has(id));
+
+	GLIndexBuffer& buffer = m_index_buffers[id.index];
+
+	glDeleteBuffers(1, &buffer.gl_object);
+
+	m_index_buffers_id_table.destroy(id);
+}
+
+//-----------------------------------------------------------------------------
+// RenderBufferId GLRenderer::create_render_buffer(uint32_t width, uint32_t height, PixelFormat format)
+// {
+// 	const RenderBufferId id = m_render_buffers_id_table.create();
+
+// 	GLRenderBuffer& buffer = m_render_buffers[id.index];
+
+// 	if (GLEW_EXT_framebuffer_object)
+// 	{
+// 		glGenFramebuffersEXT(1, &buffer.gl_frame_buffer);
+// 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, buffer.gl_frame_buffer);
+
+// 		glGenRenderbuffersEXT(1, &buffer.gl_render_buffer);
+// 		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, buffer.gl_render_buffer);
+
+// 		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, width, height);
+
+// 		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, buffer.gl_render_buffer);
+
+// 		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+// 	}
+
+// 	return id;
+// }
+
+//-----------------------------------------------------------------------------
+// void GLRenderer::destroy_render_buffer(RenderBufferId id)
+// {
+// 	GLRenderBuffer& buffer = m_render_buffers[id.index];
+
+// 	if (GLEW_EXT_framebuffer_object)
+// 	{
+// 		glDeleteFramebuffersEXT(1, &buffer.gl_frame_buffer);
+// 		glDeleteRenderbuffersEXT(1, &buffer.gl_render_buffer);
+// 	}
+
+// 	m_render_buffers_id_table.destroy(id);
+// }
+
 //-----------------------------------------------------------------------------
 void GLRenderer::set_clear_color(const Color4& color)
 {
@@ -221,6 +352,23 @@ void GLRenderer::set_lighting(bool lighting)
 	}
 }
 
+//-----------------------------------------------------------------------------
+void GLRenderer::bind_texture(uint32_t unit, TextureId texture)
+{
+	assert(m_textures_id_table.has(texture));
+
+	if (!activate_texture_unit(unit))
+	{
+		return;
+	}
+
+	m_texture_unit_target[unit] = GL_TEXTURE_2D;
+	m_texture_unit[unit] = m_textures[texture.index].gl_object;
+
+	glEnable(m_texture_unit_target[unit]);
+	glBindTexture(m_texture_unit_target[unit], m_texture_unit[unit]);
+}
+
 //-----------------------------------------------------------------------------
 void GLRenderer::set_texturing(uint32_t unit, bool texturing)
 {
@@ -237,21 +385,6 @@ void GLRenderer::set_texturing(uint32_t unit, bool texturing)
 	}
 }
 
-//-----------------------------------------------------------------------------
-void GLRenderer::set_texture(uint32_t unit, TextureId texture)
-{
-	if (!activate_texture_unit(unit))
-	{
-		return;
-	}
-
-	m_texture_unit_target[unit] = GL_TEXTURE_2D;
-	m_texture_unit[unit] = m_textures[texture.index].texture_object;
-
-	glEnable(m_texture_unit_target[unit]);
-	glBindTexture(m_texture_unit_target[unit], m_texture_unit[unit]);
-}
-
 //-----------------------------------------------------------------------------
 void GLRenderer::set_texture_mode(uint32_t unit, TextureMode mode, const Color4& blendColor)
 {
@@ -613,44 +746,82 @@ void GLRenderer::set_matrix(MatrixType type, const Mat4& matrix)
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::draw_vertex_index_buffer(const VertexBuffer* vertices, const IndexBuffer* indices)
+void GLRenderer::bind_vertex_buffer(VertexBufferId vb) const
 {
-	assert(vertices != NULL);
-	assert(indices != NULL);
+	assert(m_vertex_buffers_id_table.has(vb));
 
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_NORMAL_ARRAY);
-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-	glEnableClientState(GL_COLOR_ARRAY);
+	const GLVertexBuffer& vertex_buffer = m_vertex_buffers[vb.index];
 
-	vertices->Bind();
-	indices->Bind();
+	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer.gl_object);
 
-	glDrawElements(GL_TRIANGLES, indices->GetIndexCount(), GL_UNSIGNED_SHORT, 0);
-
-	glDisableClientState(GL_COLOR_ARRAY);
-	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-	glDisableClientState(GL_NORMAL_ARRAY);
-	glDisableClientState(GL_VERTEX_ARRAY);
+	switch (vertex_buffer.format)
+	{
+		case VF_XY_FLOAT_32:
+		{
+			glEnableClientState(GL_VERTEX_ARRAY);
+			glVertexPointer(2, GL_FLOAT, 0, 0);
+			break;
+		}
+		case VF_XYZ_FLOAT_32:
+		{
+			glEnableClientState(GL_VERTEX_ARRAY);
+			glVertexPointer(3, GL_FLOAT, 0, 0);
+			break;
+		}
+		case VF_UV_FLOAT_32:
+		{
+			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+			glTexCoordPointer(2, GL_FLOAT, 0, 0);
+			break;
+		}
+		case VF_UVT_FLOAT_32:
+		{
+			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+			glTexCoordPointer(3, GL_FLOAT, 0, 0);
+			break;
+		}
+		case VF_XYZ_NORMAL_FLOAT_32:
+		{
+			glEnableClientState(GL_NORMAL_ARRAY);
+			glNormalPointer(GL_FLOAT, 0, 0);
+			break;
+		}
+		case VF_XYZ_UV_XYZ_NORMAL_FLOAT_32:
+		{
+			glEnableClientState(GL_VERTEX_ARRAY);
+			glEnableClientState(GL_NORMAL_ARRAY);
+			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+			glVertexPointer(3, GL_FLOAT, 0, 0);
+			glTexCoordPointer(2, GL_FLOAT, 0, 0);
+			glNormalPointer(GL_FLOAT, 0, 0);
+			break;
+		}
+		default:
+		{
+			assert(0);
+			break;
+		}
+	}
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::draw_point_buffer(const VertexBuffer* buffer)
+void GLRenderer::draw_triangles(IndexBufferId id) const
 {
-	if (buffer == NULL)
-		return;
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_NORMAL_ARRAY);
-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-	glEnableClientState(GL_COLOR_ARRAY);
+	assert(m_index_buffers_id_table.has(id));
 
-	buffer->Bind();
-	glDrawArrays(GL_POINTS, 0, buffer->GetVertexCount());
+	const GLIndexBuffer& index_buffer = m_index_buffers[id.index];
 
-	glDisableClientState(GL_COLOR_ARRAY);
-	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-	glDisableClientState(GL_NORMAL_ARRAY);
-	glDisableClientState(GL_VERTEX_ARRAY);
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer.gl_object);
+
+	glDrawElements(GL_TRIANGLES, index_buffer.index_count, GL_UNSIGNED_SHORT, 0);
+}
+
+//-----------------------------------------------------------------------------
+void GLRenderer::bind_render_buffer(RenderBufferId id) const
+{
+	assert(m_render_buffers_id_table.has(id));
+
+	const GLRenderBuffer& render_buffer = m_render_buffers[id.index];
 }
 
 //-----------------------------------------------------------------------------
@@ -739,47 +910,22 @@ void GLRenderer::draw_lines(const float* vertices, const float* colors, uint32_t
 }
 
 //-----------------------------------------------------------------------------
-void GLRenderer::draw_triangles(const float* vertices, const float* normals, const float* uvs, const uint16_t* indices, uint32_t count)
+TextureId GLRenderer::load_texture(TextureResource* texture)
 {
-	glBindBuffer(GL_ARRAY_BUFFER, 0);
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+	const TextureId id = m_textures_id_table.create();
 
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_NORMAL_ARRAY);
-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-	glVertexPointer(3, GL_FLOAT, 0, vertices);
-	glNormalPointer(GL_FLOAT, 0, normals);
-	glTexCoordPointer(2, GL_FLOAT, 0, uvs);
-
-	glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices);
+	GLTexture& gl_texture = m_textures[id.index];
 
-	glDisableClientState(GL_VERTEX_ARRAY);
-	glDisableClientState(GL_NORMAL_ARRAY);
-	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-}
+	glGenTextures(1, &gl_texture.gl_object);
 
-//-----------------------------------------------------------------------------
-TextureId GLRenderer::load_texture(TextureResource* texture)
-{
-	// If texture not found, create a new one
-	GLuint gl_texture_object;
+	glBindTexture(GL_TEXTURE_2D, gl_texture.gl_object);
 
-	glGenTextures(1, &gl_texture_object);
-	glBindTexture(GL_TEXTURE_2D, gl_texture_object);
 	glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
 
 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->width(), texture->height(), 0,
 				 GL::pixel_format(texture->format()), GL_UNSIGNED_BYTE, texture->data());
 
-	TextureId id;
-	id.index = m_texture_count;
-	id.id = 0;
-
-	m_textures[id.index].texture_object = gl_texture_object;
-	m_textures[id.index].texture_resource = texture;
-	m_textures[id.index].id = id;
-
-	m_texture_count++;
+	gl_texture.texture_resource = texture;
 
 	return id;
 }
@@ -794,19 +940,19 @@ void GLRenderer::unload_texture(TextureResource* texture)
 //-----------------------------------------------------------------------------
 TextureId GLRenderer::reload_texture(TextureResource* old_texture, TextureResource* new_texture)
 {
-	for (uint32_t i = 0; i < m_texture_count; i++)
-	{
-		if (m_textures[i].texture_resource == old_texture)
-		{
-			// Reload texture
-			glBindTexture(GL_TEXTURE_2D, m_textures[i].texture_object);
+	// for (uint32_t i = 0; i < m_texture_count; i++)
+	// {
+	// 	if (m_textures[i].texture_resource == old_texture)
+	// 	{
+	// 		// Reload texture
+	// 		glBindTexture(GL_TEXTURE_2D, m_textures[i].gl_object);
 
-			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, new_texture->width(), new_texture->height(),
-				GL::pixel_format(new_texture->format()), GL_UNSIGNED_BYTE, new_texture->data());
+	// 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, new_texture->width(), new_texture->height(),
+	// 			GL::pixel_format(new_texture->format()), GL_UNSIGNED_BYTE, new_texture->data());
 
-			m_textures[i].texture_resource = new_texture;
-		}
-	}
+	// 		m_textures[i].texture_resource = new_texture;
+	// 	}
+	// }
 }
 
 //-----------------------------------------------------------------------------

+ 64 - 14
src/renderers/gl/GLRenderer.h

@@ -26,25 +26,50 @@ OTHER DEALINGS IN THE SOFTWARE.
 #pragma once
 
 #include <GL/glew.h>
-#include "Renderer.h"
-#include "Resource.h"
 
-#define MAX_TEXTURES 1024
-#define MAX_TEXTURE_UNITS 8
-#define MAX_MODEL_MATRIX_STACK_DEPTH 100
+#include "Renderer.h"
+#include "Texture.h"
+#include "VertexBuffer.h"
+#include "IndexBuffer.h"
+#include "RenderBuffer.h"
+#include "IdTable.h"
+#include "MallocAllocator.h"
 
 namespace crown
 {
 
+const uint32_t MAX_TEXTURE_UNITS = 8;
+
 class TextureResource;
 
-/// OpenGL texture
+//-----------------------------------------------------------------------------
 struct GLTexture
 {
-	TextureId			id;
+	GLuint				gl_object;
+
 	TextureResource*	texture_resource;
+};
+
+//-----------------------------------------------------------------------------
+struct GLVertexBuffer
+{
+	GLuint				gl_object;
+	size_t				count;
+	VertexFormat		format;
+};
+
+//-----------------------------------------------------------------------------
+struct GLIndexBuffer
+{
+	GLuint				gl_object;
+	uint32_t			index_count;
+};
 
-	GLuint				texture_object;
+//-----------------------------------------------------------------------------
+struct GLRenderBuffer
+{
+	GLuint				gl_frame_buffer;
+	GLuint				gl_render_buffer;
 };
 
 /// OpenGL renderer
@@ -55,6 +80,17 @@ public:
 						GLRenderer();
 						~GLRenderer();
 
+	VertexBufferId		create_vertex_buffer(const void* vertices, size_t count, VertexFormat format);
+	VertexBufferId		create_dynamic_vertex_buffer(const void* vertices, size_t count, VertexFormat format);
+	void				update_vertex_buffer(VertexBufferId id, const void* vertices, size_t count, size_t offset);
+	void				destroy_vertex_buffer(VertexBufferId id);
+
+	IndexBufferId		create_index_buffer(const void* indices, size_t count);
+	void				destroy_index_buffer(IndexBufferId id);
+
+	// RenderBufferId	create_render_buffer(uint32_t width, uint32_t height, PixelFormat format);
+	// void				destroy_render_buffer(RenderBufferId id);
+
 	void				begin_frame();
 	void				end_frame();
 
@@ -64,8 +100,8 @@ public:
 	void				set_lighting(bool lighting);
 	void				set_ambient_light(const Color4& color);
 
+	void				bind_texture(uint32_t unit, TextureId texture);
 	void				set_texturing(uint32_t unit, bool texturing);
-	void				set_texture(uint32_t unit, TextureId texture);
 	void				set_texture_mode(uint32_t unit, TextureMode mode, const Color4& blendColor);
 	void				set_texture_wrap(uint32_t unit, TextureWrap wrap);
 	void				set_texture_filter(uint32_t unit, TextureFilter filter);
@@ -113,11 +149,12 @@ public:
 	Mat4				get_matrix(MatrixType type) const;
 	void				set_matrix(MatrixType type, const Mat4& matrix);
 
-	void				draw_vertex_index_buffer(const VertexBuffer* vertices, const IndexBuffer* indices);
-	void				draw_point_buffer(const VertexBuffer* buffer);
+	void				bind_vertex_buffer(VertexBufferId vb) const;
+	void				bind_render_buffer(RenderBufferId id) const;
+
+	void				draw_triangles(IndexBufferId id) const;
 
 	void				draw_lines(const float* vertices, const float* colors, uint32_t count);
-	void				draw_triangles(const float* vertices, const float* normals, const float* uvs, const uint16_t* indices, uint32_t count);
 
 	TextureId			load_texture(TextureResource* texture);
 	void				unload_texture(TextureResource* texture);
@@ -133,6 +170,8 @@ private:
 
 private:
 
+	MallocAllocator		m_allocator;
+
 	// Matrices
 	Mat4				m_matrix[MT_COUNT];
 
@@ -152,14 +191,25 @@ private:
 	int32_t				m_scissor[4];
 
 	// Texture management
-	uint32_t			m_texture_count;
+	IdTable 			m_textures_id_table;
 	GLTexture			m_textures[MAX_TEXTURES];
 
 	uint32_t			m_active_texture_unit;
 	GLuint				m_texture_unit[MAX_TEXTURE_UNITS];
 	GLenum				m_texture_unit_target[MAX_TEXTURE_UNITS];
 
-	friend class TextureResource;
+	// Vertex/Index buffer management
+	IdTable				m_vertex_buffers_id_table;
+	GLVertexBuffer		m_vertex_buffers[MAX_VERTEX_BUFFERS];
+
+	IdTable				m_index_buffers_id_table;
+	GLIndexBuffer		m_index_buffers[MAX_INDEX_BUFFERS];
+
+	// Render buffer management
+	IdTable				m_render_buffers_id_table;
+	GLRenderBuffer		m_render_buffers[MAX_RENDER_BUFFERS];
+
+	friend class		TextureResource;
 };
 
 } // namespace crown

+ 2 - 10
src/renderers/gl/GLUtils.h

@@ -29,22 +29,14 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include <cassert>
 #include "Texture.h"
 #include "Material.h"
-#include "Pixel.h"
-
-#include "Config.h"
-#if defined(WINDOWS)
-	//Define the missing constants in vs' gl.h
-	#define GL_TEXTURE_3D					0x806F
-	#define GL_TEXTURE_CUBE_MAP				0x8513
-#endif
+#include "PixelFormat.h"
 
 namespace crown
 {
 
-/// OpenGL Utilities for converting from wrapped names to GL names and vice-versa.
+/// OpenGL utilities for converting from wrapped names to GL names and vice-versa.
 class GL
 {
-
 public:
 
 	static GLenum			compare_function(CompareFunction function);

+ 0 - 132
src/renderers/gl/GLVertexBuffer.cpp

@@ -1,132 +0,0 @@
-/*
-Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "GLVertexBuffer.h"
-#include <GL/glew.h>
-
-namespace crown
-{
-
-//!Constructor
-GLVertexBuffer::GLVertexBuffer():
-	mSize(0), mVertexCount(0)
-{
-	glGenBuffers(1, &mBufferID);
-}
-
-//!Destructor
-GLVertexBuffer::~GLVertexBuffer()
-{
-	glDeleteBuffers(1, &mBufferID);
-}
-
-void GLVertexBuffer::SetVertexData(VertexBufferMode mode, const void* vertexData, uint32_t vertexCount)
-{
-	mMode = mode;
-
-	uint32_t vertexSize = sizeof(float) * 3;
-	if (HasNormalCoords())
-		vertexSize += sizeof(float) * 3;
-	if (HasTextureCoords())
-		vertexSize += sizeof(float) * 2;
-	if (HasColorCoords())
-		vertexSize += sizeof(float) * 4;
-
-	mSize = vertexCount * vertexSize;
-	mVertexCount = vertexCount;
-
-	glBindBuffer(GL_ARRAY_BUFFER, mBufferID);
-	glBufferData(GL_ARRAY_BUFFER, mSize, vertexData, GL_DYNAMIC_DRAW);
-}
-
-void GLVertexBuffer::SetVertexSubData(const void* vertexData, uint32_t vertexOffset, uint32_t vertexCount)
-{
-	uint32_t vertexSize = sizeof(float) * 3;
-	if (HasNormalCoords())
-		vertexSize += sizeof(float) * 3;
-	if (HasTextureCoords())
-		vertexSize += sizeof(float) * 2;
-	if (HasColorCoords())
-		vertexSize += sizeof(float) * 4;
-
-	if (vertexSize * vertexCount + vertexOffset > mSize)
-		return;
-
-	glBindBuffer(GL_ARRAY_BUFFER, mBufferID);
-	glBufferSubData(GL_ARRAY_BUFFER, vertexOffset * vertexSize, vertexCount * vertexSize, vertexData);
-}
-
-uint32_t GLVertexBuffer::GetSize() const
-{
-	return mSize;
-}
-
-uint32_t GLVertexBuffer::GetVertexCount() const
-{
-	return mVertexCount;
-}
-
-void GLVertexBuffer::Bind() const
-{
-	uint32_t vertexSize = sizeof(float) * 3;
-	uint32_t offset = vertexSize;
-	if (HasNormalCoords())
-		vertexSize += sizeof(float) * 3;
-	if (HasTextureCoords())
-		vertexSize += sizeof(float) * 2;
-	if (HasColorCoords())
-		vertexSize += sizeof(float) * 4;
-
-	glBindBuffer(GL_ARRAY_BUFFER, mBufferID);
-
-	glVertexPointer(3, GL_FLOAT, vertexSize, (void*) 0);
-
-	if (HasNormalCoords())
-	{
-		glNormalPointer(GL_FLOAT, vertexSize, (void*) offset);
-		offset += sizeof(float) * 3;
-	}
-
-	if (HasTextureCoords())
-	{
-		glClientActiveTexture(GL_TEXTURE0);
-		glTexCoordPointer(2, GL_FLOAT, vertexSize, (void*) offset);
-		offset += sizeof(float) * 2;
-	}
-
-	if (HasColorCoords())
-	{
-		glColorPointer(4, GL_FLOAT, vertexSize, (void*) offset);
-		offset += sizeof(float) * 4;
-	}
-}
-
-void GLVertexBuffer::Unbind() const
-{
-	glBindBuffer(GL_ARRAY_BUFFER, 0);
-}
-
-}
-

+ 0 - 59
src/renderers/gl/GLVertexBuffer.h

@@ -1,59 +0,0 @@
-/*
-Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#pragma once
-
-#include "VertexBuffer.h"
-#include <GL/glew.h>
-
-namespace crown
-{
-
-class GLVertexBuffer: public VertexBuffer
-{
-
-public:
-
-				GLVertexBuffer();
-				~GLVertexBuffer();
-
-	void		SetVertexData(VertexBufferMode mode, const void* vertexData, uint32_t vertexCount);
-	void		SetVertexSubData(const void* vertexData, uint32_t vertexOffset, uint32_t vertexCount);
-
-	uint32_t		GetSize() const;
-	uint32_t		GetVertexCount() const;
-
-	void		Bind() const;
-	void		Unbind() const;
-
-private:
-	
-	GLuint			mBufferID;
-	uint32_t		mSize;
-	uint32_t		mVertexCount;
-};
-
-}
-