I'm learning OpenGL for a personal project and I have mesh that contains 3 shaders:
- Shader for normal rendering
- Shader for picking as explained in: http://www.opengl-tutorial.org/miscellaneous/clicking-on-objects/picking-with-an-opengl-hack/
- Shader for outlining the picked object
These are the methods that I'm using to create the shaders (the shader class creates the shader program etc...):
public static Shader CreateBasicEntityShader()
{
var shader = new Shader("entityBasicShader.vert", "entityBasicShader.frag");
shader.Use();
shader.SetModelMatrix(Matrix4.Identity);
var positionLocation = shader.GetAttribLocation("aPos");
GL.EnableVertexAttribArray(positionLocation);
GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 5 * sizeof(float), 0);
var texCoordsLocation = shader.GetAttribLocation("aTexCoords");
GL.EnableVertexAttribArray(texCoordsLocation);
GL.VertexAttribPointer(texCoordsLocation, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float));
return shader;
}
public static Shader CreateOutlineShader()
{
var shader = new Shader("outlineShader.vert", "outlineShader.frag");
shader.Use();
shader.SetModelMatrix(Matrix4.Identity);
var positionLocation = shader.GetAttribLocation("aPos");
GL.EnableVertexAttribArray(positionLocation);
GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0);
return shader;
}
public static Shader CreateMeshShader()
{
var shader = new Shader("meshShader.vert", "meshShader.frag");
shader.Use();
shader.SetModelMatrix(Matrix4.Identity);
var positionLocation = shader.GetAttribLocation("aPos");
GL.EnableVertexAttribArray(positionLocation);
GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 0);
var normalLocation = shader.GetAttribLocation("aNormal");
GL.EnableVertexAttribArray(normalLocation);
GL.VertexAttribPointer(normalLocation, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 3 * sizeof(float));
var texCoordLocation = shader.GetAttribLocation("aTexCoords");
GL.EnableVertexAttribArray(texCoordLocation);
GL.VertexAttribPointer(texCoordLocation, 2, VertexAttribPointerType.Float, false, 8 * sizeof(float), 6 * sizeof(float));
return shader;
}
Then in the mesh I'm just creating the shaders:
this.Shader = Shader.CreateMeshShader();
this.PickingShader = Shader.CreateBasicEntityShader();
this.OutlineShader = Shader.CreateOutlineShader();
The problem is that I noticed that the order in which I create the shaders are important. I think that this is because somehow the VertexAttribPointer is being overriden by the last calls.
How should I manage this situation? I've think of two options but neither of those seems optimal:
- First option: Generate the shaders as if they contain all data (positions, normals, texture coords, etc...) even I don't use that data for the calculations in the shaders.
- Disable and enable the VertexAttribPointer depending on the necessities of the shader. I don't know if this would even work as the stride and offset provided is different in every case.
Is there any other option?