Java OpenGL ES 2.0和动态VBO';s

Java OpenGL ES 2.0和动态VBO';s,java,android,opengl-es,vbo,Java,Android,Opengl Es,Vbo,我已经完成了现有的主题,并自己进行了一些测试,但我不太确定我是否以正确的方式进行了测试,因此我宁愿问一个问题,也不愿花更多的时间思考我对使用多个OpenGL ES 2.0教程的误解 我已经实现了“OpenGL ES 2 for Android-快速入门指南”中介绍的VBO,现在我需要一个动态VBO,它在模型顶点上的每一帧都用一些矩阵计算进行更新(这可能是我错的地方)。在这些计算之后,我想用这段Android/Java代码将这些数据传输(更新)到已经分配的VBO(使用glBufferData):

我已经完成了现有的主题,并自己进行了一些测试,但我不太确定我是否以正确的方式进行了测试,因此我宁愿问一个问题,也不愿花更多的时间思考我对使用多个OpenGL ES 2.0教程的误解

我已经实现了“OpenGL ES 2 for Android-快速入门指南”中介绍的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);
  • 此.id-以前生成的缓冲区的id
  • this.getLength-初始分配的FloatBuffer的长度
正如你们所注意到的,我已经注释掉了在其他问题中提到的那一行,仅仅是因为我无法正确理解屏幕上一个闪烁的物体。通过这种方式,一切都运行得很好,但我注意到在应用程序运行期间出现了一些GC_FOR_ALLOC,这确保了它可能不是一段有效的代码

问题或多或少是:

  • 这是一种更新此类缓冲区的有效方法,还是我可以在我提供的环境(OpenGL ES 2.0,Android 4+)下获得如何正确执行的建议?
A次级问题是:

  • 在这些情况下,对动态模型使用VBO的方法是否比使用VAO更好?还是我应该对静力学使用VBO方法,对动力学使用VAO方法
  • 我什么时候应该开始担心内存问题,只需查看GC_获取所有调试信息
  • (稍微超出主题子问题)使用正交等轴测视图矩阵(正交+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度
有些元素是组合在一起的,所以请不要考虑这样一个事实,即有些翻译已经到位,有些是与另一个矩阵的结果相关的。

(前言:我不熟悉OpenGL ES,只熟悉普通OpenGL。但是,我无法想象API有太大的不同)

这是更新这种缓冲区的有效方法吗

除非
fBuffer
始终小于或等于OpenGL缓冲区的大小,否则不会
glBufferSubData
不会调整缓冲区大小,并且不允许在分配的范围外写入。您可以使用
glBufferData
将缓冲区重新分配到新的大小。也请查收

在这些情况下,对动态模型使用VBO的方法是否比使用VAO更好?还是我应该对静力学使用VBO方法,对动力学使用VAO方法

VBO和VAO是正交概念。VBOs存储顶点数据;VAO只需指定渲染顶点的位置和方式

使用正交等轴测视图矩阵(正交+2x旋转+Z平移)为应用程序创建GUI的合适方法是什么


删除Z转换,而是在禁用深度缓冲区的情况下最后呈现GUI。还有,轮换是为了什么?

1)(根据缓冲区大小)我想删除所有以前的数据,并发送相同大小的新批。简单地说,我想用一些计算更新旧的缓冲区数据。我觉得没有必要创建新的缓冲区,但我还没有找到一个能为我提供另一种解决方案的答案。2) (根据VBO/VAO)正常。我将通读一些关于这个主题的其他材料,因为我似乎没有正确理解。3)(指等轴测投影)我已经掌握了一种更好的方法,即:使用等轴测投影,绘制场景对象,切换到简单的正交投影,绘制HUD。而且它似乎工作得很好(当场景移动时,HUD保持在场景上方的相同位置,就像我拖动时一样)@ukaszModliński如果上传的数据大小相同,那么您可以使用
glBufferSubData
对其进行写入。如果需要调整缓冲区大小(或孤立旧缓冲区;请参阅缓冲区流链接),则只需使用
glBufferData
。将
glBufferSubData
想象成
memcpy
glBufferData
想象成
realloc
。当然可以,但我更愿意考虑忽略创建新的
FloatBuffer
——我应该保留我初始化
glBufferData
的方法吗?或者这种创建方法有效吗?我相信这种更新会导致我最近注意到的(
GC_FOR_ALLOC)
(测试它会禁用更新)@ukaszModliński您可以保留缓冲区。您还可以使用
glMapBuffer
将缓冲区映射到内存(如果ES中存在)。您在问题中描述的内容与我有关。您使用的是OpenGL ES 2.0,但您谈论的是对存储在VBO中的顶点应用矩阵变换。如果可以访问着色器,则通常不会执行此操作。将要变换顶点的矩阵传递给顶点着色器,并在每次绘制时应用该变换。顶点缓冲区数据实际上是静态的,所有工作(重复)都由顶点着色器完成。从事物的声音中,你可以在矩阵中积累你的变换,而不是顶点缓冲区