Paritosh Kulkarni
Paritosh Kulkarni

Reputation: 872

glGetUniformLocation returns -1 for samplers other than first?

I have been developing some application in OpenGL. In first pass I write some values to my FBO which has 3 color textures attached to it. In second pass I attach this 3 textures as Samplers in shader and do some calculations for color. following is shader code for second pass .

const char* final_fragment_source[] = {
    "uniform sampler2D rt1;\n"
    "uniform sampler2D rt2;\n"
    "uniform sampler2D rt3;\n"
    "out vec4 color;\n"
    "void main(){\n"
    "vec3 bg = vec3(0.0, 0.0, 0.0);\n"
    "vec4 RGB1 = texture2D(rt1,vec2(gl_FragCoord.xy));\n"
    "vec4 RGB2 = texture2D(rt2,vec2(gl_FragCoord.xy));\n"
    "vec4 RGB3 = texture2D(rt3,vec2(gl_FragCoord.xy));\n"
    "vec3 tempcolor = RGB1.rgb -  bg * RGB1.a + bg * RGB3.a + bg * RGB2.rgb * RGB3.a + RGB3.rgb * RGB2.a * 0.0f + bg;\n"
    "color = vec4(tempcolor,0.25);\n"
    "} \n"
};

Problem is when I call glGetUniformLocation() for rt2 and rt3 I get -1. I get correct location for rt1.

This I have tried

-- I know that if you dont use any of the uniform variable you declare in fragment shader then driver may optimize and return -1 for that variable. Here clearly I am using all variables in calculation for final color.

--There is no compile time or linking error in this shader code.

Following is code where I get error

glUseProgram(fp_render_prog);
err = glGetError();

rt1 = glGetUniformLocation(fp_render_prog, "rt1");
err = glGetError();

rt2 = glGetUniformLocation(fp_render_prog, "rt2");
err = glGetError();

rt3 = glGetUniformLocation(fp_render_prog, "rt3");
err = glGetError();

MVPLocation = glGetUniformLocation(render_prog, "MVP");
err = glGetError();``

--I have tried putting glGetError() and do not get any error.

Thanks for any help in advance.

Upvotes: 4

Views: 1616

Answers (2)

Rabbid76
Rabbid76

Reputation: 211230

glGetUniformLocation(fp_render_prog, "rt2") and glGetUniformLocation(fp_render_prog, "rt3") return -1, because rt2 and rt3 are not active.

Note, that the 2nd parameter of glGetUniformLocation must be the name of an active uniform variable:

rt2 and rt3 are used when setting RGB2 and RGB3:

vec4 RGB2 = texture2D(rt2,vec2(gl_FragCoord.xy));
vec4 RGB3 = texture2D(rt3,vec2(gl_FragCoord.xy));

RGB2 and RGB3 are multiplied by 0.0:

vec3 bg = vec3(0.0, 0.0, 0.0);
vec3 tempcolor = 
    RGB1.rgb - 
    bg * RGB1.a +
    bg * RGB3.a +
    bg * RGB2.rgb * RGB3.a +
    RGB3.rgb * RGB2.a * 0.0f +
    bg;

The compiler may optimize that:

vec3 tempcolor = 
    RGB1.rgb - 
    vec3(0.0) * RGB1.a +
    vec3(0.0) * RGB3.a +
    vec3(0.0) * RGB2.rgb * RGB3.a +
    RGB3.rgb * RGB2.a * 0.0f +
    vec3(0.0);

Which in final is the same as:

vec3 tempcolor = RGB1.rgb;

This causes that rt2 and rt3 are not used in the executable code and that the uniform variables rt2 and rt3 are inactive.


See [OpenGL ES 2 Specifications - 2.10.4 Shader Variables - p. 35] (https://www.khronos.org/registry/OpenGL/specs/es/2.0/es_full_spec_2.0.pdf):

A uniform is considered active if it is determined by the compiler and linker that the uniform will actually be accessed when the executable code is executed. In cases where the compiler and linker cannot make a conclusive determination, the uniform will be considered active.

.....

To find the location of an active uniform variable within a program object, use the command

int GetUniformLocation( uint program, const char *name );


See OpenGL ES 2.0 Online Manual Pages. - glGetActiveUniform:

A uniform variable (either built-in or user-defined) is considered active if it is determined during the link operation that it may be accessed during program execution.

Upvotes: 4

solidpixel
solidpixel

Reputation: 12229

A location value of -1 is not an error condition, it just implies that the given uniform is not needed. This can occur for multiple reasons, including:

  • Uniform value never existed in the shader.
  • Uniform value is declared but never used in the shader.
  • Uniform value is declared and used in the shader/program, but is optimized out by the compiler because the compiler can prove the value is not needed.

Upvotes: 1

Related Questions