【问题标题】:Multiple meshes, multiple VBOs, multiple VAOs, OpenGL 4.1多个网格、多个 VBO、多个 VAO、OpenGL 4.1
【发布时间】:2014-11-25 22:43:55
【问题描述】:

我正在尝试使用 OpenGL 4.1 绘制两个不同的网格。在任何给定时间,只会绘制一个网格,我的目标是在它们之间切换。我将网格的顶点和索引数据存储在一个对象中,下面称为 g_obj。因此,第一个网格的数据由 g_obj->vertices_ 和 g_obj->indices 获取,第二个网格的数据由 g_obj->vertices_linear_ 和 g_obj->indices_linear_ 获取。

我可怕的想法是为每个网格设置不同的 VBO 和 VAO。然后在绘图调用中,我只需绑定适当的 VAO,然后执行 glDraw*。但是,我的代码在第一次绘制调用时出现了段错误(见下文)。

enum VAO_ID 
{
    VAO,
    VAO_LINEAR,
    NUM_VAOS
};

enum BUFFER_ID 
{
    VERTEX_BUFFER,
    VERTEX_BUFFER_LINEAR,
    INDEX_BUFFER,
    INDEX_BUFFER_LINEAR,
    NUM_BUFFERS
};

enum ATTRIBUTE_ID 
{
    VERTEX_POSITION,
    VERTEX_COLOR
};

GLuint g_vaos[NUM_VAOS];
GLuint g_buffers[NUM_BUFFERS];

再往下,我创建顶点/索引缓冲区和顶点数组对象:

void bufferGeometry()
{

   // create vertex buffers and vertex array object 
    glGenVertexArrays(NUM_VAOS, g_vaos);
    glGenBuffers(NUM_BUFFERS, g_buffers);

    // rotational grating
    glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER]);
    glBufferData(GL_ARRAY_BUFFER,
                 g_obj->num_vertices_ * sizeof(vertex2D),
                 g_obj->vertices_,
                 GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                 g_obj->num_indices_ * sizeof(GLushort),
                 g_obj->indices_,
                 GL_STATIC_DRAW);
    glBindVertexArray(g_vaos[VAO]);
    glEnableVertexAttribArray(VERTEX_POSITION);
    glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE, 
                          sizeof(vertex2D),
                          (const GLvoid *)offsetof(vertex2D, position));
    glEnableVertexAttribArray(VERTEX_COLOR);
    glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE, 
                          sizeof(vertex2D),
                          (const GLvoid *)offsetof(vertex2D, color));
    glBindVertexArray(0);

    // linear grating
    glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER_LINEAR]);
    glBufferData(GL_ARRAY_BUFFER,
                 g_obj->num_vertices_linear_ * sizeof(vertex2D),
                 g_obj->vertices_linear_,
                 GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER_LINEAR]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                 g_obj->num_indices_linear_ * sizeof(GLushort),
                 g_obj->indices_linear_,
                 GL_STATIC_DRAW);

    glBindVertexArray(g_vaos[VAO_LINEAR]);
    glEnableVertexAttribArray(VERTEX_POSITION);
    glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE, 
                          sizeof(vertex2D),
                          (const GLvoid *)offsetof(vertex2D, position));

    glEnableVertexAttribArray(VERTEX_COLOR);
    glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE, 
                          sizeof(vertex2D),
                          (const GLvoid *)offsetof(vertex2D, color));

    glBindVertexArray(0);

}

那么,这里是绘图调用:

glBindVertexArray(g_vaos[VAO]);
g_obj = &g_grating_uno;
glUseProgram(g_program);
glUniform3fv(g_trans_scale_location, 1, g_obj->trans_scale_);
glDrawElements(GL_TRIANGLES, g_obj->num_indices_,
               GL_UNSIGNED_SHORT, (const GLvoid *)0);

glDrawElements 行有哪些段错误。

我知道一般的“高性能”策略是将来自两个网格的数据打包到单个 VBO 中,并且由于两个网格之间的数据格式相同,所以我只需要一个 VAO。但是,由于我很懒,我想知道是否有人能明白为什么我现有的策略不起作用或不起作用,或者您是否认为问题出在其他地方。我的猜测是它与我的 bufferGeometry() 函数有关。我对 VAO 与特定 VBO 的关联(如果有的话)的理解有点薄弱。谢谢,对不起,我很笨!

【问题讨论】:

    标签: opengl


    【解决方案1】:

    您应该重复调用以绑定 glBindVertexArray 之间的元素缓冲区:

    glBindVertexArray(g_vaos[VAO]);
    glEnableVertexAttribArray(VERTEX_POSITION);
    glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE, 
                          sizeof(vertex2D),
                          (const GLvoid *)offsetof(vertex2D, position));
    glEnableVertexAttribArray(VERTEX_COLOR);
    glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE, 
                          sizeof(vertex2D),
                          (const GLvoid *)offsetof(vertex2D, color));
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER]);
    glBindVertexArray(0);
    

    元素缓冲区绑定是 VAO 状态的一部分,并在绑定新的 VAO 时重置。

    【讨论】:

    • 啊,好的,我也试试。谢谢!
    【解决方案2】:

    啊,通过在绑定 VBO 之前绑定 VAO 来修复它(我认为):

    void bufferGeometry()
    {
    
       // create vertex buffers and vertex array object 
        glGenVertexArrays(NUM_VAOS, g_vaos);
        glGenBuffers(NUM_BUFFERS, g_buffers);
    
        // rotational grating
        glBindVertexArray(g_vaos[VAO]);
        glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER]);
        glBufferData(GL_ARRAY_BUFFER,
                     g_obj->num_vertices_ * sizeof(vertex2D),
                     g_obj->vertices_,
                     GL_STATIC_DRAW);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER]);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                     g_obj->num_indices_ * sizeof(GLushort),
                     g_obj->indices_,
                     GL_STATIC_DRAW);
        glEnableVertexAttribArray(VERTEX_POSITION);
        glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE, 
                              sizeof(vertex2D),
                              (const GLvoid *)offsetof(vertex2D, position));
        glEnableVertexAttribArray(VERTEX_COLOR);
        glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE, 
                              sizeof(vertex2D),
                              (const GLvoid *)offsetof(vertex2D, color));
        glBindVertexArray(0);
    
        // linear grating
        glBindVertexArray(g_vaos[VAO_LINEAR]);
        glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER_LINEAR]);
        glBufferData(GL_ARRAY_BUFFER,
                     g_obj->num_vertices_linear_ * sizeof(vertex2D),
                     g_obj->vertices_linear_,
                     GL_STATIC_DRAW);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER_LINEAR]);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                     g_obj->num_indices_linear_ * sizeof(GLushort),
                     g_obj->indices_linear_,
                     GL_STATIC_DRAW);
    
        glEnableVertexAttribArray(VERTEX_POSITION);
        glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE, 
                              sizeof(vertex2D),
                              (const GLvoid *)offsetof(vertex2D, position));
    
        glEnableVertexAttribArray(VERTEX_COLOR);
        glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE, 
                              sizeof(vertex2D),
                             (const GLvoid *)offsetof(vertex2D, color));
    
        glBindVertexArray(0);
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 2019-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-21
      • 2012-12-24
      相关资源
      最近更新 更多