Adam
Adam

Reputation: 2570

Using a single ByteBuffer with multiple arrays in OpenGL

In my application, I'm having to draw multiple elements with OpenGL, some are Triangles and others are Line Strips. I'm putting my vertices into multiple float[] and my indices into multiple short[] whenever I am to draw a new shape. I also have to create a new FloatBuffer, ShortBuffer and ByteBuffer for each new array in order to make it work.

How could I more efficiently draw the multiple elements? I was thinking of putting all of the vertices into a single float[] and creating a new short[] for each element to remove excess arrays, but is it possible to use one FloatBuffer, ShortBuffer and put all of the arrays into a single ByteBuffer such as this:

float[] vertices = { -3, -3, -3, 2, 3, 0, 2, -1, 0, 0, 5, 2, 3, 1 };
short[] indItemA = { 0, 1, 2, 0, 2, 3 };
short[] indItemB = { 4, 5, 6 };

FloatBuffer fBuff;
ShortBuffer sBuff;

ByteBuffer bBuff = ByteBuffer.allocateDirect(vertices.length * 4);
fbBuff.order(ByteOrder.nativeOrder());

fBuff = bBuff.asFloatBuffer();
fBuff.put(vertices);
fBuff.position(0);

sBuff = bBuff.asShortBuffer();
sBuff.put(indItemA);
sBuff.position(0);

sBuff.put(indItemB);
sBuff.position(0);

Upvotes: 0

Views: 1285

Answers (1)

Kane Wallmann
Kane Wallmann

Reputation: 2322

glBufferData sends the data from the buffer to the graphics card's memory. You can do whatever you want with the ByteBuffer after that call and it wont effect the data already sent.

Therefore if your aim is to reduce the number of ByteBuffers you create, you could just create one large ByteBuffer that is used for everything. Just reset the pointer of the buffer, write the data, send it to the graphics card and repeat.

// Do this once
ByteBuffer bBuff = ByteBuffer.allocateDirect( someBigNumber );
bBuff.order(ByteOrder.nativeOrder());
FloatBuffer fBuff = bBuff.asFloatBuffer();
ShortBuffer sBuff = bBuff.asFloatBuffer();

// Do this for each shape
fBuff.position(0);
fBuff.put(vertices);
fBuff.position(0);

glBindBuffer( GL_ARRAY_BUFFER, vertexbuffer );
glBufferData( GL_ARRAY_BUFFER, vertices.length * 4, fBuff, GL_STATIC_DRAW );

sBuff.position( 0 );
sBuff.put( indices );
sBuff.position( 0 );

glBindBuffer( GL_ARRAY_BUFFER, indexbuffer );
glBufferData( GL_ARRAY_BUFFER, indices.length * 2, sBuff, GL_STATIC_DRAW );

If your vertex and index data is static, you could just put the vertex data for every shape into one buffer object and all the index data into another then use the offset parameter of glVertexPointer and glIndexPointer to specify where in the buffer object the data begins.

It sounds like you generate custom shapes at runtime though, so you could just re-use the ByteBuffer and store each shape in a separate buffer object like the sample above.

Upvotes: 1

Related Questions