OpenGLException:禁用数组缓冲区对象时不能使用偏移量。在调用glEnable(GL_ARRAY_BUFFER)后的一行上?

我一直得到这个例外:

Exception in thread "main" org.lwjgl.opengl.OpenGLException: Cannot use offsets when Array Buffer Object is disabled at org.lwjgl.opengl.GLChecks.ensureArrayVBOenabled(GLChecks.java:93) at org.lwjgl.opengl.GL11.glVertexPointer(GL11.java:2680) at Joehot200.TerrainDemo.render(TerrainDemo.java:2074) at Joehot200.TerrainDemo.enterGameLoop(TerrainDemo.java:3266) at Joehot200.TerrainDemo.startGame(TerrainDemo.java:3490) at StartScreenExperiments.Test2.resartTDemo(Test2.java:55) at StartScreenExperiments.Test2.main(Test2.java:41) 

但是,数组缓冲区对象IS已启用!

 glEnableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle); glVertexPointer(3, GL_FLOAT, 0, 0L); 

正如你所看到的,在glVertexPointer调用之前的两行(错误所在的那一行),然后我显然启用了数组缓冲区!

这有什么不对?

顶点缓冲区不是你启用或禁用的东西–LWJGL会误导你。

您需要确保glVertexPointer命令使用绑定到GL_ARRAY_BUFFER (“Array Buffer Object”)的任何内容作为其内存源(从OpenGL 1.5开始)。

在某些版本的OpenGL(1.5-3.0和3.1+兼容性)中,如果你有0绑定到GL_ARRAY_BUFFER ,那么glVertexPointer的最后一个参数是指向 程序内存(客户端内存)的实际指针 ,而不是GPU内存的偏移量 (服务器内存) )。 Core OpenGL 3.1+甚至不支持客户端顶点存储,因此最后一个参数始终是偏移量。


LWJGL的错误信息措辞不足:

线程“main”中的exceptionorg.lwjgl.opengl.OpenGLException禁用Array Buffer Object时不能使用偏移量。

错误消息实际上意味着当您调用glVertexPointer (...)时,您有0绑定到GL_ARRAY_BUFFER 。 只要没有绑定到GL_ARRAY_BUFFER LWJGL显然会认为数组缓冲区对象“已禁用” 。 这不是不合理,但它确实让你相信这是一个可以使用glEnableglDisable启用或禁用的状态; 它不是。

还记得当你有一些绑定到GL_ARRAY_BUFFER东西时,我如何将glVertexPointer的最后一个参数描述为一个偏移量 ? 由于LWJGL是基于Java的,因此无法将任意内存地址作为整数传递。 传递给glVertexPointer (...)的整数值必须是当前绑定的顶点缓冲区内存的偏移量。

客户端顶点规范(核心GL 3.1+不支持)

 void glVertexPointer(int size, int type, int stride, java.nio.ByteBuffer pointer); 

服务器端顶点规范(在GL_ARRAY_BUFFER占用偏移量

 void glVertexPointer(int size, int type, int stride, long pointer_buffer_offset); 

正如您所看到的,LWJGL中有一种替代forms的glVertexPointer函数,它可以将未存储在缓冲区对象中的内存传递给java.nio.Buffer的特殊化。 当您没有绑定顶点缓冲区时,这是您应该使用的表单, 是错误消息实际告诉您的内容。


这解释了您看到的错误消息实际上意味着什么,但不是它的原因。

出于某种原因, vboVertexHandle似乎为0或某些值未在您的应用程序中使用glGenBuffers (...)生成。 显示初始化VBO的代码将是helfpul。

GL_ARRAY_BUFFER不是glEnable允许的值之一。 如果要将顶点缓冲区对象附加到顶点指针,则必须使用glEnableClientState方法启用它:

 glEnableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle); glVertexPointer(3, GL_FLOAT, 0, 0L); //This is line 2074 of the TerrainDemo class. 

附注:自OpenGL 3 Core Profile以来,不推荐使用此function。 如果坚持这个旧的OpenGL版本没有限制,那么从现代OpenGL开始是个好主意(特别是因为你已经在使用vbos)。