有谁知道为什么会抛出这个错误?
当我使用VBO
?
glEnableVertexAttribArray
具有约束力
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);
}
答案 0 :(得分:0)
(我从来没有在Java上使用过OpenGL,所以我会使用C / C ++代码,但我希望它会很好用)
您不创建或绑定顶点缓冲区对象。
首先,使用glGenBuffers
创建一个缓冲区,如下所示:
GLuint bufferID;
glGenBuffers(1, &bufferID);
这会分配一个句柄并将其存储在bufferID
。
然后,绑定缓冲区:
glBindBuffers(GL_ARRAY_BUFFER, bufferID);
这使它成为"当前"缓冲区使用。
接下来,用数据填充缓冲区。假设vertices
是一个存储顶点坐标的数组,采用平面格式,每个顶点有三个浮点数:
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);
这实际上将数据放入GPU内存中。
然后启用属性数组并设置指针:
glEnableVertexAttribArray(mPositionHandle);
glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, 0, 0, 0);
这将使vertices
中的数据可用于mPositionHandle
的顶点属性位置下的着色器程序。
glVertexAttribPointer
的倒数第二个参数是stride
。在此示例中,它是0
,因为缓冲区仅包含顶点位置数据。如果要将顶点位置数据和颜色数据打包在同一缓冲区中,请执行以下操作:
v1.positionX v1.positionY v1.positionZ v1.colorR v1.colorG v1.colorB
v2.positionX ...
您需要使用非零stride
。 stride
指定一个属性与下一个属性之间的偏移量;在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);
最后一个参数是第一个属性的偏移量 - 第一个颜色属性在第三个浮动之后开始。
其他考虑因素:
答案 1 :(得分:0)
glVertexAttribPointer()
指定应使用指定的参数从当前绑定的顶点缓冲区中提取属性的数据。所以你需要打电话:
gl.glBindBuffer(GL_VERTEX_ARRAY, ...);
之前您致电glVertexAttribPointer()
。
glEnableVertexAttribArray()
指定应将数组用于顶点属性。否则,使用通过glVertexAttrib4f()
等调用指定的常量值。但它没有指定数组在缓冲区中。更重要的是,除非您绑定特定缓冲区,否则glVertexAttribPointer()
无法知道哪个缓冲区用于该属性。