I'm trying to read a memory-mapped file containing vertices and elements for rendering in OpenGL. The file loads correctly into an iPhone app, but I just can't get my head around how to do the same in Android. I've been fighting with ByteBuffer, FloatBuffer and IntBuffer, and one aspect of their behaviour baffles me.
The following code tries to read a length, set up a FloatBuffer for vertex data, read another开发者_Go百科 length that comes after the vertex data, and set up a ShortBuffer for element data.
int lenVerts = data.asIntBuffer().get();
data.position(data.position() + 4);
verts = data.asFloatBuffer();
data.position(data.position() + lenVerts);
IntBuffer ib = data.asIntBuffer();
int lenElems = ib.get();
data.position(data.position() + 4);
elems = data.asShortBuffer();
data.position(data.position() + lenElems);
Based on my interpretation of the docs, the asIntBuffer
call should return a buffer to the bytes starting at the current position, all the way to the end of the buffer. In other words, it should ignore the vertex data that I've skipped over by calling data.position(data.position() + lenVerts)
.
The problem is that it doesn't seem to do this. Regardless of what value I pass to data.position(...)
, the call to asIntBuffer
always returns a buffer to the entire underlying ByteBuffer. This is doubly-confirmed by noting that lenVerts == lenElems
(i.e., the same value is read twice, even though the sizes of the vertex and element data differ) and also that data.capacity() == 4*ib.capacity()
(i.e., the ByteBuffer has four times as many bytes as the IntBuffer has integers).
Am I doing something wrong? Have I interpreted the docs incorrectly?
How do I create an XxxBuffer that is backed by just a portion of the underlying ByteBuffer?
I just spent several hours with this problem until noticing that Buffer.position() is ignored by other methods which use the buffer as an arguement. My workaround is to create a new buffer which holds just the bytes required:
int pos = 100;
Buffer myBuffer; // old buffer containing ALL data
byte[] tmpBuf = new byte[myBuffer.capacity()-pos];
myBuffer.position(pos);
myBuffer.get(tmpBuf);
// Create new buffer:
Buffer fixedBuffer = ByteBuffer.wrap(tmpBuf); // new buffer containing only required data
精彩评论