0

I'm removing some native C code from an Android app which used a memcpy to copy an array of floats into a FloatBuffer (because an old device I had was very slow at this).

My current code looks like this:

mfVertexBuffer.position(0);
mfColourBuffer.position(0);
mfSizeBuffer.position(0);
mfVertexBuffer.put(fvertices, 0, nCount*2);
mfColourBuffer.put(fcolours, 0, nCount*4);
mfSizeBuffer.put(fsizes, 0, nCount);

I've looked at the state of mfVertexBuffer and it looks like it's behaving; .position gets incremented sensibly, and the contents of the underlying buffer seem sensible. However, nothing is being rendered onscreen (by a later process).

I rewrote the above - changing nothing else in my app whatsoever - to the following:

int vs=0;
int vd=0;
int cs=0;
int cd=0;
int ss=0;
int sd=0;
for (int i = 0; i < nCount; i++) {
   mfVertexBuffer.put(vd++, fvertices[vs++]);
   mfVertexBuffer.put(vd++, fvertices[vs++]);
   mfColourBuffer.put(cd++, fcolours[cs++]);
   mfColourBuffer.put(cd++, fcolours[cs++]);
   mfColourBuffer.put(cd++, fcolours[cs++]);
   mfColourBuffer.put(cd++, fcolours[cs++]);
   mfSizeBuffer.put(sd++, fsizes[ss++]);
}

And it works perfectly. I don't understand this at all. How do the two pieces of code differ?

The FloatBuffers are set up like this:

mfVertexBuffer = miscHelpers.getFloatBuffer(4 * NUMBER_OF_PARTICLES * 2);
mfColourBuffer = miscHelpers.getFloatBuffer(4 * NUMBER_OF_PARTICLES * 4);
mfSizeBuffer = miscHelpers.getFloatBuffer(4 * NUMBER_OF_PARTICLES);

public static FloatBuffer getFloatBuffer(int size) {
   FloatBuffer fbRet;
   ByteBuffer myBB = ByteBuffer.allocateDirect(size);
   myBB.order(ByteOrder.nativeOrder());
   fbRet = myBB.asFloatBuffer();
   return fbRet;
}

fvertices etc are simple arrays of floats, the values of which do not change.

count is the number of particles to plot this round.

NUMBER_OF_PARTICLES is a compile time limit on the maximum number of particles which can be created, and is always more than or equal to count, so the first (non-working) code is doing more work, but behaves the same if I set NUMBER_OF_PARTICLES to the same value as count.

I'm using OpenGL 1.1, Android API 17 on a Galaxy S3 running 4.2.2 (Cyanogenmod 10.1.3).

1 Answer 1

2

When you pass a buffer to an OpenGL function, it will start reading at the current position.

The first form of put() you are using, where you pass in the whole array at once, increases the position by the number of floats written. The second form with the put(int index, float f) signature does not update the position, according to the documentation.

When using the first variation, you need to reset the position to the start after filling the buffer. There are a few calls you can choose from to do this:

buffer.position(0);
buffer.rewind();
buffer.flip();

flip() is the one most people seem to use, but the other options will work as well in your use case.

Sign up to request clarification or add additional context in comments.

3 Comments

Isn't that what I'm already doing (ie in the first line of my code)?
Well, yes, you're setting the position there. But then it gets updated by the put() calls. You need to reset the position to 0 after making the put() calls.
You're right. I was only thinking about my writes into the buffer; I didn't appreciate that OpenGL uses the position as it reads it whilst rendering. Many thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.