我已经浏览了现有的主题并进行了一些测试,但我不确定自己是否正确地做了这件事,因此我宁愿提出一个问题,而不是被卡在多个OpenGL ES 2.0教程中花费更多时间弄清楚自己误解了什么。
我按照“OpenGL ES 2 for Android - A Quick Start Guide”中所述实现了VBO,现在需要一个动态VBO,每帧都要用一些矩阵计算(这可能是我错了的地方)对模型顶点进行更新。在这些计算之后,我想使用以下Android/Java代码将其传输(更新)到已分配的VBO(使用glBufferData)。
我按照“OpenGL ES 2 for Android - A Quick Start Guide”中所述实现了VBO,现在需要一个动态VBO,每帧都要用一些矩阵计算(这可能是我错了的地方)对模型顶点进行更新。在这些计算之后,我想使用以下Android/Java代码将其传输(更新)到已分配的VBO(使用glBufferData)。
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, this.id);
//GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, this.getLength() * Utils.BYTES_PER_FLOAT, null, GLES20.GL_DYNAMIC_DRAW);
/* CREATE BUFFER AND SET POSITION */
FloatBuffer fBuffer = ByteBuffer.allocateDirect((this.length = vertices.length) * Utils.BYTES_PER_FLOAT)
.order(ByteOrder.nativeOrder()).asFloatBuffer().put(vertices);
fBuffer.position(0);
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, fBuffer.capacity(), fBuffer);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
- this.id - 先前生成缓冲区的ID
- this.getLength - 最初分配的 FloatBuffer 的长度
您可能已经注意到,我已经注释掉了其他问题中提到的那行代码,因为保留它会导致屏幕上出现闪烁的对象,我无法正确理解。以这种方式进行一切工作得很好,但我注意到在运行应用程序时会出现一些 GC_FOR_ALLOC,这使我确信它可能不是有效的代码。
问题 - 或多或少 - 是:
- 更新此类缓冲区是否是有效方法,或者我可以获得如何在我提供的情况下(OpenGL ES 2.0、Android 4+)正确执行它的建议?
子问题包括:
- 在动态模型中使用 VBO 方法是否比在这些情况下使用 VAO 更好,或者我应该实现静态的 VBO 方法和动态的 VAO 方法?
- 仅查看 GC_FOR_ALLOC 调试信息,何时应开始担心内存问题?
- (一个有点超出话题的子问题)使用正交等距视图矩阵(正交 + 2x 旋转 + Z-平移),对于应用程序创建 GUI 的适当方法是什么?
编辑(27.12):
为了实现等距投影矩阵,我只需使用以下行:
Matrix.orthoM(this.orthoProjectionMatrix, 0, -screenAspect, screenAspect, -1.0f, 1.0f, -1.0f, 10.0f);
Matrix.translateM(this.viewProjectionMatrix, 0, this.orthoProjectionMatrix, 0, 0.0f, 0.0f, -5.0f);
Matrix.rotateM(this.viewProjectionMatrix, 0, 45, 1.0f, 0.0f, 0.0f);
Matrix.rotateM(this.viewProjectionMatrix, 0, 45, 0.0f, 1.0f, 0.0f);
简单来说:
- 根据屏幕的纵横比创建正交的肖像投影
- 仅在 Z 轴上移动(以便从远处看到场景)
- 将 X 轴旋转 45 度
- 将 Y 轴旋转 45 度
有些元素已经组合在一起了,所以请不要考虑一些翻译是就地进行的,而另一些是针对另一个矩阵的结果。
viewProjectionMatrix
进行平移,使其按照(-1, 0, 0)进行转换,然后传递给着色器 B)更新包含该对象顶点的VBO。对于这个例子的回答应该能够澄清我的看法。 - Łukasz Modliński