【问题标题】:OpenGLException: Cannot use offsets when Array Buffer Object is disabled.. On a line after calling glEnable(GL_ARRAY_BUFFER)?OpenGLException:禁用数组缓冲区对象时无法使用偏移量。在调用glEnable(GL_ARRAY_BUFFER)后一行?
【发布时间】:2014-12-17 12:10:32
【问题描述】:

我不断收到此异常:

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)

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

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

如您所见,在 glVertexPointer 调用之前的两行(错误所在的那一行),那么我显然是在启用数组缓冲区!

这里有什么问题?

【问题讨论】:

    标签: java opengl lwjgl


    【解决方案1】:

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

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

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


    LWJGL 的错误信息措辞不当:

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

    错误消息实际上意味着您在调用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 中有一个替代形式的glVertexPointer 函数可以获取未存储在缓冲区对象中的内存,您可以在其中传递java.nio.Buffer 的特化。当您没有绑定顶点缓冲区并且 是错误消息真正告诉您的内容时,这是您应该使用的形式。


    这解释了您看到的错误消息的实际含义,而不是其原因。

    由于某种原因,vboVertexHandle 似乎为 0 或某些值未在您的应用程序中使用 glGenBuffers (...) 生成。显示初始化 VBO 的代码会很有帮助。

    【讨论】:

    • 这就是我希望得到 200 个问题的赏金的答复!非常感谢您的回答!我现在正在使用一种新的对象渲染技术,它不需要这两个变量,这意味着这些变量永远不会被初始化。
    【解决方案2】:

    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 起,此功能已被弃用。如果坚持使用这个旧的 OpenGL 版本没有任何限制,那么最好从现代 OpenGL 开始(尤其是因为您已经在使用 vbos)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-19
      • 2011-09-19
      • 1970-01-01
      • 2012-06-23
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多