View Full Version : Post linking vertex attribute binding not stored

03-13-2010, 03:45 AM
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_ProgramLi st[_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");


//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.

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


MVMatrix = Foundation.RenderingDevice.DeviceState.GetCurrentM odelviewMatrix();
PMatrix = Foundation.RenderingDevice.DeviceState.GetCurrentP rojectionMatrix();
NormalMatrix = Foundation.RenderingDevice.DeviceState.GetCurrentN ormalMatrix();

GL.Uniform3(Foundation.GetUniformLocation(_GLSL_Pr ogramHandle, "BrickColor"), 1.0f, 0.3f, 0.2f);
GL.Uniform3(Foundation.GetUniformLocation(_GLSL_Pr ogramHandle, "MortarColor"), 0.85f, 0.86f, 0.84f);
GL.Uniform2(Foundation.GetUniformLocation(_GLSL_Pr ogramHandle, "BrickSize"), 0.30f, 0.15f);
GL.Uniform2(Foundation.GetUniformLocation(_GLSL_Pr ogramHandle, "BrickPct"), 0.9f, 0.85f);
GL.Uniform3(Foundation.GetUniformLocation(_GLSL_Pr ogramHandle, "LightPosition"), 0.0f, 0.0f, 4.0f);
GL.UniformMatrix4(Foundation.GetUniformLocation(_G LSL_ProgramHandle, "MVMatrix"), false, ref MVMatrix);
GL.UniformMatrix4(Foundation.GetUniformLocation(_G LSL_ProgramHandle, "PMatrix"), false, ref PMatrix);
GL.UniformMatrix3(Foundation.GetUniformLocation(_G LSL_ProgramHandle, "NormalMatrix"), 1, false,
Foundation.ArrayOperations.ToColumnWiseArrayf(Norm alMatrix));


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);
GL.DrawElements(BeginMode.Quads, IndexArray.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);

if (FirstRun) FirstRun = false;