|
From: Lasse Kärkkäi. <tr...@us...> - 2011-02-24 02:47:50
|
Author: Lasse Kärkkäinen <tronic+ndrm at trn.iki.fi> Date: Thu Feb 24 01:56:18 2011 +0100 VertexArray simplification/optimization. Be sure the always call .Vertex only after all other attributes from now on. --- game/glshader.cc | 17 +++++++---------- game/glshader.hh | 54 ++++++++++++++++++++++++++---------------------------- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/game/glshader.cc b/game/glshader.cc index fa864d6..c01912f 100644 --- a/game/glshader.cc +++ b/game/glshader.cc @@ -139,33 +139,30 @@ GLint Shader::operator[](const std::string& uniform) { } void VertexArray::Draw(GLint mode) { + if (empty()) return; GLint program; glGetIntegerv(GL_CURRENT_PROGRAM, &program); GLint vertPos = glGetAttribLocation(program, "vertPos"); GLint vertTexCoord = glGetAttribLocation(program, "vertTexCoord"); GLint vertNormal = glGetAttribLocation(program, "vertNormal"); GLint vertColor = glGetAttribLocation(program, "vertColor"); - unsigned vertices = size(); + glmath::Vec4 const* ptr = &m_vertices[0].position; + unsigned stride = sizeof(VertexInfo); if (vertPos != -1) { glEnableVertexAttribArray(vertPos); - glVertexAttribPointer(vertPos, 3, GL_FLOAT, GL_FALSE, 0, &m_vertices.front()); + glVertexAttribPointer(vertPos, 4, GL_FLOAT, GL_FALSE, stride, ptr); } if (vertTexCoord != -1) { - if (m_texcoords.empty()) m_texcoords.resize(4 * vertices, 0.0f); // FIXME: Shouldn't be using a texturing shader if not texturing... - if (m_texcoords.size() != 4 * vertices) throw std::logic_error("Invalid number of vertex texture coordinates"); glEnableVertexAttribArray(vertTexCoord); - glVertexAttribPointer(vertTexCoord, 4, GL_FLOAT, GL_FALSE, 0, &m_texcoords.front()); + glVertexAttribPointer(vertTexCoord, 4, GL_FLOAT, GL_FALSE, stride, ptr + 1); } if (vertNormal != -1) { - if (m_normals.size() != 3 * vertices) throw std::logic_error("Invalid number of vertex normals"); glEnableVertexAttribArray(vertNormal); - glVertexAttribPointer(vertNormal, 3, GL_FLOAT, GL_FALSE, 0, &m_normals.front()); + glVertexAttribPointer(vertNormal, 4, GL_FLOAT, GL_FALSE, stride, ptr + 2); } if (vertColor != 1) { - if (m_colors.empty()) m_colors.resize(4 * vertices, 1.0f); - if (m_colors.size() != 4 * vertices) throw std::logic_error("Invalid number of vertex colors"); glEnableVertexAttribArray(vertColor); - glVertexAttribPointer(vertColor, 4, GL_FLOAT, GL_FALSE, 0, &m_colors.front()); + glVertexAttribPointer(vertColor, 4, GL_FLOAT, GL_FALSE, stride, ptr + 3); } glDrawArrays(mode, 0, size()); diff --git a/game/glshader.hh b/game/glshader.hh index 5ab89d0..bfd0d44 100644 --- a/game/glshader.hh +++ b/game/glshader.hh @@ -99,67 +99,65 @@ struct UseShader { }; namespace glutil { + // Note: if you reorder or otherwise change the contents of this, VertexShader::Draw() must be modified accordingly + struct VertexInfo { + glmath::Vec4 position; + glmath::Vec4 texCoord; + glmath::Vec4 normal; + glmath::Vec4 color; + VertexInfo(): + position(0.0, 0.0, 0.0, 1.0), + texCoord(0.0, 0.0, 0.0, 0.0), + normal(0.0, 0.0, 0.0, 0.0), + color(1.0, 1.0, 1.0, 1.0) + {} + }; /// handy vertex array capable of drawing itself class VertexArray { private: - std::vector<float> m_vertices; - std::vector<float> m_normals; - std::vector<float> m_texcoords; - std::vector<float> m_colors; - + std::vector<VertexInfo> m_vertices; + VertexInfo m_vert; public: VertexArray() {} VertexArray& Vertex(float x, float y, float z = 0.0f) { - m_vertices.push_back(x); - m_vertices.push_back(y); - m_vertices.push_back(z); + m_vert.position = glmath::Vec4(x, y, z, 1.0f); + m_vertices.push_back(m_vert); + m_vert = VertexInfo(); return *this; } VertexArray& Normal(float x, float y, float z) { - m_normals.push_back(x); - m_normals.push_back(y); - m_normals.push_back(z); + m_vert.normal = glmath::Vec4(x, y, z, 1.0f); return *this; } VertexArray& TexCoord(float s, float t, float u = 0.0f, float v = 0.0f) { - m_texcoords.push_back(s); - m_texcoords.push_back(t); - m_texcoords.push_back(u); - m_texcoords.push_back(v); + m_vert.texCoord = glmath::Vec4(s, t, u, v); return *this; } - VertexArray& Color(float r, float g, float b, float a) { - m_colors.push_back(r); - m_colors.push_back(g); - m_colors.push_back(b); - m_colors.push_back(a); + VertexArray& Color(float r, float g, float b, float a = 1.0f) { + m_vert.color = glmath::Vec4(r, g, b, a); return *this; } VertexArray& Color(const glutil::Color& c) { - m_colors.push_back(c.r); - m_colors.push_back(c.g); - m_colors.push_back(c.b); - m_colors.push_back(c.a); - return *this; + return Color(c.r, c.g, c.b, c.a); } void Draw(GLint mode = GL_TRIANGLE_STRIP); bool empty() const { - return m_vertices.empty() && m_normals.empty() && m_texcoords.empty() && m_colors.empty(); + return m_vertices.empty(); } unsigned size() const { - return m_vertices.size() / 3; + return m_vertices.size(); } void clear() { - m_vertices.clear(); m_normals.clear(); m_texcoords.clear(); m_colors.clear(); + m_vertices.clear(); } }; |