5

我正在将我的顶点数组函数转移到 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);
}

不知道错误是什么,但我很确定我的渲染功能有误。希望有一个更统一的教程,因为网上有很多,但他们经常互相矛盾。

4

3 回答 3

2

除了米罗所说的(GL_UNSIGNED_BYTE应该是GL_UNSIGNED_SHORT),我认为您不想使用numVerticesbut numIndices,就像在您的非 VBO 通话中一样。

glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);

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

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

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

于 2011-08-12T13:46:05.280 回答
0

你如何声明顶点索引

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

改用sizeof(Vertex)*numVerticessizeof(indices[0])*numIndices之类的方法。

于 2011-08-12T13:54:43.370 回答
0

如果您在不使用 VBO 时将相同的数据传递给 glDrawElements,而将相同的数据传递给 VBO 缓冲区。然后参数几乎没有什么不同,没有你用过GL_UNSIGNED_SHORT的 FBO 和你用过的 FBO GL_UNSIGNED_BYTE。所以我认为 VBO 调用应该是这样的:

glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_SHORT, 0);

也看看这个教程,里面有 VBO 缓冲区解释得很好。

于 2011-08-12T11:14:58.033 回答