0

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 Answers 3

1

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.

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

4 Comments

I don't see any flip() method in the java documentation of the class... Wrap doesn't work, that gives me an error saying I need a direct Buffer... Shouldn't need 8 buffers, the equivalent function call in C takes a size 4 array
Flip was in the super class, gave the same direct buffer error
@sol_var (1) Buffer.flip() does exist, look again. It is inherited. (2) If you really need a direct buffer, allocate() shouldn't work either, you would have to use allocateDirect(). Something wrong here. (3) There is no C equivalent of FloatBuffer. I think you're going to have to look again at the documentation for the package you're using.
EJP, thank you for your information, it was very helpful. Just to clarify, by C equivalent, I meant the equivalent of the function call, not the equivalent of the FloatBuffer. In C the function glMaterialfv would be called instead for the exact same effect, and its third parameter is a pointer to a float array of size four instead of a FloatBuffer of size 4.
1

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();

Comments

0

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

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.