[LWJGL] Binding multiple VBOs to a VAO

I’m giving modern OpenGL a go, but I’m curious why I wasn’t able to add another VBO (more positional data) to my VAO. Based off the Wiki, I followed the same process to create the first VBO (vbo0) and put it on index 0. The second one (vbo1) at a different position isn’t being rendered, even though I put it in index 1. They should be 2 quads at different positions.

INITIALIZATION

 public void setupQuad() {  
    	
    	//vbo0
        float[] vertices = {
                // Left bottom triangle
                -0.5f, 0.5f, 0f,
                -0.5f, -0.5f, 0f,
                0.5f, -0.5f, 0f,
                // Right top triangle
                0.5f, -0.5f, 0f,
                0.5f, 0.5f, 0f,
                -0.5f, 0.5f, 0f
        };
        FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
        verticesBuffer.put(vertices);
        verticesBuffer.flip();
        
        ///////vbo1
        float[] vertices1 = {
                // Left bottom triangle
                -0.8f, 0.8f, 0f,
                -0.8f, -0.8f, 0f,
                -0.6f, -0.8f, 0f,
                // Right top triangle
                -0.8f, 0.8f, 0f,
                -0.6f, -0.8f, 0f,
                -0.6f, 0.8f, 0f
        };
        FloatBuffer verticesBuffer1 = BufferUtils.createFloatBuffer(vertices1.length);
        verticesBuffer1.put(vertices1);
        verticesBuffer1.flip();
        
        
        vaoId = GL30.glGenVertexArrays();
        GL30.glBindVertexArray(vaoId);
        
        //vbo0
        vboId = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
        GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);//index 0
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
        
        
        
        //vbo 1
        vboId1 = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId1);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer1, GL15.GL_STATIC_DRAW);
        GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, 0, 0);//index 1
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
        
        
         
        GL30.glBindVertexArray(0);
         
    }

Rendering

  public void loopCycle() {
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
         
        GL30.glBindVertexArray(vaoId);
        GL20.glEnableVertexAttribArray(0);
        GL20.glEnableVertexAttribArray(1);
         
        // Draw the vertices
        GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vertexCount);
         
        GL20.glDisableVertexAttribArray(0);
        GL20.glDisableVertexAttribArray(1);
        GL30.glBindVertexArray(0);
         
    }

Also, how can I get coordinates based on screen size without using an Orthographic projection? It wont let me call

glOrtho

, so I’d asume it’s deprecated.

You can still use orthographic projection, you just have to send the Matrix in a floatbuffer to a shader.

You’ve bound vbo0 to index 0 (floats, 3 floats per vertex, tightly packed) and vbo1 to index 1 (floats, 3 floats per vertex, tightly packed), so when the first vertex is rendered you get the vertex data from the first vertex of vbo0 and vbo1. This means you’re getting the information for two vertices in one vertex. If you want to draw data out of one vbo and then another vbo, you’ll have to do it like this, in two glDraw calls:


public void loopCycle() {
  GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
  GL30.glBindVertexArray(vaoId);

  GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
  GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0); // vbo0 has its data in index 0 now
  GL20.glEnableVertexAttribArray(0);
  GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

  // Draw the vertices in vbo0
  GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vertexCountInVbo0);

  GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId1);
  GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0); // vbo1 has its data in index 0 now
//  GL20.glEnableVertexAttribArray(0); // The index is already enabled, not needed
  GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

  // Draw the vertices in vbo1
  GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vertexCountInVbo1);

  GL20.glDisableVertexAttribArray(0);
  GL30.glBindVertexArray(0);
}

Hope this helps :slight_smile:

MinusKelvin is totally to the point!
Using two or more VBOs for the same draw call only makes sense if you want to add more vertex attributes
(color, specularity, roughness, temperature, health, time-to-live, younameit, …) to your vertices from those additional VBOs and not to add more vertices at the end.
Because as MinusKelvin said, all VBOs are being sourced from at the same time during a draw call.
Additional info: with instancing you can control how fast the “cursor” of the ‘current vertex’ advances per VBO (i.e. “vertex binding point”) ranging from “advance one attribute per vertex” to “do not advance at all for the whole draw call”.