如果Else语句导致GLSL存在行为

时间:2014-06-30 15:10:27

标签: java opengl lwjgl

所以我的顶点着色器就像这样

String vertexshader = "#version 330 core"
        + System.getProperty("line.separator")
        + "in vec4 vertexin;"
        + "in vec2 textcoords;"
        + "in int texture;"
        + "uniform mat4 orthogonal;"
        + "out vec2 supertextcoords;"
        + "out int textureoi;"
        + "void main(){"
        + "gl_Position = orthogonal * vertexin ;"
        + "supertextcoords = textcoords;"
        + "textureoi=texture;"
        + "}";

我的片段着色器就像这样

String fragmentshader="#version 330 core"
        + System.getProperty("line.separator")
        +"out vec4 outcolor;"
        + "in int textureoi;"
        +"in vec2 supertextcoords;"
        +"uniform sampler2D texture1;"
        +"uniform sampler2D texture2;"
        + "vec4 texturedecode();"
        + "vec4 texturedecode() {"
        + "vec4 color;"
        + "if(textureoi==0) {"
        + "color= texture2D(texture1, supertextcoords); return color; }"
        + "else if(textureoi==1) {"
        + " color= texture2D(texture2, supertextcoords); return color;"
        + "} else {"
        + " color= texture2D(texture2, supertextcoords); return color;}"
        + "}"
        +"void main(){"         
        +" outcolor =texturedecode();"      
        +"}";

问题是,当我glUseProgram()时,我得到错误1282.只有在我使用函数texturedecode()时才会出现问题。如果我在outcolor变量上使用它或者自己声明一些未使用的变量并不重要。它崩溃了opengl。

我发送变量的方式如下。

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, TextureInit.loadTexture(io.getSubimage(0,0, 32, 32), 4));
int loc1 = glGetUniformLocation(program, "texture1");
glUniform1i(loc1, 0);
glActiveTexture(GL_TEXTURE1); 
glBindTexture(GL_TEXTURE_2D, TextureInit.loadTexture(io.getSubimage(32,0, 32, 32), 4));
int loc2 = glGetUniformLocation(program, "texture2");
glUniform1i(loc2, 0);
int orthographicloc=glGetUniformLocation(program,"orthogonal");
glUniformMatrix4(orthographicloc,false, orthographicBuffer);
glBindAttribLocation(program, 0, "vertexin");
glBindAttribLocation(program, 1, "textcoords");  
glLinkProgram(program);


glVertexAttribPointer(0, 4, GL_FLOAT,false,0,0);
glVertexAttribPointer(1,2,GL_FLOAT,false,0,vertices.length*datasize);
glVertexAttribIPointer(2,1,GL_INT,0,vertices.length*datasize+textcoord.length*4);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glDrawArrays(GL_TRIANGLES, 0, vertices.length/4);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);

2 个答案:

答案 0 :(得分:1)

来自OpenGL wiki

  

在片段着色器中,还有一种情况会导致所有非“Lod”或“Grad”纹理访问变为未定义:非均匀流控制。

     

代码中特定位置的统一流控制意味着,无论着色器如何执行,着色器都将遵循相同的路径到达代码位置。请考虑片段着色器的以下GLSL代码:

void main()
{
  vec4 firstData = texture(someSampler, textureCoords);

  if(parameterValue < 20)
  {
      firstData += texture(someOtherSampler, otherTexCoords);
  }

  vec4 moreData = texture(thirdSampler, thirdTexCoords);
}
  

第一次纹理访问发生在统一流控制中。因此,纹理访问产生明确的结果。但是,下一个纹理访问不是统一流程。如果访问的纹理使用任何类型的mipmapping或各向异性过滤,则任何不是“Lod”或“Grad”的纹理函数都将检索未定义的结果。最后一次纹理访问再次发生在均匀流控制中,并将产生明确的结果。

     

注意:GLSL编译器不会为此提供错误。这是完全合法的GLSL代码。只有在这些纹理上设置了某些纹理状态时,它才会变为未定义。具体来说,如果使用mipmap或各向异性过滤。

为了缓解这种情况,您可以对两种纹理进行采样并使用if / else返回相应的颜色值,也可以手动使用textureGrad

答案 1 :(得分:0)

我们去!问题是整数不是&#34;平坦&#34;。这是什么意思?我不知道。但解决这个问题的方法是写

flat out int textureoi;

flat in int textureoi;