我正在尝试用于Android的Rajawali库在场景中绘制一些基本的3D对象。 有一个样本2000个平面,它展示了如何使用一个着色器非常“廉价”地渲染大量顶点。我可以将顶点数组传递给着色器并绘制它们。
我想升级此示例并相互独立地移动一些顶点。
我已经尝试了glBufferSubData,但我无法改变场景中的任何内容。我发现的一种方法是更改数据并重新创建缓冲区,但我希望有一种更简单的方法来只更改必要的数据。
例如,我只想从已创建和绑定的缓冲区中更改某些位置。
初始化职位
float[] planePositions = new float[numVertices * 3];
....
创建缓冲区
mGeometry.createBuffer(mPlanePositionsBufferInfo, BufferType.FLOAT_BUFFER, mPlanePositions, GLES20.GL_ARRAY_BUFFER);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
设置职位
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, planePosBufferHandle);
GLES20.glEnableVertexAttribArray(maPlanePositionHandle);
fix.android.opengl.GLES20.glVertexAttribPointer(maPlanePositionHandle, 3, GLES20.GL_FLOAT,
false, 0, 0);
如何修改第一个平面的第一个顶点的位置? (planePositions [0] = a; planePositions [1] = b; planePositions [1] = c ...现在我必须将这个修改后的数组传递给opengl,但不知道如何)。
答案 0 :(得分:3)
您需要做的就是修改缓冲区数据,然后从PlanesGalore类中调用mGeometry.changeBufferData()。我将以下代码放在我的Renderer类的onDrawFrame()事件期间调用的更新方法中。
for (int i = 0; i < vertices.length; i += 3) {
mPlanePositions= mPlanePositions.put(i, mPlanePositions.get(i) - 0.01f);
}
mGeometry.changeBufferData(mCubePositionsBufferInfo, mPlanePositions, 0);
这是我完成动作的最好方法。另外,我已经提议对此issue进行更改,以便您指定缓冲区的哪些部分已更改,从而提高性能。
修改
我对引擎的更改已经获得批准,因此您现在可以进一步优化它。
// The offset position should be vertices.length * object #. In my use case this is 72*x
// allowing me to update the XYZ coordinates of all 24 vertices of a cube.
int offsetPosition = 0;
mGeometry.changeBufferData(mCubePositionsBufferInfo, mPlanePositions, offsetPosition, offsetPosition + vertices.length);