Question

I am trying Rajawali library for Android to draw some basic 3d objects on the scene. There is a sample 2000 planes, which show how to render huge amount of vertexes very "cheaply" with one shader. I can pass array of vertexes to the shader and draw them.

I want to upgrade this sample and move some vertexes independently from each other.

I've tried glBufferSubData, but i cant change anything on the scene. The one way i've found is to change data and recreate buffer, but i hope there is a simpler way to only change the necessary data.

For example, I only want to change some positions from already created and binded buffer.

initialize positions

    float[] planePositions = new float[numVertices * 3];
    ....

create buffer

    mGeometry.createBuffer(mPlanePositionsBufferInfo, BufferType.FLOAT_BUFFER, mPlanePositions,     GLES20.GL_ARRAY_BUFFER);
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

set positions

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, planePosBufferHandle);
    GLES20.glEnableVertexAttribArray(maPlanePositionHandle);
    fix.android.opengl.GLES20.glVertexAttribPointer(maPlanePositionHandle, 3, GLES20.GL_FLOAT,
            false, 0, 0);   

and how can i modify position of, for example, the first vertex of the first plane ? (planePositions[0] = a;planePositions[1] = b; planePositions[1] = c... and now i have to pass this modified array to opengl but don't know how).

Was it helpful?

Solution

All you need to do is modify the buffer data then call mGeometry.changeBufferData() from the PlanesGalore class. I put the following code in an update method which is called during the onDrawFrame() event of my Renderer class.

for (int i = 0; i < vertices.length; i += 3) {
   mPlanePositions= mPlanePositions.put(i, mPlanePositions.get(i) - 0.01f);
}

mGeometry.changeBufferData(mCubePositionsBufferInfo, mPlanePositions, 0);

This is the best way I could find for accomplishing the movements. Additionally, I have proposed a change in this issue that would let you specify what part of the buffer changed which should provide increased performance.

EDIT

My change to the engine has been approved so you can now optimize this even further like so.

// 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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top