OpenGL着色器:如何单独移动每个顶点?

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,但不知道该怎么做。


在修改缓冲区之前,您需要锁定它吗?我也很新,正在使用C++的Ogre3d,但原则应该是相同的。您应该能够获取当前顶点缓冲区,锁定它,修改它,然后解锁它。我认为您不必做其他任何事情,但我可能完全错了。抱歉我没有提供更多帮助。 - Jon Taylor
glBufferSubData 应该可以正常工作,你能展示一下你尝试过但没有成功的内容吗? - Tim
1个回答

3
你所需要做的就是修改缓冲区数据,然后从PlanesGalore类中调用mGeometry.changeBufferData()。我将以下代码放在了一个update方法中,在我的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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接