使用VBO渲染顶点的问题 - OpenGL

时间:2011-08-12 11:06:19

标签: c++ opengl render vbo

我将顶点数组函数转移到VBO以提高应用程序的速度。

这是我原来的工作顶点数组渲染函数:

void BSP::render()
{
    glFrontFace(GL_CCW);

    // Set up rendering states
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &vertices[0].x);

    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vertices[0].u);

    // Draw
    glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, indices);

    // End of rendering - disable states
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

工作得很好!

现在我将它们转移到VBO中,我的程序实际上导致我的显卡停止响应。我的顶点和索引上的设置完全相同。

新设置:

vboId在bsp.h中设置如下:GLuint vboId [2];

当我运行createVBO()函数时,我没有收到任何错误!

void BSP::createVBO()
{

    // Generate buffers
    glGenBuffers(2, vboId);

    // Bind the first buffer (vertices)
    glBindBuffer(GL_ARRAY_BUFFER, vboId[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // Now save indices data in buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboId[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

}

VBOS的渲染代码。我很确定它就在这里。只想像在顶点数组中那样在VBO中渲染什么。

渲染:

void BSP::renderVBO()
{
    glBindBuffer(GL_ARRAY_BUFFER, vboId[0]);         // for vertex coordinates
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboId[1]); // for indices

    // do same as vertex array except pointer
    glEnableClientState(GL_VERTEX_ARRAY);             // activate vertex coords array
    glVertexPointer(3, GL_FLOAT, 0, 0);               // last param is offset, not ptr

    // draw the bsp area
    glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));

    glDisableClientState(GL_VERTEX_ARRAY);            // deactivate vertex array

    // bind with 0, so, switch back to normal pointer operation
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

不确定错误是什么,但我很确定我的渲染功能有误。希望有一个更加统一的教程,因为有一堆在线,但它们经常互相矛盾。

3 个答案:

答案 0 :(得分:2)

另外Miro说的话(GL_UNSIGNED_BYTE应该是GL_UNSIGNED_SHORT),我认为您不想使用numVertices而是使用numIndices,就像您的非VBO电话。

glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);

否则您的代码看起来非常有效,如果这不能解决您的问题,可能错误就在其他地方。

顺便说一下,BUFFER_OFFSET(i)这个东西通常只是((char*)0+(i))的定义,所以你也可以直接传递字节偏移,特别是当它为0时。

编辑:刚发现另一个。如果您使用用于非VBO版本的精确数据结构(我在上面假设),那么您当然需要在sizeof(Vertex)中使用glVertexPointer作为步幅参数。

答案 1 :(得分:0)

如果在不使用VBO和相同数据到VBO缓冲区时将相同数据传递给glDrawElements。然后参数差异很小,没有FBO你已经使用GL_UNSIGNED_SHORT而FBO则使用了GL_UNSIGNED_BYTE。所以我认为VBO调用应该是这样的:

glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_SHORT, 0);

另见this tutorial,有很好的VBO缓冲区解释。

答案 2 :(得分:0)

如何声明顶点指数

glBufferData的size参数应该是缓冲区的大小(以字节为单位),如果传递 sizeof(vertices),它将返回声明的数组的总大小(不仅仅是分配的内容)。

尝试使用 sizeof(Vertex)* numVertices sizeof(indices [0])* numIndices 等内容。