Reputation: 1437
Two questions:
I am rendering elements in a large VBO with different shaders. In GLSL 1.2 which I must use if I am correct as it is the most current version on OSX does not support uniform locations, which I assume means that the location of your attributes is wherever the compiler decides. Is there any way around this? For instance, as my VBO up with interleaved (x,y,z,nx,ny,nz,texU,texV), I need multiple shaders to be able to access these attributes in the same place every time. I am finding however that the compiler is giving them different locations leading to the location being the normals, and so on. I need their locations to be consistent with my VBO attribute location.
I just got my first GLSL rendering completed and it looks exactly like I forgot to enable the depth test with various polygons rendered on top of one another. I enabled depth testing with:
glEnable(GL_DEPTH_TEST);
And the problem persists. Is there a different way to enable them with shaders? I thought the depth buffer took care of this?
Problem 2 Solved. Turned out to be an SFML issue where I needed to specify the OpenGL settings when creating the window.
Upvotes: 2
Views: 1184
Reputation: 473427
Attribute locations are specified in one of 3 places, in order from highest priority to lowest:
Through the use of the GLSL 3.30 (or better) or ARB_explicit_attrib_location extension syntax layout(location = #)
, where #
is the attribute index. So if I have an input called position
, I would give it index 3 like this:
layout(location = 3) in vec4 position;
This is my preferred method of handling this. Explicit_attrib_location is available on pretty much any hardware that is still being supported (that isn't Intel).
Explicit association via glBindVertexAttrib
. You call this function before linking the program. To do the above, we would do this:
GLuint program = glCreateProgram();
glAttachShader(program, some_shader);
glBindVertexAttrib(program, 3, "position");
glLinkProgram(program);
You can set multiple attributes. Indeed, you can set multiple attribute names to the same index. The idea with that is to be able to just set a bunch of mappings automatically and let OpenGL figure out which one works with the actual shader code. So you could have "position" and "axis" map to index 3, and as long as you don't put a shader into this system that has both of those inputs, you'll be fine.
Note that you can also set attributes that don't exist. You could give "normal" an attribute that isn't specified in the shader. That is fine; the linker will only care about attributes that actually exist. So you can establish a complex convention for this sort of thing, and just run every program on it before linking:
void AttribConvention(GLuint prog)
{
glBindVertexAttrib(program, 0, "position");
glBindVertexAttrib(program, 1, "color");
glBindVertexAttrib(program, 2, "normal");
glBindVertexAttrib(program, 3, "tangent");
glBindVertexAttrib(program, 4, "bitangent");
glBindVertexAttrib(program, 5, "texCoord");
}
GLuint program = glCreateProgram();
glAttachShader(program, some_shader);
AttribConvention(program);
glLinkProgram(program);
Even if a particular shader doesn't have all of these attributes, it will still work.
Let OpenGL assign it. If you don't assign an attribute index to an attribute in one of the other ways, the GLSL linker will assign it for you. You can fetch the attribute post-linking with glGetAttribLocation
.
I really don't advise this, because OpenGL will assign the indices arbitrarily. So every shader that uses an attribute named position
may have the position in a different index. I don't think it's a good idea. So if you can't explicitly set it in the shader, then at least explicitly set it in your OpenGL code before linking. That way, you can have a convention about what attribute index 0 means, what index 1 means, etc.
Upvotes: 2
Reputation: 16662
On OpenGL 3.3+ you have VAOs, when you use them, you do bind VBOs to it and you can define attributes in a custom order : http://www.opengl.org/sdk/docs/man3/xhtml/glEnableVertexAttribArray.xml (remember that attributes must be contiguous)
A nice/easy implementation of this can be found on XNA : VertexDeclaration, you might want to see all the Vertex* types as well.
Some hint on getting v3 to work with SFML : http://en.sfml-dev.org/forums/index.php?topic=6314.0
An example on how to create and use VAOs : http://www.opentk.com/files/issues/HelloGL3.cs
(It's C# but I guess you'll get it)
Update :
On v2.1 you have it too http://www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml, though you can't create VAOs. Almost the same functionality can be achieved but you will have to bind attributes every time since it'll be on the fixed pipeline.
Upvotes: 1