OpenGL ES 2 on Android: how to use VBOs

后端 未结 1 1605
余生分开走
余生分开走 2021-01-23 05:42

this question is similar to something I asked here Android OpenGL ES 2: Introduction to VBOs however I tried multiple aproaches since then and I still haven\'t succeeded, so I

相关标签:
1条回答
  • 2021-01-23 06:40

    The transition to the VBO can be a bit strange due to the data pointer usage.

    From a quick inspection your main issue is in

    GLES20.glVertexAttribPointer(
                mPositionHandle, COORDS_PER_VERTEX,
                GLES20.GL_FLOAT, false,
                vertexStride, vertexBuffer);
    

    as this should be

     GLES20.glVertexAttribPointer(
                mPositionHandle, COORDS_PER_VERTEX,
                GLES20.GL_FLOAT, false,
                vertexStride, 0);
    

    So about this buffers: A VBO is a custom buffer on the GPU generally used and optimised to store the vertex data directly to the GPU. The performance you gain by doing so is that the vertex data do not need to be copied to the GPU on every draw call.

    These buffers are still custom and on generating them all you need to set is their size. I see you are using factor *4 on the vertex count assuming a float value has a size of 4 bytes, this is not the best idea since that might not always be true. If possible always try to use some form of "sizeOf". Anyway your buffer is created correctly and data are sent to it.

    After the data are sent to the VBO you should keep them there until you need them. That means you generally create a single VBO per unique object (a square for instance) and then just hold its ID. Whenever you wish to draw it you just simply bind the buffer and draw as you did. In other words the buffer should never be created in the draw method. What you did there is a memory leak as well since you are responsible for releasing the buffer by calling delete once the buffer is no longer needed.

    So about your pointer issue on glVertexAttribPointer: There are 2 ways to use this method. Without the VBO the last parameter is the pointer to the data on your CPU. With the VBO you need to set that as a relative pointer inside the VBO. That means when VBO is bound the beginning of the buffer would be NULL (0), you might even need to typecast that value. For other positions in the buffer you need to manually calculate them.

    And the code you posted specifically:

        // First, generate as many buffers as we need.
        // This will give us the OpenGL handles for these buffers.
        final int buffer[] = new int[1];
        GLES20.glGenBuffers(1, buffer, 0);
    
        //these I don't fully understand
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffer[0]);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,vertexBuffer.capacity() *    4,vertexBuffer,GLES20.GL_STATIC_DRAW);
    

    This all goes into some load time and have a reference to the buffer[] beside that you should add GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); what this call does is unbind the buffer. This is not something you NEED to do but it is best that you do so you have no confusion what buffer is bound if any.

    Before the glVertexAttribPointer is called you need to bind your buffer. Then set the last parameter as described above.

    After you are done using this buffer (done drawing) you should (again not necessary) unbind the buffer.

    0 讨论(0)
提交回复
热议问题