1

I'm using lwjgl 3 as a Java wrapper to OpenGL, and I'm trying to figure out how to render things with Vertex Array Objects. I have not been able to find any examples online that show how to use a VAO that has both shader attributes and uses the element array buffer.

According to this vao tutorial, I need to do something like this:

// 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);

However, I don't understand how to adapt this tutorial to my project, because I am using glVertexAttribPointer to deal with fields in the shader. These fields have id's that are assigned to them when the shader is compiled. In the above example, they seem to be able to use the default field 0. However, I checked, for me posAttrib is in field 0.

How should I associate a VBO with my 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;
    }

EDIT: Thanks @RetoKoradi, getting rid of the glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); call improved things. The scene flashed onscreen, but I got a seg-fault on the second frame. After some debugging, the issue was with another object I was trying to render that was not yet using VAO's. I was making calls like this to render the object:

    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);

Somehow that interfered with subsequent VAO rendering calls that looked like this:

    glBindVertexArray(texturedPoints.getVaoId());
    glBindTexture(GL_TEXTURE_2D, texturedPoints.getTextureId());
    glDrawElements(GL_TRIANGLES, texturedPoints.getCount(), GL_UNSIGNED_INT, 0);

The glDrawElements call would seg-fault the second time that the main loop went around and called it. After moving everything over to VAO's the problems have gone away.

Kevin
  • 1,080
  • 3
  • 15
  • 41
  • 3
    And what's the problem with your code? Looks like you have pretty much everything you need. The only thing you probably want to avoid is unbinding the `GL_ELEMENT_ARRAY_BUFFER` at the end, because that binding is part of the VAO state, and you will need it when you draw. – Reto Koradi Jan 16 '16 at 22:49
  • See for example my answer here if you have problems understanding how the VBO is associated with the vertex attributes: http://stackoverflow.com/a/24879196/3530129. – Reto Koradi Jan 16 '16 at 22:56
  • This question shows an answer which outlines shader attributes as defined in call to glVertexAttribPointer https://stackoverflow.com/questions/19135962/drawing-opengl-lines-squares-in-3-2-using-vao-vbos/19149320#19149320 – Scott Stensland Jan 16 '16 at 23:06

0 Answers0