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

Posted

技术标签:

【中文标题】使用 VBO 渲染顶点的问题 - OpenGL【英文标题】:Problems using VBOs to render vertices - OpenGL 【发布时间】:2011-10-25 17:39:44 【问题描述】:

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

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

【问题讨论】:

您是在关注这个问题并等待正确答案,还是放弃(或发布后 2 分钟解决)?在前一种情况下,请随时更新问题或询问您不理解的内容。在后一种情况下,放弃一个问题(即使你自己解决了)是不好的做法。如果您发现错误与发布的答案完全不同,请随时发布并接受您自己的答案。 @Christian Rau 我最终放弃了这个,直到我对顶点数组有了更好的理解。然后我会选择 VBO,因为我认为它们很相似。谢谢! 【参考方案1】:

除了米罗所说的(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 中的步幅参数。

【讨论】:

【参考方案2】:

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

glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_SHORT, 0);

也可以看看this tutorial,里面有VBO缓冲区解释的很好。

【讨论】:

仍然导致我的图形驱动程序无响应。整个 BUFFER_OFFSET(0) 包含在许多教程中。还是谢谢! 您能否也为您传递给 gl 函数的每个变量发布声明?【参考方案3】:

如何声明顶点索引

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

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

【讨论】:

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

以上是关于使用 VBO 渲染顶点的问题 - OpenGL的主要内容,如果未能解决你的问题,请参考以下文章

opengl vbo 纹理

使用 VBO 在 OpenGL 中渲染人群

JOGL/OpenGL VBO - 如何渲染顶点?

OpenGL,交错的 VBO(顶点、法线和颜色)与光

GL 错误:尝试使用 VBO 渲染时内存不足

各种顶点格式和vbo