Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

When I provide the following struct definition in linked frag and vert shaders, my phone (Samsung Vibrant / Android 2.2) complains that the definition differs.

struct Light {
    mediump vec3 _position;
    lowp vec4 _ambient;
    lowp vec4 _diffuse;
    lowp vec4 _specular;
    bool _isDirectional;
    mediump vec3 _attenuation; // constant, linear, and quadratic components
};

uniform Light u_light;

I know the struct is identical because its included from another file. These shaders work on a linux implementation and on my Android 3.0 tablet. Both shaders declare "precision mediump float;"

The exact error is:

Uniform variable u_light type/precision does not match in vertex and fragment shader

Am I doing anything wrong here, or is my phone's implementation broken? Any advice (other than file a bug report?)

share|improve this question
    
Certainly sounds odd, have you checked to make sure the structure alignments are the same? Perhaps as they are drawn in to be compiled they have different data alignments and thus different sizes, so the compiler throws up an error. –  Shaktal Jul 30 '11 at 11:56
    
That's a very good thought. Other than the order in which I declare things, what control do I have over alignment? –  stephelton Jul 30 '11 at 19:16
    
Well, you could test using the glGetActiveUniformsiv( GLuint program, GLsizei uniformCount, GLconstuint *uniformIndices, GLenum pname, GLint *params ); function, you can find more information on it here. That should allow you to check at run-time if they have similar block structures (hopefully before the error), update me on the results of that. :) –  Shaktal Jul 30 '11 at 19:45
    
Another good idea, but this doesn't work before linking (at least on this implementation.) I can link the two shaders in question with bogus shaders just so I can have the chance to print their info and compare it, but I haven't the time for that at the moment. –  stephelton Jul 31 '11 at 0:12
    
In all shaders (including the ones in question, when not linked together) the struct Light generated the same output from getActiveUniformsiv() –  stephelton Jul 31 '11 at 2:06

2 Answers 2

The reason is due to a bug in the driver (or an overlooked gotcha in the GLSL language?). Your vertex shader uses some of the struct members, your fragment shader uses a different set of the struct members, and the drivers ends up creating 2 different types by independently eliminating the unused uniforms from the struct type in both shaders which cause them to differ when linked together as the final step. To work around this you have to split your struct in 2 (one for vertex, one for fragment) or pass the pixel shader data as varying data (wasteful).

share|improve this answer
up vote 0 down vote accepted

I'm not going to flag this as the correct answer, but I have worked around this by avoiding this particular struct. Pretty lame.

share|improve this answer
    
After playing with this some more, I think this is unfortunately the answer. The implementation is clearly just buggy. –  stephelton Nov 15 '11 at 3:36
    
Damned phones... always complaining. I just tell mine, "shut it". –  Nick Wiggill Nov 15 '11 at 19:49
    
I think the phone won that battle. –  stephelton Nov 15 '11 at 20:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.