OpenGL ES 2.0,使用多个顶点缓冲区进行绘制

Posted

技术标签:

【中文标题】OpenGL ES 2.0,使用多个顶点缓冲区进行绘制【英文标题】:OpenGL ES 2.0, drawing using multiple vertex buffers 【发布时间】:2012-01-07 18:57:50 【问题描述】:

我找不到太多关于 opengl es 2.0 是否支持从多个顶点缓冲区绘制的信息(即,一个顶点缓冲区用于位置数据,另一个用于法线、颜色等)。此页面http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html 和清单 9.4 特别暗示您应该能够,但我无法让它在我的程序上运行。违规draw call的代码:

glBindBuffer(GL_ARRAY_BUFFER, mPositionBuffer->openglID);
glVertexAttribPointer(0, 4, GL_FLOAT, 0, 16, NULL);
glEnableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, mTexCoordBuffer->openglID);
glVertexAttribPointer(1, 2, GL_FLOAT, 0, 76, NULL);
glEnableVertexAttribArray(1);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->openglID);
glDrawElements(GL_TRIANGLES, 10788, GL_UNSIGNED_SHORT, NULL);

此绘图调用将在模拟器上因 EXC_BAD_ACCESS 而停止或崩溃,并在设备上产生非常奇怪的行为(opengl 绘制随机三角形或呈现先前渲染的帧)。没有任何 opengl 调用会返回错误,我已经广泛检查了顶点缓冲区,并且确信它们具有正确的大小和数据。

有没有人成功地使用多个顶点缓冲区进行渲染,并且可以分享他们为什么这可能不起作用的经验?任何有关从何处开始调试不返回任何错误代码的停滞/失败的绘图调用的信息将不胜感激。

【问题讨论】:

【参考方案1】:

访问冲突通常意味着您尝试绘制的三角形数量超过了在缓冲区中分配的数量。您设置缓冲区的方式非常好,应该可以工作,我会检查您的参数是否设置正确:

http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml http://www.opengl.org/sdk/docs/man/xhtml/glDrawElements.xml

我认为您的问题要么是您在 glVertexAttribPointer 调用中切换了偏移量和步幅,要么您错误计算了要绘制的索引数量

【讨论】:

【参考方案2】:

是的,您可以使用多个顶点缓冲区对象 (VBO) 进行一次绘制。 OpenGL ES 2.0 spec 在第 2.9.1 节中这样说。

你的代码中真的有所有这些硬编码的常量吗?那 76 是从哪里来的?

如果您需要调试帮助,您需要发布初始化缓冲区的代码(调用glGenBuffersglBufferData 的代码)。您还应该发布 EXC_BAD_ACCESS 的堆栈跟踪。

如果你画一些更简单的东西,比如一个三角形,而不是 3596 个三角形,也可能更容易调试。

【讨论】:

以上是关于OpenGL ES 2.0,使用多个顶点缓冲区进行绘制的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL ES 2.0 每个顶点使用多个法线向量

OpenGL ES 2.0 vbo 白屏

共享内存架构中的 OpenGL (ES 2.0) VBO 性能

在 OpenGL ES 2.0 中创建精灵类

iphone opengl es 2.0,如何使用objective-c类来存储原始数据?

在 Android 上的 OpenGL ES 2.0 中使用 VBO/IBO