使用 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)*numVertices 和 sizeof(indices[0])*numIndices 之类的方法。
【讨论】:
假设他使用数组(而不是动态分配的存储),sizeof(vertices)
应该是完全有效的。否则这当然是个问题。以上是关于使用 VBO 渲染顶点的问题 - OpenGL的主要内容,如果未能解决你的问题,请参考以下文章