GLSL:着色器链接失败(但没有日志)

时间:2014-02-04 14:29:19

标签: opengl linker glsl fragment-shader

我正在尝试为窗口的亮度和对比度创建一个小的着色器(我见过here)。

我可以加载文件,并成功编译着色器。但我没有联系它。我的问题是日志没有输出,所以我看不出它有什么问题。如何检查链接问题?我在哪里可以找到关于链接失败的信息,并检查链接失败的原因(我是着色器的新手)。

我正在使用Ubuntu 12.04。

这是初始化代码

if (GLEW_ARB_fragment_shader) {
    // I enter here so I suppose that shader is enabled for
    // my graphics card
    std::cout << "arb shader enabled" << std::endl;
}

// Loading shader
string fragmentShaderSource;
GLint len;
std::ifstream in("/path/to/file.glsl");
fragmentShaderSource = std::string((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
len = fragmentShaderSource->size();

// I've checked the string and file seems to be loaded properly.

// Creating shader
GLint flength;
GLuint fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
GLcharARB** text = new (GLcharARB*);
text[0] = (char*)fragmentShaderSource.c_str();
glShaderSourceARB(fragmentShader, 1, (const GLcharARB**) text, &flength);

// Compile shader
glCompileShaderARB(fragmentShader);
GLint compiled;

glGetObjectParameteriv(ShaderObject, GL_COMPILE_STATUS, &compiled);
if (compiled)
{
    // I enter here so I suppose that compilation is ok.
    std::cout << "shader compiled" << std::endl;
} 

// Attaching to program
GLuint program;
program = glCreateProgram();
glAttachShader(program, fragmentShader);

// Linking
glLinkProgram(program);

// Link check
GLint linked;
glGetProgramivARB(program, GL_LINK_STATUS, &linked);
if (linked) {
    std::cout << "linked" << std::endl;
} else {
    // I enter here so linking is failed
    std::cout << "not linked" << std::endl;
    GLint blen = 0;
    GLsizei slen = 0;
    glGetShaderiv(program, GL_INFO_LOG_LENGTH, &blen);
    // blen is equal to zero so I cannot print the log message
    // because it's absent
    if (blen > 1) {
        GLchar* linking_log = (GLchar*) malloc(blen);
        glGetProgramInfoLog(program, blen, &slen, linking_log);
        glGetInfoLogARB(program, blen, &slen, linking_log);
        std::cout << "compiler_log:\n" << linking_log << std::endl;
        free(linking_log);
    }
}

这是我加载的glsl代码

uniform float Brightness : register(C0);
uniform float Contrast : register(C1);

sampler2D Texture1Sampler : register(S0);

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 pixelColor = tex2D(Texture1Sampler, uv);
    pixelColor.rgb /= pixelColor.a;

    // Apply contrast.
    pixelColor.rgb = ((pixelColor.rgb - 0.5f) * max(Contrast, 0)) + 0.5f;

    // Apply brightness.
    pixelColor.rgb += Brightness;

    // Return final pixel color.
    pixelColor.rgb *= pixelColor.a;
    return pixelColor;
}

编辑:

我修复了日志,当链接失败时,我得到以下输出:

Fragment info
-------------
0(1) : warning C7557: OpenGL does not allow Cg-style semantics
0(2) : warning C7557: OpenGL does not allow Cg-style semantics
0(4) : warning C7557: OpenGL does not allow Cg-style semantics
0(4) : warning C7554: OpenGL requires sampler variables to be explicitly declared as uniform
0(6) : warning C7506: OpenGL does not define the global type float4
0(6) : warning C7506: OpenGL does not define the global type float2
0(6) : warning C7557: OpenGL does not allow Cg-style semantics
0(6) : warning C7557: OpenGL does not allow Cg-style semantics
0(6) : warning C7527: OpenGL requires main to take no parameters
0(6) : warning C7530: OpenGL requires main to return void
0(9) : warning C7506: OpenGL does not define the global function tex2D
0(13) : warning C7502: OpenGL does not allow type suffix 'f' on constant literals in versions below 120
0(13) : warning C7011: implicit cast from "int" to "float"
0(13) : warning C7502: OpenGL does not allow type suffix 'f' on constant literals in versions below 120

EDIT2:

我修复了片段着色器

uniform float Brightness;
uniform float Contrast;
uniform vec2 vTextureCoord;
uniform sampler2D Texture1Sampler;

void main() {
    vec4 textureColor = texture2D(Texture1Sampler, vTextureCoord);
    vec3 fragRGB = textureColor.rgb / textureColor.a;
    fragRGB.rgb = ((fragRGB.rgb - 0.5) * max(Contrast, 0.0)) + 0.5;
    fragRGB.rgb += Brightness;
    fragRGB.rgb *= textureColor.a;
    gl_FragColor = vec4(fragRGB, textureColor.a);
}

我添加了一个基本的顶点着色器

attribute vec4 gl_Vertex;

void main(){
  gl_Position = gl_Vertex;
}

我已将它们添加到程序中。现在所有编译警告都消失了,但链接再次失败。

program = glCreateProgram(); 
glAttachShader(program, fragmentShader); // fragment shader compiled. No warnings
glAttachShader(program, vertexShader); // vertex shader compiled. No warnings
glLinkProgram(program);
GLint linked;
glGetProgramivARB(program, GL_LINK_STATUS, &linked); // linked != GL_TRUE. Linking failed.

我还在做错什么?

1 个答案:

答案 0 :(得分:3)

您只附加片段着色器而不是顶点着色器。在完全可编程的openGL中,都是必需的。你的代码应该是:

glAttachShader(program, fragmentShader);
glAttachShader(program, vertexShader);

在着色器附加到程序后发生链接,并且由于顶点和片段着色器都需要链接失败。

此外,你基本上是在GLSL中写Cg。

float4 main(float2 uv : TEXCOORD) : COLOR // These Cg semantics are not accepted in GLSL

关键是GLSL不使用类似Cg的语义,你需要使用GLSL特殊输出变量。检查以下psudo-GLSL代码。

 in vec3 vertex;
    //vertex shader.
    void main() // write a main and output should be done using special variables
    {
      // output using special variables.
    gl_Position = vertex;
    }


    //fragment shader.
    uniform vec4 color;
    void main() // write a main and output should be done using special variables 
    {
      // output using special variables.
    gl_FragColor = color;
    }

我实际上建议您选择像this one这样的GLSL语言教程。