【问题标题】:How to change the content of vertexbuffer used in glDrawArrays method in opengles如何更改opengles中glDrawArrays方法中使用的顶点缓冲区的内容
【发布时间】:2014-09-25 08:34:47
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: opengl-es 3d


    【解决方案1】:

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

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

    【讨论】:

    • 可能你是对的,但我无法做到。不知道在使用glbuffersubdata之前是否需要对glgenbuffers和glbindbuffer做一些准备?
    • @emre:不,我不记得使用glbufferSubData做了任何不寻常/特别的事情。
    • 我做 smt 类似于这个(如果看起来很清楚) public void draw(GL11 gl) { 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);顶点[0] += 5; gl.glBufferSubData(GL11.GL_ARRAY_BUFFER, 0, 4, vertexBuffer); } 我会继续努力并告知我是否可以管理
    • @JerryCoffin 您没有指出glBufferSubData 仅在一小部分缓冲区需要更新时才可取。否则,应使用glBufferData。来源:opengl.org/wiki/…
    • @b1nary.atr0phy:至少在我阅读时,这就是问题的重点。他已经提交了数据,正在修改一些具体的部分,并希望避免重新发送所有数据。
    【解决方案2】:

    我发现我的大部分问题都与 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() 方法。 vertexBuffer 是一个 FloatBuffer 对象。你可以从这个 sn-p 中得到我的想法。

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

    如果有误导的地方可以指正..

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我不明白这将如何工作。我想改变每个顶点的内容,而不是在数组之间切换。
      • 没有理由这样做。如果他只有一个 VBO 有问题,那么告诉他使用多个 VBO 并不能解决任何问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多