Sign in to follow this  
562538332

Helps! Errors In glGetAttribLocationARB

Recommended Posts

I have created a program and attach a vertex shader and a fragment shader.

Before  linking the program,I use glBindAttribLocationARB the bind the attribue location 

and the i use glLinkProgramARB to link the program.

Linking is OK.There is still no error.

But when i use glGetAttribLocationARB to get the location.

The return result is wrong!!

 

The attribue"vertex" return 0

but the "normal" return -1

which i binded into 0 and 2

 

Here is the shader very simple:

vertex shader

#version 330 core
uniform mat4 MV;
uniform mat4 Proj;
in vec3 normal;
in vec3 vertex;
 
 
void main()
{
 gl_Position=Proj*MV*vec4(vertex,1.0);
}
 
fragment shader
#version 330 core
void main()
{
 
 }
If anyone know the reason,please tell me!!

Share this post


Link to post
Share on other sites

This should be considered very unlikely to work.

  1. You're using GLSL version 330 core.
  2. You're using the old GL_ARB_shader_objects extension.

To be totally clear: GL_ARB_shader_objects is not the same as OpenGL 2.0+ shader objects.  GL_ARB_shader_objects was the old pre-2.0 extension that was never promoted to core OpenGL and never updated since it's original specification.

 

In particular, mixing and matching GL_ARB_shader_objects and GL 2.0+ shader objects can blow up quite spectacularly on some drivers.

 

Stop using GL_ARB_shader_objects.  Use the GL 2.0 entry points instead (i.e those without the -ARB suffix) and you have better guaranteed functionality and stability, because there is absolutely no guarantee whatsoever of either functionality or stability when trying to use GL_ARB_shader_objects with more recent features.

Share this post


Link to post
Share on other sites

 

The normal attribute is not used and is removed from the shader by the shader compiler. This is not an error.

Come on.That is not gl_Normal....

 

I think you're misreading his answer.

Your variable normal is not used in the shader in any calculations.

The shader compiler sees this, and optimizes it out.

Since the variable is optimized out, the getAttrib function returns -1.

Share this post


Link to post
Share on other sites
Indeed, to avoid this, call glBindAttribLocation (_Bind_, not Get) _before_ linking the program. That's an explicit instruction to the compiler to set said variable at the specified slot, no questions.

You can also use the explicit binding locations support of newer GLSL versions for the same purpose. e.g. `layout(location=2) in vec3 normal;`

This is, in general, a far better way to do things (and, incidentally, is how every other modern or even semi-modern graphics API/language works!). Whether you have 1 or 20 shaders, your vertex attribute objects and your vertex buffers should be reusable with all of them. That means that your code should have an agreement that such-and-such attribute is always in a specific slot. Which in turn means that letting GLSL assign slot indices for you is counter-productive.

You can emulate the fixed mappings (with unavoidable overhead) if you're stuck on older versions of GL for some reason.

Share this post


Link to post
Share on other sites


Indeed, to avoid this, call glBindAttribLocation (_Bind_, not Get) _before_ linking the program. That's an explicit instruction to the compiler to set said variable at the specified slot, no questions.

It doesn't help this case (and in fact, the OP is already calling Bind).

 

If the compiler optimises out a particular attribute, it still won't be assigned to a slot, regardless of binding or explicit attrib location.

Share this post


Link to post
Share on other sites

your shader is bad:

 

uniform mat4 MV;
uniform mat4 Proj;
 
write 
attribute mat4 MV;
attribute mat4 Proj;
 
then glgetattribloaction will return something bigger than -1
 
because you want to fetch attribute location not uniform location

Share this post


Link to post
Share on other sites

...


That is not what the OP intends to do. That is not what he should be doing. Unless you are doing instancing there is no good reason to put these matrices into an attribute instead of a uniform.

Apart from that MV and Proj have nothing to do with the problem described, so even talking about them here has no purpose. Edited by BitMaster

Share this post


Link to post
Share on other sites
He wants to get the attribute location of the attribute 'normal' and he got an unexpected return value (for him). He did everything correctly except not realizing that unused attributes will be removed by the driver, resulting in the invalid location index. Edited by BitMaster

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this