Browse Source

Improve texturing support

Daniele Bartolini 12 years ago
parent
commit
a8b8285af8
3 changed files with 173 additions and 96 deletions
  1. 97 27
      engine/renderers/VertexFormat.h
  2. 31 45
      engine/renderers/gl/GLRenderer.cpp
  3. 45 24
      engine/renderers/gl/GLRenderer.h

+ 97 - 27
engine/renderers/VertexFormat.h

@@ -29,18 +29,95 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
-/// Enumerates vertex formats.
+enum ShaderAttrib
+{
+	ATTRIB_POSITION			= 0,
+	ATTRIB_NORMAL			= 1,
+	ATTRIB_COLOR			= 2,
+	ATTRIB_TEX_COORD0		= 3,
+	ATTRIB_TEX_COORD1		= 4,
+	ATTRIB_TEX_COORD2		= 5,
+	ATTRIB_TEX_COORD3		= 6,
+	ATTRIB_COUNT
+};
+
 enum VertexFormat
 {
-	VF_XY_FLOAT_32					= 0,	///< XY coordinates, 32-bit floating point each
-	VF_XYZ_FLOAT_32					= 1,	///< XYZ coordinates, 32-bit floating point each
+	VERTEX_P2 = 0,
+	VERTEX_P2_N3,
+	VERTEX_P2_C4,
+	VERTEX_P2_T2,
+	VERTEX_P2_N3_C4,
+	VERTEX_P2_N3_C4_T2,
 
-	VF_UV_FLOAT_32					= 2,	///< UV coordinates, 32-bit floating point each
-	VF_UVT_FLOAT_32					= 3,	///< UVT coordinates, 32-bit floating point each
+	VERTEX_P3,
+	VERTEX_P3_N3,
+	VERTEX_P3_C4,
+	VERTEX_P3_T2,
+	VERTEX_P3_N3_C4,
+	VERTEX_P3_N3_C4_T2,
+
+	VERTEX_COUNT
+};
+
+struct VertexFormatInfo
+{
+	bool has_attrib(ShaderAttrib attrib) const
+	{
+		return sizes[attrib] != 0;
+	}
 
-	VF_XYZ_NORMAL_FLOAT_32			= 4, 	///< XYZ normal coordinates, 32-bit floating point each
+	/// Returns the number of components per @a attrib
+	size_t num_components(ShaderAttrib attrib) const
+	{
+		return (size_t) sizes[attrib];
+	}
+
+	/// Returns the byte offset between consecutive vertex @a attrib
+	size_t attrib_stride(ShaderAttrib /*attrib*/) const
+	{
+		size_t stride = 0;
+		for (uint8_t i = 0; i < ATTRIB_COUNT; i++)
+		{
+			stride += sizes[i];
+		}
+
+		return stride * sizeof(float);
+	}
 
-	VF_XYZ_UV_XYZ_NORMAL_FLOAT_32	= 5		///< XYZ coordinates, UV coordinates, XYZ normal coordinates, 32-bit floating point each
+	/// Returns the byte offset of the first @a attrib in the format
+	size_t attrib_offset(ShaderAttrib attrib) const
+	{
+		size_t offset = 0;
+		for (uint8_t i = 0; i < attrib; i++)
+		{
+			offset += sizes[i];
+		}
+
+		return offset * sizeof(float);
+	}
+
+public:
+
+	uint8_t sizes[ATTRIB_COUNT];
+};
+
+// VertexFormat to VertexFormatInfo
+const VertexFormatInfo VERTEX_FORMAT_INFO[VERTEX_COUNT] =
+{
+	{ 2, 0, 0, 0, 0, 0, 0 },
+	{ 2, 3, 0, 0, 0, 0, 0 },
+	{ 2, 0, 4, 0, 0, 0, 0 },
+	{ 2, 0, 0, 2, 0, 0, 0 },
+	{ 2, 3, 4, 0, 0, 0, 0 },
+	{ 2, 3, 4, 2, 0, 0, 0 },
+
+	{ 3, 0, 0, 0, 0, 0, 0 },
+	{ 3, 3, 0, 0, 0, 0, 0 },
+	{ 3, 0, 4, 0, 0, 0, 0 },
+	{ 3, 0, 0, 2, 0, 0, 0 },
+	{ 3, 3, 4, 0, 0, 0, 0 },
+	{ 3, 3, 4, 2, 0, 0, 0 }
 };
 
 class Vertex
@@ -50,28 +127,16 @@ public:
 	/// Returns the bytes occupied by @a format
 	static size_t bytes_per_vertex(VertexFormat format)
 	{
-		switch (format)
+		const VertexFormatInfo& info = VERTEX_FORMAT_INFO[format];
+		
+		size_t size = 0;
+		for (uint8_t i = 0; i < ATTRIB_COUNT; i++)
 		{
-			case VF_XY_FLOAT_32:
-			case VF_UV_FLOAT_32:
-			{
-				return 8;
-			}
-			case VF_XYZ_FLOAT_32:
-			case VF_UVT_FLOAT_32:
-			case VF_XYZ_NORMAL_FLOAT_32:
-			{
-				return 12;
-			}
-			case VF_XYZ_UV_XYZ_NORMAL_FLOAT_32:
-			{
-				return 32;
-			}
-			default:
-			{
-				return 0;
-			}
+			size += info.sizes[i];
 		}
+
+		// Components are always float
+		return size * sizeof(float);
 	}
 
 	/// Returns the bits occupied by @a format
@@ -80,6 +145,11 @@ public:
 		return bytes_per_vertex(format) * 8;
 	}
 
+	static const VertexFormatInfo& info(VertexFormat format)
+	{
+		return VERTEX_FORMAT_INFO[format];
+	}
+
 private:
 
 	// Disable construction

+ 31 - 45
engine/renderers/gl/GLRenderer.cpp

@@ -142,8 +142,6 @@ void GLRenderer::init()
 	Log::d("Max Vertex Indices   : %d", m_max_vertex_indices);
 	Log::d("Max Vertex Vertices  : %d", m_max_vertex_vertices);
 
-	GL_CHECK(glDisable(GL_TEXTURE_2D));
-
 	GL_CHECK(glDisable(GL_BLEND));
 	GL_CHECK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 	GL_CHECK(glBlendEquation(GL_FUNC_ADD));
@@ -507,51 +505,10 @@ void GLRenderer::frame()
 		if (vb.id != INVALID_ID)
 		{
 			const VertexBuffer& vertex_buffer = m_vertex_buffers[vb.index];
-
 			glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer.m_id);
 
-			switch (vertex_buffer.m_format)
-			{
-				case VF_XY_FLOAT_32:
-				{
-					GL_CHECK(glEnableVertexAttribArray(ATTRIB_POSITION));
-					GL_CHECK(glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0));
-					break;
-				}
-				case VF_XYZ_FLOAT_32:
-				{
-					GL_CHECK(glEnableVertexAttribArray(ATTRIB_POSITION));
-					GL_CHECK(glVertexAttribPointer(ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, 0, 0));
-					break;
-				}
-				case VF_XYZ_NORMAL_FLOAT_32:
-				{
-					GL_CHECK(glEnableVertexAttribArray(ATTRIB_NORMAL));
-					GL_CHECK(glVertexAttribPointer(ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, 0));
-					break;
-				}
-				// case VF_UV_FLOAT_32:
-				// {
-				// 	GL_CHECK(glEnableVertexAttribArray(SA_COORDS));
-				// 	GL_CHECK(glVertexAttribPointer(SA_COORDS, 2, GL_FLOAT, GL_FALSE, 0, 0));
-				// 	break;
-				// }
-				// case VF_UVT_FLOAT_32:
-				// {
-				// 	GL_CHECK(glEnableVertexAttribArray(SA_COORDS));
-				// 	GL_CHECK(glVertexAttribPointer(SA_COORDS, 3, GL_FLOAT, GL_FALSE, 0, 0));
-				// 	break;
-				// }
-				case VF_XYZ_UV_XYZ_NORMAL_FLOAT_32:
-				{
-					break;
-				}
-				default:
-				{
-					CE_ASSERT(false, "Oops, vertex format unknown!");
-					break;
-				}
-			}
+			const GPUProgram& gpu_program = m_gpu_programs[cur_state.program.index];
+			gpu_program.bind_attributes(vertex_buffer.m_format);
 		}
 		else
 		{
@@ -569,6 +526,35 @@ void GLRenderer::frame()
 		{
 			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());

+ 45 - 24
engine/renderers/gl/GLRenderer.h

@@ -34,6 +34,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Resource.h"
 #include "GLContext.h"
 #include "HeapAllocator.h"
+#include "VertexFormat.h"
 
 namespace crown
 {
@@ -42,20 +43,8 @@ extern const GLenum TEXTURE_MIN_FILTER_TABLE[];
 extern const GLenum TEXTURE_MAG_FILTER_TABLE[];
 extern const GLenum TEXTURE_WRAP_TABLE[];
 
-enum ShaderAttrib
-{
-	ATTRIB_POSITION			= 0,
-	ATTRIB_NORMAL			= 1,
-	ATTRIB_COLOR			= 2,
-	ATTRIB_TEX_COORD0		= 3,
-	ATTRIB_TEX_COORD1		= 4,
-	ATTRIB_TEX_COORD2		= 5,
-	ATTRIB_TEX_COORD3		= 6,
-	ATTRIB_COUNT
-};
-
 // Keep in sync with ShaderAttrib
-const char* const SHADER_ATTRIB_NAMES[] =
+const char* const SHADER_ATTRIB_NAMES[ATTRIB_COUNT] =
 {
 	"a_position",
 	"a_normal",
@@ -300,9 +289,6 @@ struct GPUProgram
 		GL_CHECK(glAttachShader(m_id, vertex.m_id));
 		GL_CHECK(glAttachShader(m_id, pixel.m_id));
 
-		GL_CHECK(glBindAttribLocation(m_id, ATTRIB_POSITION, SHADER_ATTRIB_NAMES[ATTRIB_POSITION]));
-		GL_CHECK(glBindAttribLocation(m_id, ATTRIB_NORMAL, SHADER_ATTRIB_NAMES[ATTRIB_NORMAL]));
-
 		GL_CHECK(glLinkProgram(m_id));
 
 		GLint success;
@@ -337,8 +323,20 @@ struct GPUProgram
 			char attrib_name[1024];
 			GL_CHECK(glGetActiveAttrib(m_id, attrib, max_attrib_length, NULL, &attrib_size, &attrib_type, attrib_name));
 
-			Log::d("Attrib %d: name = '%s' location = '%d'", attrib, attrib_name,
-					glGetAttribLocation(m_id, attrib_name));
+			GLint attrib_location = GL_CHECK(glGetAttribLocation(m_id, attrib_name));
+			Log::d("Attrib %d: name = '%s' location = '%d'", attrib, attrib_name, attrib_location);
+		}
+
+		m_num_active_attribs = 0;
+		for (uint32_t attrib = 0; attrib < ATTRIB_COUNT; attrib++)
+		{
+			GLint loc = GL_CHECK(glGetAttribLocation(m_id, SHADER_ATTRIB_NAMES[attrib]));
+			if (loc != -1)
+			{
+				m_active_attribs[m_num_active_attribs] = (ShaderAttrib) attrib;
+				m_num_active_attribs++;
+				m_attrib_locations[attrib] = loc;
+			}
 		}
 
 		for (GLint uniform = 0; uniform < num_active_uniforms; uniform++)
@@ -347,10 +345,7 @@ struct GPUProgram
 			GLenum uniform_type;
 			char uniform_name[1024];
 			GL_CHECK(glGetActiveUniform(m_id, uniform, max_uniform_length, NULL, &uniform_size, &uniform_type, uniform_name));
-
-			GLint uniform_location = glGetUniformLocation(m_id, uniform_name);
-			Log::d("Uniform %d: name = '%s' location = '%d'", uniform, uniform_name,
-					uniform_location);
+			GLint uniform_location = GL_CHECK(glGetUniformLocation(m_id, uniform_name));
 
 			ShaderUniform stock_uniform = name_to_stock_uniform(uniform_name);
 			if (stock_uniform != UNIFORM_COUNT)
@@ -358,9 +353,10 @@ struct GPUProgram
 				m_stock_uniforms[m_num_stock_uniforms] = stock_uniform;
 				m_stock_uniform_locations[m_num_stock_uniforms] = uniform_location;
 				m_num_stock_uniforms++;
-
-				Log::d("Found stock uniform: %s", uniform_name);
 			}
+
+			Log::d("Uniform %d: name = '%s' location = '%d' stock = %s", uniform, uniform_name, uniform_location,
+						(stock_uniform != UNIFORM_COUNT) ? "yes" : "no");
 		}
 	}
 
@@ -371,9 +367,34 @@ struct GPUProgram
 		GL_CHECK(glDeleteProgram(m_id));
 	}
 
+	//-----------------------------------------------------------------------------
+	void bind_attributes(VertexFormat format) const
+	{
+		// Bind all active attributes
+		for (uint8_t i = 0; i < m_num_active_attribs; i++)
+		{
+			ShaderAttrib attrib = m_active_attribs[i];
+			GLint loc = m_attrib_locations[attrib];
+
+			const VertexFormatInfo& info = Vertex::info(format);
+
+			if (loc != -1 && info.has_attrib(attrib))
+			{
+				GL_CHECK(glEnableVertexAttribArray(loc));
+				GL_CHECK(glVertexAttribPointer(loc, info.num_components(attrib), GL_FLOAT, GL_FALSE, info.attrib_stride(attrib),
+										(GLvoid*)(uintptr_t) info.attrib_offset(attrib)));
+			}
+		}
+	}
+
 public:
 
 	GLuint				m_id;
+
+	uint8_t				m_num_active_attribs;
+	ShaderAttrib		m_active_attribs[ATTRIB_COUNT];
+	GLint				m_attrib_locations[ATTRIB_COUNT];
+
 	uint8_t				m_num_stock_uniforms;
 	ShaderUniform		m_stock_uniforms[UNIFORM_COUNT];
 	GLint				m_stock_uniform_locations[UNIFORM_COUNT];