我一直在OpenGL中开发一些应用程序。在第一遍中,我给我的FBO写了一些值,它附有3个颜色纹理。在第二遍中,我将这3个纹理附加为着色器中的采样器,并对颜色进行一些计算。以下是第二遍的着色器代码。
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"
};
问题是当我为rt2和rt3调用glGetUniformLocation()时,我得到-1。我得到了rt1的正确位置。
我试过了
- 我知道如果你不使用你在片段着色器中声明的任何统一变量,那么驱动程序可以优化并为该变量返回-1。这里显然我在计算最终颜色时使用所有变量。
- 此着色器代码中没有编译时间或链接错误。
以下是我收到错误的代码
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();``
- 我试过放glGetError()并且没有任何错误。
在此先感谢您的帮助。
glGetUniformLocation(fp_render_prog, "rt2")
和glGetUniformLocation(fp_render_prog, "rt3")
返回-1,因为rt2
和rt3
不活跃。
注意,glGetUniformLocation
的第二个参数必须是活动统一变量的名称:
设置rt2
和rt3
时使用RGB2
和RGB3
:
vec4 RGB2 = texture2D(rt2,vec2(gl_FragCoord.xy));
vec4 RGB3 = texture2D(rt3,vec2(gl_FragCoord.xy));
RGB2
和RGB3
乘以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;
编译器可以优化:
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);
最终的结果如下:
vec3 tempcolor = RGB1.rgb;
这导致rt2
和rt3
未在可执行代码中使用,并且统一变量rt2
和rt3
处于非活动状态。
参见[OpenGL ES 2规范 - 2.10.4着色器变量 - p。 35](https://www.khronos.org/registry/OpenGL/specs/es/2.0/es_full_spec_2.0.pdf):
如果编译器和链接器确定在执行可执行代码时实际将访问统一,则统一被认为是活动的。如果编译器和链接器无法做出确定的决定,则统一将被视为活动。
.....
要在程序对象中查找活动统一变量的位置,请使用该命令
int GetUniformLocation( uint program, const char *name );
见OpenGL ES 2.0 Online Manual Pages. - glGetActiveUniform
:
如果在链接操作期间确定可以在程序执行期间访问它,则统一变量(内置或用户定义)被认为是活动的。
-1
的位置值不是错误条件,它只是意味着不需要给定的制服。出现这种情况的原因有多种,包括: