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

Posted

技术标签:

【中文标题】在 Android 上的 OpenGL ES 2.0 中使用 VBO/IBO【英文标题】:Using VBOs/IBOs in OpenGL ES 2.0 on Android 【发布时间】:2012-03-21 18:21:17 【问题描述】:

我正在尝试使用 OpenGL ES 2.0 在 android (API 10) 上创建一个简单的测试程序来绘制一个简单的矩形。我可以让它与直接引用顶点的浮动缓冲区一起工作,但我宁愿用 VBO/IBO 来做。我已经寻找了无数小时试图找到一个简单的解释(教程),但还没有遇到一个。我的代码编译和运行都很好,但是屏幕上除了清晰的颜色之外什么都没有显示。

这里有一些代码块可以帮助解释我现在是如何设置它的。

onSurfaceChanged() 的一部分:

int[] buffers = new int[2];
GLES20.glGenBuffers(2, buffers, 0);
rectVerts = buffers[0];
rectInds = buffers[1];
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, rectVerts);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, (rectBuffer.limit()*4), rectBuffer, GLES20.GL_STATIC_DRAW);

GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, rectInds);
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, (rectIndices.limit()*4), rectIndices, GLES20.GL_STATIC_DRAW);

onDrawFrame() 的一部分:

GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, rectVerts);
GLES20.glEnableVertexAttribArray(0);
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, rectInds);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_INT, 0);

【问题讨论】:

列出任何书籍或简单教程会很有帮助。 【参考方案1】:

我没有立即看到任何错误,但这里有一些您可以提出的想法。

1) “编译和运行良好”对于 opengl 程序来说是一个无用的指标。通过主动调用 glGetError 并使用 glGet(Shader|Program)iv 检查着色器的编译和链接状态来报告错误。您是否在任何地方检查错误?

2) 你不应该假设 0 是顶点的正确索引。它现在可能工作,但如果您更改着色器,以后可能会中断。使用 glGetAttribLocation 获取正确的索引。

3) 您正在绑定 verts 缓冲区 onDraw,但我没有看到有关索引缓冲区的任何信息。那总是绑定的吗?

4) 您也可以尝试使用 glDrawArrays 绘制您的 VBO,以将索引缓冲区排除在等式之外,以帮助调试以查看哪个部分是错误的。

否则,据我在那个小 sn-p 中所说,您所拥有的看起来是正确的。也许它之外的其他东西出了问题。

【讨论】:

1.我才刚刚开始,所以我还没有合并任何 opengl 错误检查。只是从我到目前为止看到的教程构建。但我会记住这一点。 2. 我有一个 vPosition(顶点着色器)句柄,我在这些领域中可以互换使用。再一次,这是我从其他代码中得到的,我不确定正确的方法。 3.它应该总是从onSurfaceChanged绑定,但我是新人所以可能不正确。 4. 我刚刚用 glDrawArray 试了一下,效果很好(但只画了一个三角形,因为我只定义了 4 个顶点)。 @Derek 我刚刚在 glDrawElements 的规范中注意到:“类型:指定索引中值的类型。必须是 GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT 或 GL_UNSIGNED_INT 之一。”看起来 GL_INT 是该函数的非法参数。如果你有错误检查,你会发现这个:) 是的,我只是自己看到并更改了它。这解决了我的问题。感谢蒂姆的帮助 BTW Tim - 我确实使用 glGetError() 来解决这个问题。我得到了 1280 并查看了规格以得出相同的结论。所以再次感谢:)

以上是关于在 Android 上的 OpenGL ES 2.0 中使用 VBO/IBO的主要内容,如果未能解决你的问题,请参考以下文章

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

使用 Android 上的 OpenGL ES 2.0,在帧缓冲区上渲染时是不是可以保留多重采样?

Android 上的 openGl es 在右上角显示一个 Square

如何确定Android OpenGL ES上的最大纹理内存

Android 上的 Opengl ES:如何使用 gluUnProject?

Android OpenGL ES 纹理映射/绘图问题 - 倾斜图像