Opengl - display various vertex formats

I am looking for a good way to render mesh objects with different vertex layouts with great effort (for example, defining a visualization class for each vertex layout). The following are examples of different vertex formats.

enum EVertexFormat { VERTEX_FORMAT_UNDEFINED = -1, VERTEX_FORMAT_P1 = 0, VERTEX_FORMAT_P1N1, VERTEX_FORMAT_P1N1UV, VERTEX_FORMAT_P1N1C1, VERTEX_FORMAT_P1N1UVC1, }; // the simplest possible vertex -- position only struct SVertexP1 { math::Vector3D m_position; // position of the vertex }; struct SVertexP1N1 { math::Vector3D m_position; // position of the vertex math::Vector3D m_normal; // normal of the vertex }; // a typical vertex format with position, vertex normal // and one set of texture coordinates struct SVertexP1N1UV { math::Vector3D m_position; // position of the vertex math::Vector3D m_normal; // normal of the vertex math::Vector2D m_uv; // (u,v) texture coordinate }; struct SVertexP1N1C1 { math::Vector3D m_position; // position of the vertex math::Vector3D m_normal; // normal of the vertex uint32_t m_color_u32; // color of the vertex }; struct SVertexP1N1UVC1 { math::Vector3D m_position; // position of the vertex math::Vector3D m_normal; // normal of the vertex math::Vector2D m_uv; // (u,v) texture coordinate uint32_t m_color_u32; // color of the vertex }; 

The background is that I want to display different objects. Some of them are primitives (for example, planes, spheres) that do not have texture coordinates or normals. On the other hand, I want to display more complex objects with normals, texture coordinates, etc. Is there any sensible way or design to avoid programming multiple visualization classes and use the same rendering class instead? I know that this will also affect shaders.

+5
source share
1 answer

What you can do is give each of your vertex structures a static method, perhaps called EnableVertexAttribArray or something like that. In this static method, you set the vertex layout to GL_ARRAY_BUFFER , assuming that the correct array buffer is bound.

 struct SVertexP1N1 { math::Vector3D m_position; // position of the vertex math::Vector3D m_normal; // normal of the vertex static void EnableVertexAttribArray() { glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(SVertexP1N1), (const GLvoid*)offsetof(SVertexP1N1, m_position)); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(SVertexP1N1), (const GLvoid*)offsetof(SVertexP1N1, m_normal)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); } }; 

Then you can create a vertex buffer template class based on the vertex structure. For instance,

 template <class VertexType> class vertex_buffer { public: typedef VertexType vertex_type; vertex_buffer() { glGenVertexArrays(1, &m_vao); glGenBuffers(1, &m_vbo); glGenBuffers(1, &m_ibo); glBindVertexArray(m_vao); glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo); vertex_type::EnableVertexAttribArray(); // <-------- glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } ~vertex_buffer() { glDeleteVertexArrays(1, &m_vao); glDeleteBuffers(1, &m_vbo); glDeleteBuffers(1, &m_ibo); } // ... void draw() { glBindVertexArray(m_vao); glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glDrawElements(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, NULL); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } private: GLuint m_vao; GLuint m_vbo; GLuint m_ibo; std::vector<vertex_type> m_vertices; std::vector<GLuint> m_indices; } 
+3
source

All Articles