使用glDrawElements的OpenGL ES 2.0渲染仅显示单个VBO

时间:2012-08-31 04:22:16

标签: ios opengl-es opengl-es-2.0

请参阅下面的编辑,这会显着改变问题。

ORIGINAL:

使用 Xcode 4.1 iOS 4 上使用 OpenGL ES 2.0 渲染元素时出现问题。

使用 glDrawElements

显示的内容没有任何问题
glDrawElements(GL_TRIANGLES, indicesSizeAll/sizeof(IndicesAll[0]), GL_UNSIGNED_SHORT, 0);

但如果我使用等效的 glDrawRangeElements ,我会遇到各种问题:

glDrawRangeElements(GL_TRIANGLES, 0, (indicesSizeAll/sizeof(IndicesAll[0]))-1, indicesSizeAll/sizeof(IndicesAll[0]), GL_UNSIGNED_SHORT, 0);

我收到以下构建警告:

Semantic Issue: Implicit declaration of function 'glDrawRangeElements' is invalid in C99

执行期间出现以下错误:

Program received signal: "EXC_BAD_ACCESS"

我包含了这个函数原型:

extern void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices);

摆脱了构建警告,但我仍然有执行错误。

不确定如何解决此问题。我正在逐步采取措施并展示一些事情,但是前进我相信我将需要使用 glDrawRangeElements ,所以我试图让它工作。有人给我一些指导吗?

修改

引起我的注意:

  

OpenGL ES 1.1或2.0中不存在DrawRangeElements,这就是它不在系统头文件中的原因。你应该改为调用glDrawElements。

这让我回到了以前我认为 glDrawRangeElements 可以解决我的问题的情况。

这意味着我需要使用多个缓冲区来渲染所有内容,因为我想对每个缓冲区应用不同的旋转。

[modelView rotateBy:CC3VectorMake(x, y, z)];
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);

我设置了两个不同的缓冲区:

glGenBuffers(1, &vertexBufferA);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferA);
glBufferData(GL_ARRAY_BUFFER, verticesSizeA, VerticesA, GL_STATIC_DRAW);

glGenBuffers(1, &indexBufferA);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferA);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesSizeA, IndicesA, GL_STATIC_DRAW);
--------------------
glGenBuffers(1, &vertexBufferZ);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferZ);
glBufferData(GL_ARRAY_BUFFER, verticesSizeZ, VerticesZ, GL_STATIC_DRAW);

glGenBuffers(1, &indexBufferZ);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferZ);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesSizeZ, IndicesZ, GL_STATIC_DRAW);

然后当我想渲染这些元素时:

glBindBuffer(GL_ARRAY_BUFFER, vertexBufferA);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferA);

glDrawElements(GL_TRIANGLES, indicesSizeA/sizeof(IndicesA[0]), GL_UNSIGNED_SHORT, 0);
--------------------
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferZ);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferZ);

glDrawElements(GL_TRIANGLES, indicesSizeZ/sizeof(IndicesZ[0]), GL_UNSIGNED_SHORT, 0);

glDrawElements 的单次调用将呈现正常,但如果我为每个缓冲区调用它,则只有第二次调用会进行任何渲染。

不完全确定我在这里缺少什么。我是整个OpenGL的新手,在我学习的过程中学习。

感谢任何指示或澄清。

1 个答案:

答案 0 :(得分:1)

我已经找到了自己问题的答案。事实证明,我可以将所有数据保存在一个缓冲区中,并为每个渲染指定所需的范围。


设置顶点和索引缓冲区:单组缓冲区包含两个图形(A和Z)的数据

glGenBuffers(1, &vertexBufferAll);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferAll);
glBufferData(GL_ARRAY_BUFFER, verticesSizeAll, VerticesAll, GL_STATIC_DRAW);

glGenBuffers(1, &indexBufferAll);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferAll);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesSizeAll, IndicesAll, GL_STATIC_DRAW);

定义顶点数组中数据的偏移量

glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 0));
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));

绘制位于索引数组中指定偏移量的元素

glDrawElements(GL_TRIANGLES, indicesCountA, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * 0));
glDrawElements(GL_TRIANGLES, indicesCountZ, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * indicesCountA));

在每个glDrawElements之前应用适当的矩阵以实现所需的旋转

glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);

既然我已经有了工作,那看起来确实非常简单明了,但我不得不经历很多变化,直到我偶然发现了正确的设置。感觉像OpenGL一样,如果事情不是100%正确,那么它们是不正确的。