2015-05-18 97 views
5

我正在尋找一種很好的方式來渲染具有不同頂點佈局的網格對象,而不需要付出很大努力(例如爲每個頂點佈局定義一個渲染器類)。您可以在下面看到一些不同頂點格式的例子。Opengl - 渲染不同的頂點格式

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 
}; 

背景是,我想渲染不同的對象。它們中的一些是不具有紋理座標或法線的基元(例如平面,球體)。另一方面,我想呈現更復雜的對象,其中有法線,紋理座標等。有沒有一種智能的方法或設計可以避免編程多個渲染器類,而是使用單個渲染器類?我知道,這也會影響着色器。

回答

3

你可以做的是給你的每個頂點結構一個靜態方法,可能被稱爲EnableVertexAttribArray或類似的東西。在這種靜態方法中,假設已經綁定了正確的數組緩衝區,您可以在GL_ARRAY_BUFFER中設置頂點佈局。

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); 
    } 
}; 

然後,您可以根據頂點結構創建一個頂點緩衝區的模板類。例如,

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; 
} 
+0

哦,這是一個不錯的主意。謝謝! – bobby