Jump to content

  • Log In with Google      Sign In   
  • Create Account


glGetAttribLocation and a -1 return value?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
18 replies to this topic

#1 MARS_999   Members   -  Reputation: 1237

Like
0Likes
Like

Posted 10 February 2009 - 07:21 AM

I am at my minds end, I have no errors when checking my code with GL's built in calls, and I am using the vertex attribute in my VS... What else would cause me to get a -1? I am using GLUT to do some test runs on my new shader lib, and the same code works in my engine. The shader runs and shows a textured surface, but the values are wrong, and gDebugger throws the error saying that glEnableVertexAttribArray() has a wrong value... The code in the shader is the same as my engines code and that returns a value other than -1... Thanks

Sponsor:

#2 swiftcoder   Senior Moderators   -  Reputation: 9584

Like
0Likes
Like

Posted 10 February 2009 - 07:35 AM

Post some code - preferably the code that sets up the vertex arrays/buffers, and the code that binds the shaders and sets the uniforms.

glGetAttribLocation() only returns -1 when the attribute cannot be found in the shader. This includes when the attribute is declared but unused, and thus optimised out.

Tristam MacDonald - Software Engineer @Amazon - [swiftcoding]


#3 MARS_999   Members   -  Reputation: 1237

Like
0Likes
Like

Posted 10 February 2009 - 07:40 AM


//vs
#version 120

varying vec3 lightDir;
attribute vec3 vTangent, vBiTangent;

void main()
{
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
vec3 tangent = normalize(gl_NormalMatrix * vTangent);
vec3 bitangent = normalize(gl_NormalMatrix * vBiTangent);
mat3 TBN = mat3(tangent, bitangent, normal);
lightDir = normalize(vec3(gl_LightSource[0].position) - (vec3(gl_Vertex) * gl_LightSource[0].position.w));
lightDir = lightDir * TBN;

gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

//code

{
char *vs = 0, *fs = 0, *gs = 0;
if(!vsFilename.empty())
{
v = glCreateShader(GL_VERTEX_SHADER);
vs = TextFileRead(vsFilename);
const char* vv = vs;
glShaderSource(v, 1, &vv, NULL);
glCompileShader(v);
ValidateCompile(v);
}
if(!fsFilename.empty())
{
f = glCreateShader(GL_FRAGMENT_SHADER);
fs = TextFileRead(fsFilename);
const char* ff = fs;
glShaderSource(f, 1, &ff, NULL);
glCompileShader(f);
ValidateCompile(f);
}
if(!gsFilename.empty())
{
g = glCreateShader(GL_GEOMETRY_SHADER_EXT);
gs = TextFileRead(gsFilename);
const char* gg = gs;
glShaderSource(g, 1, &gg, NULL);
glCompileShader(g);
ValidateCompile(g);
}
id = glCreateProgram();
if(!vsFilename.empty())
glAttachShader(id, v);
if(!fsFilename.empty())
glAttachShader(id, f);
if(!gsFilename.empty())
glAttachShader(id, g);

//need to call glBindAttribLocation() before glLinkProgram() if you want to explicitly assign the index value
//or the compiler will assign one automatically
glBindAttribLocation(id, 6, "vTangent");
glBindAttribLocation(id, 7, "vBiTangent");

glLinkProgram(id);
glUseProgram(id);
ValidateProgram();

textureLocation[0] = glGetUniformLocation(id, "texture");
glUniform1i(textureLocation[0], 0);

uniformVariable[NXObject::VERTEX_TANGENT] = glGetAttribLocation(id, "vTangent");
uniformVariable[NXObject::VERTEX_BITANGENT] = glGetAttribLocation(id, "vBiTangent");

glUseProgram(0);

if(vs)
delete []vs;
if(fs)
delete []fs;
if(gs)
delete []gs;
}






#4 swiftcoder   Senior Moderators   -  Reputation: 9584

Like
0Likes
Like

Posted 10 February 2009 - 09:01 AM

I don't see any particular issues with that code, but why do you force specific attribute locations, if you are going to query them later?

Tristam MacDonald - Software Engineer @Amazon - [swiftcoding]


#5 MARS_999   Members   -  Reputation: 1237

Like
0Likes
Like

Posted 10 February 2009 - 09:19 AM

Quote:
Original post by swiftcoder
I don't see any particular issues with that code, but why do you force specific attribute locations, if you are going to query them later?


I put that in to see if they are picked up. And even after that they still return -1... I am out of ideas.

#6 MARS_999   Members   -  Reputation: 1237

Like
0Likes
Like

Posted 10 February 2009 - 09:34 AM

glGetProgramiv(id, GL_ACTIVE_ATTRIBUTES, &success);

Returns 2, so I can only assume it is seeing them? But still I have a -1.

#7 swiftcoder   Senior Moderators   -  Reputation: 9584

Like
0Likes
Like

Posted 10 February 2009 - 09:40 AM

Quote:
Original post by MARS_999
glGetProgramiv(id, GL_ACTIVE_ATTRIBUTES, &success);

Returns 2, so I can only assume it is seeing them? But still I have a -1.
Try retrieving the attribute names with glGetActiveAttrib().

Tristam MacDonald - Software Engineer @Amazon - [swiftcoding]


#8 NumberXaero   Prime Members   -  Reputation: 1303

Like
0Likes
Like

Posted 10 February 2009 - 09:40 AM

Myself, I do,

create program object
create vertex program
compile vertex program
attach vertex program
create fragment program
compile fragment program
attach fragment program

init attributes
link program object
init uniforms

so after attaching the geometry shader, try

//or the compiler will assign one automatically
glBindAttribLocation(id, 6, "vTangent");
glBindAttribLocation(id, 7, "vBiTangent");
// or
uniformVariable[NXObject::VERTEX_TANGENT] = glGetAttribLocation(id, "vTangent");
uniformVariable[NXObject::VERTEX_BITANGENT] = glGetAttribLocation(id, "vBiTangent");

glLinkProgram(id);
//glUseProgram(id);

textureLocation[0] = glGetUniformLocation(id, "texture");
glUniform1i(textureLocation[0], 0);

ValidateProgram();

//glUseProgram(0);

#9 MARS_999   Members   -  Reputation: 1237

Like
0Likes
Like

Posted 10 February 2009 - 09:59 AM

Quote:
Original post by swiftcoder
Quote:
Original post by MARS_999
glGetProgramiv(id, GL_ACTIVE_ATTRIBUTES, &success);

Returns 2, so I can only assume it is seeing them? But still I have a -1.
Try retrieving the attribute names with glGetActiveAttrib().


Sigh, it shows only the gl_MultiTexCoord0 and gl_Vertex attributes. So for some reason they aren't getting assigned... No errors.

#10 MARS_999   Members   -  Reputation: 1237

Like
0Likes
Like

Posted 10 February 2009 - 12:23 PM

Some more fun, I just looked and noticed that gl_Normal doesn't even show up in the glGetActiveAttrib() calls. I only have gl_Vertex and gl_MultiTexCoord0.

This is going to seem stupid, but I don't need to setup anything else correct?

#11 Yann L   Moderators   -  Reputation: 1794

Like
0Likes
Like

Posted 10 February 2009 - 12:36 PM

From a quick (and pretty tired) look at it, it should work alright. I'm actually not entirely sure what glGetAttribLocation is supposed to return when you bind the streams manually. Logically it should just echo the stream binding, but I never tried it. There is a kind of non-orthogonality in the standard here, since you are allowed to manually bind to an unused attribute, yet you cannot query it. I also do manual binding in my engine, but I directly use the bound vertex attribute stream indices without re-querying them. Have you tried that ? Does that work ?

Ah wait a second. Do you actually use a GS in that example ?

#12 MARS_999   Members   -  Reputation: 1237

Like
0Likes
Like

Posted 10 February 2009 - 01:22 PM

Hey YannL, no I send in a empty string and it doesn't setup the GS.

Add, I am going to ask this because I am not seeing straight anymore, do I need to setup my VBO and IBO before I setup the shaders? I wouldn't think so, but I am really reaching here.

#13 swiftcoder   Senior Moderators   -  Reputation: 9584

Like
0Likes
Like

Posted 10 February 2009 - 03:09 PM

Quote:
Original post by MARS_999
Hey YannL, no I send in a empty string and it doesn't setup the GS.
Sent an empty string where?

I would advise you try two things:
a) comment out the manual binding, and see if you get attribute locations
b) don't use getAttrib, instead just bind to the locations you manually set

Tristam MacDonald - Software Engineer @Amazon - [swiftcoding]


#14 MARS_999   Members   -  Reputation: 1237

Like
0Likes
Like

Posted 10 February 2009 - 05:09 PM

if(!gsFilename.empty())
that there is "" so it skips the code blocks...

Anyway, I commented out the getAttrib() and used the glBindAttribLocation() and still nothing, like I said I don't even get gl_Normal to show up in the list when its printed off. Why is that? I have gl_Normal in the damn VS.... Why I am so pissed is, the code is pulled from my engine, but I am not understanding why its not working, when 1. No errors from the shader logs, other than glGetError() throwing and invalid value after the shader is shutdown.


#15 swiftcoder   Senior Moderators   -  Reputation: 9584

Like
0Likes
Like

Posted 11 February 2009 - 12:27 AM

Well, I am afraid that I am out of advice at this point. Do you have access to a copy of gDEBugger?

Tristam MacDonald - Software Engineer @Amazon - [swiftcoding]


#16 Ashaman73   Crossbones+   -  Reputation: 6685

Like
0Likes
Like

Posted 12 February 2009 - 03:09 AM

My bet:
The compiler optimized the code, removing unused variables. If you try to bind to an unused variable you will get -1 as a result.

Just a test'n'try, but how about changing your lightDir calculation from

lightDir = lightDir * TBN;

to

lightDir = TBN * lightDir;

Does it help ?

--
Ashaman

#17 JvdWulp   Members   -  Reputation: 170

Like
0Likes
Like

Posted 12 February 2009 - 06:27 PM

Hey someone with a similar problem.

For some reason glGetUniformLocationARB, always returns -1.

I am currently at the point where I copied all the code to set up shaders from a tutorial and it still does not work.

Greetz Jaap

#18 hellraizer   Members   -  Reputation: 979

Like
0Likes
Like

Posted 12 February 2009 - 07:27 PM

Just a shot in the dark here, but do you actually use 'lightDir' inside the fragment shader? I know it's a dumb question but since the vs/fs are linked in a program, the driver is free to "optimize" out unused varyings. I'm not sure if it does, i'm just guessing.

HellRaiZer

#19 MARS_999   Members   -  Reputation: 1237

Like
0Likes
Like

Posted 13 February 2009 - 01:10 PM

As someone else already pointed out, you need to actually use the register at some point in the shader, my problem was, I thought/assumed it only needed to be used in the shader in which I declared it in. e.g. attributes are only vertex shader so I figured I only need to do something in the VS such as assign it to a new variable and that would be good enough. Nope, the compiler is smart enough to see you never used it to do anything so it will -1 it and not use it. You need to actually do something with it in the FS also from what I could tell... Maybe that isn't the case but when I passed the attribute as a varying with some math done on it in the VS, and did something with it in the FS it assigned a index, but just multiplying it by a value in the VS and doing nothing else with it, gave me a -1.

Hope this clears up for others.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS