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

时间:2014-12-17 12:10:33

标签: java opengl lwjgl

我一直得到这个例外:

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调用之前的两行(错误所在的那一行),然后我显然启用了数组缓冲区!

这里有什么问题?

2 个答案:

答案 0 :(得分:5)

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

您需要确保glVertexPointer命令使用绑定到GL_ARRAY_BUFFER的任何内容(“数组缓冲区对象”)作为其内存源(从OpenGL 1.5开始)。

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


LWJGL的错误信息措辞不足:

  

线程“main”中的异常 org.lwjgl.opengl.OpenGLException 禁用数组缓冲区对象时无法使用偏移量。

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

还记得当你有glVertexPointer的约束时,我将GL_ARRAY_BUFFER的最后一个参数描述为偏移量吗?由于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中有一种glVertexPointer函数的替代形式,它可以将未存储在缓冲区对象中的内存传递给java.nio.Buffer的特化。这是您没有绑定顶点缓冲区时要使用的表单, 是错误消息实际告诉您的内容。


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

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

答案 1 :(得分:1)

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核心配置文件以来,不推荐使用此功能。如果坚持这个旧的OpenGL版本没有限制,那么从现代OpenGL开始是个好主意(特别是因为你已经在使用vbos)。