Reputation: 872
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
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
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:
Upvotes: 1