3

我正在尝试 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 但不知道如何)。

4

1 回答 1

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);

这是我能找到的完成动作的最佳方式。此外,我在这个问题上提出了一个更改,让您可以指定缓冲区的哪些部分发生了更改,这应该提供更高的性能。

编辑

我对引擎的更改已获得批准,因此您现在可以像这样进一步优化它。

// 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);
于 2012-09-06T18:17:26.723 回答