多个顶点缓冲区OpenGL c ++

Posted

技术标签:

【中文标题】多个顶点缓冲区OpenGL c ++【英文标题】:Multiple Vertex Buffers OpenGL c++ 【发布时间】:2021-07-05 08:01:14 【问题描述】:

我想绘制 2 个顶点缓冲区,但它只绘制第二个。我正在使用 OpenGL 4.6 和 COMPAT 配置文件。代码:

    float buffer[] =
    
        0.0f,0.0f,
        1.0f,0.0f,
        1.0f,1.0f
    ;
    float buffera[] =
    
        0.0f,0.0f,
        1.0f,0.0f,
        1.0f,-1.0f
    ;
    unsigned int id;
    glGenBuffers(1, &id);
    glBindBuffer(GL_ARRAY_BUFFER, id);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), buffer, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (const void*)8);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    unsigned int ida;
    glGenBuffers(1, &ida);
    glBindBuffer(GL_ARRAY_BUFFER, ida);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), buffera, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (const void*)8);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    unsigned int indices[]
    
        0,1,2
    ;

然后绘制调用:

glBindBuffer(GL_ARRAY_BUFFER, id);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);
glBindBuffer(GL_ARRAY_BUFFER, ida);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);

【问题讨论】:

【参考方案1】:

当调用glVertexAttribPointer 时,当前绑定到目标ARRAY_BUFFER 的缓冲区与属性相关联。绑定缓冲区对象是不够的。您必须在绘制对象之前进行顶点规范:

glBindBuffer(GL_ARRAY_BUFFER, id);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (const void*)8);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);

glBindBuffer(GL_ARRAY_BUFFER, ida);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (const void*)8);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);

我建议使用Vertex Array Object。 VAO用于存储顶点规范。

unsigned int vao1;
glGenVertexArrays(1, &vao1);
glBindVertexArray(vao1);

unsigned int id;
glGenBuffers(1, &id);
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), buffer, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (const void*)8);

unsigned int vao2;
glGenVertexArrays(1, &vao2);
glBindVertexArray(vao2);

unsigned int ida;
glGenBuffers(1, &ida);
glBindBuffer(GL_ARRAY_BUFFER, ida);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), buffera, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (const void*)8);
glBindVertexArray(vao1);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);
glBindVertexArray(vao2);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);

【讨论】:

【参考方案2】:

由于您没有使用 VAO,因此仅绑定缓冲区是不够的。确定绘制命令从哪个缓冲区读取的命令是glVertexAttribPointer。您必须将此命令移动到绘图命令中(并且由于它们没有做任何事情,因此将它们从初始化中删除。

代码应该是这样的:

初始化:

unsigned int id;
glGenBuffers(1, &id);
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), buffer, GL_STATIC_DRAW);

unsigned int ida;
glGenBuffers(1, &ida);
glBindBuffer(GL_ARRAY_BUFFER, ida);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), buffera, GL_STATIC_DRAW);

绘图:

glEnableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, id);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (const void*)8);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);

glBindBuffer(GL_ARRAY_BUFFER, ida);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (const void*)8);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);

【讨论】:

以上是关于多个顶点缓冲区OpenGL c ++的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL ES 2.0,使用多个顶点缓冲区进行绘制

Opengl_8_索引绘制

无法使用 VAO 和 EBO (openGL) 绘制多个对象

在交错的 openGL 顶点缓冲区对象之间复制

C++ OpenGL,绘制形状返回错误

✠OpenGL-2-图像管线