java - 尝试使用 VBO "array vertex_buffer_object must be disabled to call this method"时出错

标签 java opengl language-agnostic jogl vbo

编辑

我已经有效地重写了这个问题以大大提高它的质量 - 如果必须的话请查看修订日志

当我尝试创建顶点缓冲区时,我已将问题缩小到程序的初始化阶段。我目前使用的代码是...

vaoID = new int[1];
gl.glGenVertexArrays(1, vaoID, 0);
gl.glBindVertexArray(vaoID[0]);
vboID = new int[1];
gl.glGenBuffers(1, vboID, 0);
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboID[0]);
FloatBuffer vData = FloatBuffer.allocate(vertexData.length);
vData.put(vertexData);
vData.rewind();
gl.glBufferData(GL4.GL_ARRAY_BUFFER, vData.capacity() * (Float.SIZE / 8), vData, GL4.GL_STATIC_DRAW);
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, 0); // With out this line my code throws the exception
gl.glEnableVertexAttribArray(0);
gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT, false, 0, null); // This is the line where the exception is thrown
gl.glBindVertexArray(0);

所以是的,目前我的代码能够运行而不会崩溃,但它一定是在某些地方有错误,因为我无法让它呈现。为了缓冲索引数据,我使用了这段代码,它在运行时确实成功完成了

gl.glGenBuffers(1, bufferIDs, 0);
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, bufferIDs[0]);
ShortBuffer iData = ShortBuffer.allocate(indexData.length);
iData.put(indexData);
iData.rewind();
indexCount = iData.capacity();
gl.glBufferData(GL4.GL_ELEMENT_ARRAY_BUFFER, indexCount * (Short.SIZE / 8), iData, GL4.GL_STATIC_DRAW);
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, 0);

然后在绘图方面,我执行以下步骤,我认为这并不重要,因为我确信我仍然没有在第一时间正确缓冲

// first I bind my VAO
gl.glBindVertexArray(vaoID[0]);
// then bind, draw, unbind the index buffer
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, bufferIDs[0]);
gl.glDrawElements(GL4.GL_POINT, indexCount, GL4.GL_UNSIGNED_SHORT, 0);
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, 0);
// finally I unbind the VAO
gl.glBindVertexArray(0);

我相当确定这是渲染缓冲几何体的正确过程。我已经通过使用一些即时绘图命令确认我的着色器代码是正确和有效的,所以我有完整的管道,看起来我没有向其中输入数据。作为一个兴趣点,我还尝试编辑我的顶点着色器以将所有点设置为 (0,0,0,1),这样如果传入任何点,我应该看到它们,但这没有用,我意思是我一开始就没有将数据传递到我的着色器中。

最佳答案

glVertexAttribPointer 有两种操作模式。如果没有 VBO 绑定(bind),它会将指向数据的指针作为最后一个参数。如果存在 VBO 绑定(bind),则最后一个参数是缓冲区中的整数偏移量。在 C 中,您无论如何都必须将此整数转换为指针,但如果存在 VBO 绑定(bind),则不会将其视为指针。

在JOGL中,这两种模式是通过两个重载实现的:one that takes a Buffer (而不是指针)和 one that takes a long (而不是将偏移量转换为指针)。

如果您使用第一个带有 VBO 绑定(bind)的模式,它会抛出一个错误,因为这是仅在没有 VBO 绑定(bind)的情况下才有效的模式。如果您取消绑定(bind)您的 VBO 并将 null 传递给最后一个参数,您仍在调用第一个重载:null 可以匹配 Buffer 参数,但不是 long。 JOGL 似乎没有对这种情况进行类似的验证。这可能会将其视为偏移量 0,但它还会将 0 存储为 VBO 以查找数据。也就是说,根本没有 VBO。

您需要做的是,使用您的原始代码,即使用 VBO 绑定(bind),调用采用偏移量的重载:

//pass a long instead of a null Buffer
gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT, false, 0, 0L);

还有另一个问题是不让任何东西渲染。您正在将 GL4.GL_POINT 传递给 glDrawElements。那不是有效的汇编模式。我不知道它的用途(我的 OpenGL 4 知识让我失望)。点集合模式的常量被命名为 GL_POINTS:

gl.glDrawElements(GL.GL_POINTS, indexCount, GL4.GL_UNSIGNED_SHORT, 0);

关于java - 尝试使用 VBO "array vertex_buffer_object must be disabled to call this method"时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8398581/

相关文章:

c# - 构造函数中的代码是否添加到子类构造函数中的代码?

java - 在mockito中模拟参数化 map

c++ - glut32.dll 丢失错误。一种在非管理访问机器上摆脱它的方法

java - 如何使用 Xpath 在 XML 树的节点后检索节点?

opengl - 为什么 GL_MAX_ARRAY_TEXTURE_LAYERS 比 GL_MAX_TEXTURE_SIZE 小很多?

java - 尝试用鼠标移动四边形/正方形 - LWJGL

language-agnostic - 更改 Active Directory 用户密码

algorithm - 什么是模拟和比较旅程的简单系统?

java - 使用可变参数自动装箱

java - TestNG报告定制