glGetUniformLocation为第一个以外的采样器返回-1?

时间:2017-12-18 15:30:57

标签: c++ graphics opengl-es opengl-es-2.0

我一直在用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()并且不会出现任何错误。

感谢您提前提供任何帮助。

2 个答案:

答案 0 :(得分:2)

glGetUniformLocation(fp_render_prog, "rt2")glGetUniformLocation(fp_render_prog, "rt3")返回-1,因为rt2rt3无效。

请注意,glGetUniformLocation的第二个参数必须是有效统一变量的名称:

设置rt2rt3时会使用

RGB2RGB3

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

RGB2RGB3乘以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;

这导致rt2rt3未在可执行代码中使用,并且统一变量rt2rt3 无效


参见[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 :(得分:0)

-1的位置值不是错误条件,它只是暗示不需要给定的制服。出现这种情况的原因有多种,包括:

  • 着色器中从未存在统一值。
  • 声明统一值但从未在着色器中使用。
  • 在着色器/程序中声明并使用统一值,但编译器会对其进行优化,因为编译器可以证明不需要该值。