How do I properly update a vertex array in OpenGL Es 2.0?

无人久伴 提交于 2019-12-03 05:56:49

Misfire #1

I found an answer here which pointed me to using glSubBufferData for parking data in the array, and to use glBufferData only for the initial allocation. Ultimately this did not work (if the vb was too big, only the first 3 elements would be updated),

So,

glBufferData( glBufferData(
  GL_ARRAY_BUFFER, //Specifies the target buffer object.
  rawDynamicData.size() * sizeof( VertexType ),
  0, // NO INITIAL DATA
  GL_DYNAMIC_DRAW  // I plan to update the data every frame
) ;  CHECK_GL ; 

Then for the first and subsequent updates:

// Update the whole buffer
glBufferSubData(GL_ARRAY_BUFFER, 0,
  rawDynamicData.size()*sizeof(VertexType), &rawDynamicData[0]) ;

That seemed to work.

Seemed. But it didn't.

The only thing I could do to make it work was quit using vertex buffers and use client memory vertex arrays.

This looks as follows:

// do all your vertex attrib/glVertexAttrib enable commands:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexPC), &debugPoints->data[0].pos.x) ;
CHECK_GL ;
glEnableVertexAttribArray(0);  CHECK_GL ;

// ..do glVertexAttrib* for all attributes you have..

// then just flush your draw command
glDrawArrays(GL_POINTS, 0, debugPoints->data.size());  

So in short, I have found that using vertex buffers for dynamic data is either challenging or not supported.

Andy

For Android users out there, I just confirmed that it's possible to have deformable geometry using vertex attribute arrays in OpenGL ES 2.0 on Android, in a little test. The annoying thing is you don't get to pass a pointer to your own array, instead you have to use a FloatBuffer (or similar type). Sample code:

Initialization:

    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(
            // (number of coordinate values * 4 bytes per float)
            coords.length * 4);
    // use the device hardware's native byte order
    bb.order(ByteOrder.nativeOrder());

    // create a floating point buffer from the ByteBuffer
    vertexBuffer = bb.asFloatBuffer();
    // add the coordinates to the FloatBuffer
    vertexBuffer.put(coords);
    // set the buffer to read the first coordinate
    vertexBuffer.position(0);

Drawing Code:

    // get handle to vertex shader's vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
    checkGlError("glGetAttribLocation");

    // Enable a handle to the triangle vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    checkGlError("glEnableVertexAttribArray");

    float newValue = (float) Math.sin((float) (frame++) / 1000) + 1;
    System.out.println(newValue);

    vertexBuffer.put(0, newValue);

    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, VERTEX_STRIDE, vertexBuffer);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!