OpenGL着色器:如何分别移动每个顶点?

问题描述:

我想要Android的Rajawali库来在场景中绘制一些基本的3d对象。 有一个2000平面示例,展示了如何使用一个着色器非常“便宜”地渲染大量顶点。我可以将顶点数组传递给着色器并绘制它们。OpenGL着色器:如何分别移动每个顶点?

我想升级这个示例并相互独立地移动一些顶点。

我试过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

是否需要在修改缓冲区之前锁定缓冲区?我对此也很新,并且在C++中使用Ogre3d,但是原理应该仍然是一样的。你应该能够获得当前的顶点缓冲区,锁定它,修改它,然后解锁它。我不认为你必须做其他事情,但我可能完全错误。对不起,我没有太大的帮助。 – 2012-07-17 11:12:08

+0

glBufferSubData应该可以正常工作,你可以显示你尝试过的东西没有用吗? – Tim 2012-07-17 15:23:32

您只需修改缓冲区数据,然后从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); 
+0

已更新显示进一步优化。 – 2012-09-07 11:27:57