我正在使用lwjgl 3作为OpenGL的Java包装器,我正在试图弄清楚如何使用Vertex Array Objects渲染东西。我无法在网上找到任何显示如何使用具有着色器属性并使用元素数组缓冲区的VAO的示例。
根据this vao tutorial,我需要做这样的事情:
// Create a new Vertex Array Object in memory and select it (bind)
// A VAO can have up to 16 attributes (VBO's) assigned to it by default
vaoId = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoId);
// Create a new Vertex Buffer Object in memory and select it (bind)
// A VBO is a collection of Vectors which in this case resemble the location of each vertex.
vboId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
// Put the VBO in the attributes list at index 0
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
// Deselect (bind to 0) the VBO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
// Deselect (bind to 0) the VAO
GL30.glBindVertexArray(0);
但是,我不明白如何使本教程适应我的项目,因为我使用glVertexAttribPointer
来处理着色器中的字段。这些字段具有在编译着色器时分配给它们的id。在上面的示例中,他们似乎可以使用默认字段0
。但是,我检查过,posAttrib
位于0
字段中。
我应该如何将VBO与我的VAO相关联?
private int createVao(int shaderProgramId, FloatBuffer vertices, IntBuffer order) {
int floatSize = 4;
int stride = 7 * floatSize;
int vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
int vboId = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
int eboId = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eboId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, order, GL_STATIC_DRAW);
int posAttrib = shaderProgramService.getAttribute(shaderProgramId, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, false, stride, 0);
int colAttrib = shaderProgramService.getAttribute(shaderProgramId, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, false, stride, 2 * floatSize);
int texAttrib = shaderProgramService.getAttribute(shaderProgramId, "texcoord");
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, false, stride, 5 * floatSize);
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); <==== Removed
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
return vaoId;
}
编辑:感谢@RetoKoradi,摆脱glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
电话改进的事情。场景在屏幕上闪现,但我在第二帧上遇到了一个段错误。经过一些调试后,问题出现在我试图呈现的另一个尚未使用VAO的对象上。我正在进行这样的调用来渲染对象:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, texturedPoints.getEboId());
glBindBuffer(GL_ARRAY_BUFFER, texturedPoints.getVboId());
glBindTexture(GL_TEXTURE_2D, texturedPoints.getTextureId());
specifyVertexAttributes();
int count = texturedPoints.getCount();
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
以某种方式干扰了后续的VAO渲染调用,如下所示:
glBindVertexArray(texturedPoints.getVaoId());
glBindTexture(GL_TEXTURE_2D, texturedPoints.getTextureId());
glDrawElements(GL_TRIANGLES, texturedPoints.getCount(), GL_UNSIGNED_INT, 0);
glDrawElements
调用会在主循环第二次调用时调整错误。将一切都移到VAO之后,问题就消失了。