Java FloatBuffer大小错误OpenGL

时间:2012-03-02 23:20:14

标签: java opengl lwjgl light floatbuffer

使用LWJGL实现OpenGL,并尝试使用照明功能。这需要创建FloatBuffers以传递给OpenGL。相关代码如下:

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

我对glMaterial的第一次调用给出了以下错误:

线程“main”中的异常java.lang.IllegalArgumentException:剩余缓冲区元素的数量为0,必须至少为4.因为最多可以返回4个元素,所以需要一个至少包含4个元素的缓冲区,而不管实际返回的元素数

不太确定我在这里做错了什么,似乎是创建FloatBuffer的问题。

3 个答案:

答案 0 :(得分:1)

在put()之后翻转()缓冲区,或者使用FloatBuffer.wrap(),这也可以节省一些代码行。或者它可能需要另一个 4个插槽,因此分配8个元素。

答案 1 :(得分:1)

该解决方案最终需要另一个特定于LWJGL(BufferUtils.createFloatBuffer)的函数调用,以及flip()方法。以下正确初始化缓冲区

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

答案 2 :(得分:0)

将FloatBuffers与LWJGL一起使用的想法是本机代码可以直接使用缓冲区,为了使其正常工作,它们应该像这样使用,

//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

ByteOrder.nativeOrder()将确保您的系统是使用大端还是小端,它将从java正确传输到本机代码。 (见http://en.wikipedia.org/wiki/Endianness

LWJGL缓冲区util可能会为您执行此操作