Opengl 数组顶点缓冲区对象必须绑定才能调用此方法
有人知道为什么会抛出此错误吗 当我使用Opengl 数组顶点缓冲区对象必须绑定才能调用此方法,opengl,jogl,Opengl,Jogl,有人知道为什么会抛出此错误吗 当我使用GlenableVertexAttributeArray时,我以为我正在绑定到VBO com.jogamp.opengl.GLException: array vertex_buffer_object must be bound to call this method at jogamp.opengl.gl4.GL4bcImpl.checkBufferObject(GL4bcImpl.java:39146) at jogamp.opengl.
GlenableVertexAttributeArray
时,我以为我正在绑定到VBO
com.jogamp.opengl.GLException: array vertex_buffer_object must be bound to call this method
at jogamp.opengl.gl4.GL4bcImpl.checkBufferObject(GL4bcImpl.java:39146)
at jogamp.opengl.gl4.GL4bcImpl.checkArrayVBOBound(GL4bcImpl.java:39178)
at jogamp.opengl.gl4.GL4bcImpl.glVertexAttribPointer(GL4bcImpl.java:37371)
这是我要画的代码
public void draw(final GL2ES2 gl, Matrix4f projectionMatrix, Matrix4f viewMatrix, int shaderProgram, final Vec3 position, final float angle) {
// enable glsl
gl.glUseProgram(shaderProgram);
// enable alpha
gl.glEnable(GL2ES2.GL_BLEND);
gl.glBlendFunc(GL2ES2.GL_SRC_ALPHA, GL2ES2.GL_ONE_MINUS_SRC_ALPHA);
// get handle to glsl variables
mPositionHandle = gl.glGetAttribLocation(shaderProgram, "vPosition");
setmColorHandle(gl.glGetUniformLocation(shaderProgram, "vColor"));
mProj = gl.glGetUniformLocation(shaderProgram, "mProj");
mView = gl.glGetUniformLocation(shaderProgram, "mView");
mModel = gl.glGetUniformLocation(shaderProgram, "mModel");
// perform translations
getModelMatrix().loadIdentity();
getModelMatrix().translate(new Vec3(position.x * 60.0f, position.y * 60.0f, position.z * 60.0f));
getModelMatrix().rotate(angle, 0, 0, 1);
// set glsl variables
gl.glUniform4fv(getmColorHandle(), 1, getColorArray(), 0);
gl.glUniformMatrix4fv(mProj, 1, true, projectionMatrix.getValues(), 0);
gl.glUniformMatrix4fv(mView, 1, true, viewMatrix.getValues(), 0);
gl.glUniformMatrix4fv(mModel, 1, true, getModelMatrix().getValues(), 0);
// Enable a handle to the triangle vertices
gl.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
gl.glVertexAttribPointer(
getmPositionHandle(),
COORDS_PER_VERTEX,
GL2ES2.GL_FLOAT,
false,
vertexStride, 0L); // This is the line that throws error
// Draw the square
gl.glDrawElements(
GL2ES2.GL_TRIANGLES,
drawOrder.length,
GL2ES2.GL_UNSIGNED_SHORT,
0L);
// Disable vertex array
gl.glDisableVertexAttribArray(mPositionHandle);
gl.glDisable(GL2ES2.GL_BLEND);
gl.glUseProgram(0);
}
(我从未将OpenGL与Java一起使用过,所以我将使用C/C++代码,但我希望它能得到很好的理解)
不创建或绑定顶点缓冲区对象
首先,使用glGenBuffers
创建缓冲区,如下所示:
GLuint bufferID;
glGenBuffers(1, &bufferID);
v1.positionX v1.positionY v1.positionZ v1.colorR v1.colorG v1.colorB
v2.positionX ...
这将分配句柄并将其存储在bufferID
中
然后,绑定缓冲区:
glBindBuffers(GL_ARRAY_BUFFER, bufferID);
这使得它成为要使用的“当前”缓冲区
接下来,用数据填充缓冲区。假设顶点
是以平面格式存储顶点坐标的数组,每个顶点有三个浮点数:
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);
这实际上会将数据放入GPU内存中
然后启用属性数组并设置指针:
glEnableVertexAttribArray(mPositionHandle);
glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, 0, 0, 0);
这将使顶点中的数据可用于mPositionHandle
的顶点属性位置下的着色器程序
glvertexattributepointer
的倒数第二个参数是stride
。在本例中,它是0
,因为缓冲区仅包含顶点位置数据。如果要将顶点位置数据和颜色数据打包到同一缓冲区中,如下所示:
GLuint bufferID;
glGenBuffers(1, &bufferID);
v1.positionX v1.positionY v1.positionZ v1.colorR v1.colorG v1.colorB
v2.positionX ...
您需要使用非零的步幅
<代码>步幅
指定同一类型的一个属性和下一个属性之间的偏移量;如果跨步为0
,则假定它们是紧密排列的。在这种情况下,您需要将跨距设置为sizeof(GLfloat)*6
,以便在读取一个顶点的位置后,它将跳过颜色数据以到达下一个顶点,对于颜色也是如此
// (create, bind and fill vertex buffer here)
glEnableVertexAttribArray(location_handle_of_position_data);
glVertexAttribPointer(location_handle_of_position_data, 3, GL_FLOAT, 0, sizeof(GLfloat) * 6, 0);
glEnableVertexAttribArray(location_handle_of_color_data);
glVertexAttribPointer(location_handle_of_color_data, 3, GL_FLOAT, 0, sizeof(GLfloat) * 6, sizeof(GLfloat) * 3);
最后一个参数是第一个属性的偏移量-第一个颜色属性在第三个浮点之后开始
其他考虑:
- 您应该研究如何使用顶点数组对象。如果没有它们,它可能会工作,也可能不会工作,但按照标准,它们是必需的,并且它们在任何情况下都会简化代码
- 为了简单起见,此示例代码以浮点形式存储颜色数据,但对于实际使用,最好使用字节
glvertexattributepointer()
指定应使用指定的参数从当前绑定的顶点缓冲区中提取属性的数据。所以你需要打电话:
gl.glBindBuffer(GL_VERTEX_ARRAY, ...);
在调用glvertexattributepointer()
之前
glEnableVertexAttribArray()
指定应将数组用于顶点属性。否则,将使用一个常量值,该常量值由调用指定,如glVertexAttrib4f()
。但是它没有指定数组在缓冲区中。更重要的是,除非绑定特定的缓冲区,否则glvertexattributepointer()
无法知道属性使用哪个缓冲区。我已经尝试glGenBuffers
,glBindBuffer
和glBufferData
之前的glEnableVertexAttribArray
但我得到的错误与原始错误非常相似<代码>元素顶点\u缓冲区\u对象必须绑定才能调用此方法@bobbyrne01尝试也绑定一个。有些实现不允许您在没有它的情况下做任何事情。