0
votes

The LWJGL 3 code below sets up the buffers, etc, for rendering a triangle. I'm able to see the triangle. Now I'm trying to understand exactly what's going on.

Here's my understanding of the code below. We first create a vertex buffer object, which is just a container for an array of numbers. glBindBuffer() and glBufferData() fill the vertex buffer object with the vertices array. We do this again for a second array of vertices. We then compile the vertex and fragment shaders and add them to a shader program. Somehow, this program accesses the data in the second vertex buffer object.

So then we bind a vertex array object. We're populating it with the output of the shader program, which processed the vertex data from the second vertex buffer object.

Question

It looks like this setup is to allow multiple pieces of vertex data to be processed by the same set of commands. What commands would I place at the end of the code to to pass the first vertex data, rather than the second. Do I have to create a separate vertex array object for every vertex buffer object, or can I send different buffers down the pipe and keep the same vertex array object?

Code

Here's the code I was referencing above: First, the variables are:

//The vertices of a triangle
float[] vertices = new float[] {
        0.0f, 0.5f,
        0.5f, -0.5f,
        -0.5f, -0.5f
};

//Vertices of the second triangle
float[] vertices2 = new float[] {
        0.0f, 0.9f,
        0.5f, -0.5f,
        -0.5f, -0.5f
};

//The source for the vertex shader
String vertexShaderSrc =
        "#version 300 es\n\n" +
        "precision mediump float;\n" +
        "in vec2 position;\n\n" +
        "void main()\n" +
        "{\n" +
            "gl_Position = vec4(position, 0.0, 1.0);\n" +
        "}";

int vertexShader;

//The source for the fragment shader
String fragmentShaderSrc =
        "#version 300 es\n\n" +
        "precision mediump float;\n" +
        "out vec4 outColor;\n\n" +
        "void main()\n" +
        "{\n" +
            "outColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
        "}";
int fragmentShader;
int shaderProgram;
//The position attribute
int posAttrib;

//A vertex buffer object handle.
int vbo;

//A second vertex buffer object handle.
int vbo2;

//A vertex array object handle.
int vao;

The code segment that uses them is:

vbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);

vbo2 = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, vertices2, GL_STATIC_DRAW);


vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, vertexShaderSrc);
glCompileShader(vertexShader);

System.out.println(glGetShaderInfoLog(vertexShader));

fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, fragmentShaderSrc);
glCompileShader(fragmentShader);

System.out.println(glGetShaderInfoLog(fragmentShader));

shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);

vao = glGenVertexArrays();
glBindVertexArray(vao);

posAttrib = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(posAttrib);
1

1 Answers

0
votes

"It looks like this setup is to allow multiple pieces of vertex data to be processed by the same set of commands" - Yes, you can pass with one render call of an Vertex Arrays Object by adding more Vertex Buffer Objects that contain data like vertices positions, texture coordinates, vertex color and more. If you want to change the vertex data sent to the shader like position, you can use a transformation matrix passed as a uniform to move, scale and rotate the object. However if the objects are different models then you should use different vaos.