I’m trying to figure out how VAOs work so I wrote a stupid function to test a shader.
In the Vertex Shader I have 2 in variables for passing vertex attribute data.
When I bind these variables directly (using glBindAttribLocation()) to some Vertex Attribute Index and Bind the VBOs to these indices then it works fine.
If I link the program first and let the linker decide the indices of these variables, then query these indices and bind the VBOs to them (as I did in the previous case) , nothing gets drawned. As if the VBOs are not hooked on the indices.
Here is my code.
I’m using OpenTK and C#
As you can see I create a Dictionary with entries for each in variable which I then invoke by name. I’ve checked it and the indices returned are the correct (and the same with the Pre Linking Binding). I have put commends which lines I use in each of the two cases.
private void PureShaderDraw()
{
Matrix4 MVMatrix;
Matrix4 PMatrix;
float[,] NormalMatrix;
Dictionary<string, VertexAttribute> VAttribLexicon = new Dictionary<string, VertexAttribute>();
Shaders.GLSL_Program cProg = Foundation.Global3DObjectCollection.GLSL_ProgramList[_GLSL_ProgramHandle];
if (FirstRun)
{
//Uncomment these two Lines for Fixed binding
//GL.BindAttribLocation(_GLSL_ProgramHandle, 0, "gli_Vertex");
//GL.BindAttribLocation(_GLSL_ProgramHandle, 1, "gli_Normal");
GL.BindFragDataLocation(_GLSL_ProgramHandle, 0, "FragColor");
cProg.LinkProgram();
}
//If Pre linking fixed Binding occurs, Comment this whole if clause
if (FirstRun)
{
//First get the number of used vertex attribute indices
int numOfIndices, maxNameLen;
GL.GetProgram(_GLSL_ProgramHandle, ProgramParameter.ActiveAttributes, out numOfIndices);
GL.GetProgram(_GLSL_ProgramHandle, ProgramParameter.ActiveAttributeMaxLength, out maxNameLen);
//Clear the current Entries in the Lexicon.
VAttribLexicon.Clear();
//For each attribute index
for (int i = 0; i < numOfIndices; ++i)
{
int NameLen, attribSize;
ActiveAttribType attribType;
StringBuilder sBuilder = new StringBuilder();
//Read the variable assigned to it.
GL.GetActiveAttrib(_GLSL_ProgramHandle, i, maxNameLen, out NameLen, out attribSize, out attribType, sBuilder);
//Store an entry in the lexikon.
VAttribLexicon.Add(sBuilder.ToString(), new VertexAttribute(sBuilder.ToString(), (uint)i, attribType));
}
}
GL.UseProgram(_GLSL_ProgramHandle);
MVMatrix = Foundation.RenderingDevice.DeviceState.GetCurrentModelviewMatrix();
PMatrix = Foundation.RenderingDevice.DeviceState.GetCurrentProjectionMatrix();
NormalMatrix = Foundation.RenderingDevice.DeviceState.GetCurrentNormalMatrix();
GL.Uniform3(Foundation.GetUniformLocation(_GLSL_ProgramHandle, "BrickColor"), 1.0f, 0.3f, 0.2f);
GL.Uniform3(Foundation.GetUniformLocation(_GLSL_ProgramHandle, "MortarColor"), 0.85f, 0.86f, 0.84f);
GL.Uniform2(Foundation.GetUniformLocation(_GLSL_ProgramHandle, "BrickSize"), 0.30f, 0.15f);
GL.Uniform2(Foundation.GetUniformLocation(_GLSL_ProgramHandle, "BrickPct"), 0.9f, 0.85f);
GL.Uniform3(Foundation.GetUniformLocation(_GLSL_ProgramHandle, "LightPosition"), 0.0f, 0.0f, 4.0f);
GL.UniformMatrix4(Foundation.GetUniformLocation(_GLSL_ProgramHandle, "MVMatrix"), false, ref MVMatrix);
GL.UniformMatrix4(Foundation.GetUniformLocation(_GLSL_ProgramHandle, "PMatrix"), false, ref PMatrix);
GL.UniformMatrix3(Foundation.GetUniformLocation(_GLSL_ProgramHandle, "NormalMatrix"), 1, false,
Foundation.ArrayOperations.ToColumnWiseArrayf(NormalMatrix));
cProg.VAO.MakeCurrent();
if (FirstRun)
{
Primary.Vertex_VBO.BindData(Primary.VertexArray, 3);
Primary.Normal_VBO.BindData(Primary.NormalArray, 3);
Index_VBO.BindData(IndexArray, 3);
//Uncomment these two Lines for Fixed binding
//cProg.VAO.BindVBO(0, Primary.Vertex_VBO);
//cProg.VAO.BindVBO(1, Primary.Normal_VBO);
//Ccomment these two Lines for Fixed binding
cProg.VAO.BindVBO(VAttribLexicon["gli_Vertex"].Index, Primary.Vertex_VBO);
cProg.VAO.BindVBO(VAttribLexicon["gli_Normal"].Index, Primary.Normal_VBO);
}
//Draw the primitives according to the subdivision method
if (SubdivisionMethod == MeshSubdivisionMethod.Triangulation)
GL.DrawElements(BeginMode.Triangles, IndexArray.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
else
GL.DrawElements(BeginMode.Quads, IndexArray.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
if (FirstRun) FirstRun = false;
GL.BindVertexArray(0);
GL.UseProgram(0);
}