Java FloatBuffer size error OpenGL

4.8k views Asked by At

working with LWJGL's implementation of OpenGL, and trying to work with the lighting functions. This requires the creation of FloatBuffers to pass to OpenGL. Relevant code follows:

GL11.glClearColor(0,0,0,0);

float[] ambientLight={(float).3,(float).5,(float).8,1};
FloatBuffer ambientLightB = FloatBuffer.allocate(4);
ambientLightB.put(ambientLight);

float[] diffuseLight={(float).25,(float).25,(float).25,1};
FloatBuffer diffuseLightB = FloatBuffer.allocate(4);
diffuseLightB.put(diffuseLight);

float[] lightPosition={0,0,1,1};
FloatBuffer lightPositionB = FloatBuffer.allocate(4);
lightPositionB.put(lightPosition);

float[] matAmbient={1,1,1,1};
FloatBuffer matAmbientB = FloatBuffer.allocate(4);
matAmbientB.put(matAmbient);

float[] matDiff={1,1,1,1};
FloatBuffer matDiffB = FloatBuffer.allocate(4);
matDiffB.put(matDiff);

GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glFrontFace(GL11.GL_CCW);
GL11.glEnable(GL11.GL_LIGHTING);

GL11.glMaterial(GL11.GL_FRONT,GL11.GL_AMBIENT,matAmbientB);
GL11.glMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE,matDiffB);
GL11.glLight(GL11.GL_LIGHT0,GL11.GL_AMBIENT,ambientLightB);
GL11.glLight(GL11.GL_LIGHT0,GL11.GL_DIFFUSE,diffuseLightB);
GL11.glLight(GL11.GL_LIGHT0,GL11.GL_POSITION,lightPositionB);
GL11.glEnable(GL11.GL_LIGHT0);

The first call I make to glMaterial gives the following error:

Exception in thread "main" java.lang.IllegalArgumentException: Number of remaining buffer elements is 0, must be at least 4. Because at most 4 elements can be returned, a buffer with at least 4 elements is required, regardless of actual returned element count

Not quite sure what I'm doing wrong here, seems to be a problem in the creation of the FloatBuffer.

3

There are 3 answers

0
sol_var On BEST ANSWER

The solution ended up requiring another function call specific to LWJGL (BufferUtils.createFloatBuffer), as well as the flip() method. The following correctly initialized the buffer

float[] matAmbient={1,1,1,1};
FloatBuffer matAmbientB = BufferUtils.createFloatBuffer(4);
matAmbientB.put(matAmbient);
matAmbientB.flip();
0
Istinra On

The idea of using FloatBuffers with LWJGL is so native code can use there buffers directly, in order for this to work correctly they should be used like so,

//Create a directly allocated buffer in bytes (16 = 4 Floats * size of float in bytes)
ByteBuffer bytes = ByteBuffer.allocateDirect(16).order(ByteOrder.nativeOrder());
FloatBuffer fb = bytes.asFloatBuffer();
fb.put(...);
fb.rewind(); //Moves the internal buffer pointer back to the start for the next thing to read from it

The ByteOrder.nativeOrder() will ensure that whether your system uses big or little endian it will be transferred correctly from java to native code. (See http://en.wikipedia.org/wiki/Endianness)

The LWJGL buffer util likely does this for you

4
user207421 On

Flip() the buffer after the put(), or use FloatBuffer.wrap(), which would also save you some lines of code. Or maybe it needs another 4 slots, so allocate 8 elements.