如何在opengles中更改glDrawArrays方法中使用的vertexbuffer的内容

时间:2011-05-01 16:09:17

标签: opengl-es 3d

我有一些三角形多边形并以传统方式绘制它们: (android-java code)

gl.glDrawArrays(GL10.GL_TRIANGLES, i, j);

我想更新三角形的顶点坐标。我发现的所有教程都使用初始顶点数据,然后只对它们应用变换。我需要独立改变每个顶点坐标。

我更改了用于创建相关顶点缓冲区的数组的内容,但它不会在屏幕上进行任何更改。我想,在每个帧上重建顶点缓冲似乎不正确。

如果你知道的话,至少可以指出任何示例源代码吗?

3 个答案:

答案 0 :(得分:6)

您似乎在寻找glBufferSubData。基本上,您正如您所描述的那样更新数组的内容,然后调用glBufferSubData以使用新值更新顶点缓冲区对象。

这假设您只修改了相对较小的数据子集。如果您要修改大部分数据,通常最好再次调用glBufferData

答案 1 :(得分:1)

我发现我的大部分问题都与java-android有关。 @jerry在我的问题中提出了对主要想法的正确解决方案,但我将解决java-android相关问题的部分:

首先; Android的Renderer界面中的方法签名为您提供了GL10对象作为参数,但您需要的一些方法是在opengl-es1.1中,因此您需要转换gl对象。

public void onDrawFrame(GL10 gl) {
   GL11 gl11 = (GL11)gl;    

当然,如果设备不支持opengl-es1.1,你的代码将无效,但这不属于我们的主题。

我的另一个问题是关于opengl-es的java实现的差异。在java中,您创建一个相关的Buffer对象,它是java.nio包中的本机java类,并使用您指定的数组填充此缓冲区的内部。

public static FloatBuffer createFloatBuffer(float[] array){     
    ByteBuffer byteBuf = ByteBuffer.allocateDirect(array.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    FloatBuffer fbuf = byteBuf.asFloatBuffer();
    fbuf.put(array);
    fbuf.position(0);
    return fbuf;
}

在此部分之后,您与数组对象无关。您需要更新缓冲区对象。您可以使用相关缓冲类的put(index, value)方法更新缓冲区的内容。

这是我们想要绘制的对象的draw()方法。 vertexBufferFloatBuffer个对象。您可以从这个片段中了解我的想法。

public void draw(GL11 gl) {

    vertexBuffer.put(index, floatValue);
    gl.glBufferSubData(GL11.GL_ARRAY_BUFFER, 0, vertexBuffer.capacity(),vertexBuffer);

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

    gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

}

如果有误导性的话,你可以纠正我。

答案 2 :(得分:-1)

我认为您要做的是在初始化时创建多个顶点缓冲区,然后使用glBindBuffer()绑定到不同的顶点缓冲区