I've been getting some strange results when trying to implement a normals buffer for the purpose of rendering lighting. It seems to be related to the indexes for glEnableVertexAttribArray, glVertexAttribPointer and the location value in the vertex shader. Take a look at the following code for example:
gl.glEnableVertexAttribArray(1);
gl.glEnableVertexAttribArray(0);
//bind vertex data - why does the index have to be 1?
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboHandles[VERTICES_IDX]); //the vertex data
gl.glVertexAttribPointer(1,3,GL4.GL_FLOAT, false, 0,0);
// Select the VBO, GPU memory data, to use for colors
// - why doe the index have to be 0??
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboHandles[COLOR_IDX]);
gl.glVertexAttribPointer(0, 3, GL4.GL_FLOAT, false, 0, 0);
//bind IBO
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, vboHandles[2]);
Where do the values for the indexes used in the above functions come from? If I were to switch them and make the color buffer 1 and the vertex buffer 0, nothing renders. It seems logical to me that the vertices should be applied first and then the colors? My confusion is compounded when I try to pass the data to a shader. I thought the location value in the shader program referred to the index in glVertexAttribPointer but that doesn't seem to be the case. In fact it looks like location is being completely ignored (targeting GLSL 430). Have a look at this:
From the shader:
layout (location=0) in vec3 vertexPosition;
layout (location=1) in vec3 vertexNormal;
The Java code:
//with glEnableVertexAttribArray 0 and 1 enabled all of the cubes render but they
//are individually lighted - ie the shading doesn't propagate over the whole scene,
//only over each cube.
//if i rem 1, the scene looks lighted properly. So only 1 vertex array enabled
//and it still works?
gl.glEnableVertexAttribArray(0);
gl.glEnableVertexAttribArray(1);
//gl.glEnableVertexAttribArray(2);
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboHandles[VERTICES_IDX]);
//with the index set to 5 (doesn't relate to any other index) the scene still
//renders...
gl.glVertexAttribPointer(5,3,GL4.GL_FLOAT, false, 0,0);
//normals
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboHandles[3]);
gl.glVertexAttribPointer(1, 3, GL4.GL_FLOAT, false, 0, 0);
// Select the VBO, GPU memory data, to use for colors
//almost strangest of all. If I remove colors the program crashes. I don't
//even use this buffer..
gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboHandles[COLOR_IDX]);
gl.glVertexAttribPointer(0, 3, GL4.GL_FLOAT, false, 0, 0);
//bind IBO
gl.glBindBuffer(GL4.GL_ELEMENT_ARRAY_BUFFER, vboHandles[2]);
There is obviously something fundamental here that I am not understanding. I would think that by setting the glVertexAttribPointer index for the vertices to 5 it would unlink from the shader in variable as its location is 0. I need to know what is going on here especially now that I am implementing lighting. So, what is the relationship between the glVertexAttribPointer index and the shader location value? Also, why does the index have to be certain value (eg 0 for color, 1 for vertex)?