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

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

我不确定错误是什么,但我相当确定我的渲染函数有问题。希望有更统一的教程,因为有很多在线教程,但它们经常互相矛盾。


1
你还在监视这个问题并等待正确的答案吗?还是你已经放弃了它(或者在发布后2分钟内解决了)?如果是前者,请随时更新问题或询问您不理解的内容。如果是后者,仅仅放弃一个问题是不好的做法(即使您自己解决了它)。如果您发现错误与已发布的答案完全不同,请随时发布并接受您自己的答案。 - Christian Rau
@Christian Rau,我最终放弃了,直到我更好地理解了顶点数组。然后我会尝试VBO,因为我认为它们很相似。谢谢! - Satchmo Brown
3个回答

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版本相同的数据结构(我上面假设了这一点),那么你当然需要在 glVertexPointer 中使用 sizeof(Vertex) 作为步长参数。

0

如果您在不使用VBO时将相同的数据传递给glDrawElements,并将相同的数据传递给VBO缓冲区。那么参数略有不同,没有FBO时您使用了GL_UNSIGNED_SHORT,而使用FBO时您使用了GL_UNSIGNED_BYTE。因此,我认为VBO调用应该如下所示:

glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_SHORT, 0);

同时也可以看看这个教程, 里面对VBO缓冲区的解释非常清晰明了。


仍然会导致我的图形驱动程序无响应。而且整个BUFFER_OFFSET(0)在许多教程中都有涉及。不管怎样,还是谢谢! - Satchmo Brown
你能否在调用OpenGL函数时,也为每个变量声明类型吗? - kravemir

0

你如何声明顶点索引

glBufferData的大小参数应该是缓冲区的字节数,如果你传递sizeof(vertices),它会返回所声明数组的总大小(而不仅是分配的大小)。

尝试使用sizeof(Vertex)*numVerticessizeof(indices[0])*numIndices之类的东西。


1
假设他使用数组(而不是动态分配的存储),sizeof(vertices)应该是完全有效的。否则,这当然是一个问题。 - Christian Rau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接