本文介绍了GLSL:着色器链接失败(但没有日志)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to create a little shader for brightness and contrast of the window (that I've seen here).

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

I can load the file, and compile the shader successfully. But I fail to link it. My problem is that the log has no output, so I can't see what's wrong with it. How can I check the linking problem? Where can I find informations about linking failing, and check why linking can fail (I'm new to shaders).

我正在使用Ubuntu 12.04.

I'm using 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代码

And this is the glsl code that I load

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;
}

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

I fixed log, when linking fails, I obtain following output:

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

我已经修复了片段着色器

I've fixed fragment shader

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);
}

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

And I've added a basic vertex shader

attribute vec4 gl_Vertex;

void main(){
  gl_Position = gl_Vertex;
}

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

I've added them to program. Now all compilation warning disappeared, but linking fails again.

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.

我现在做错了什么?

推荐答案

您仅附加了片段着色器,而不附加了顶点着色器.在完全可编程的openGL中,两者都需要.您的代码应为:

You are only attaching a fragment shader and not a vertex shader. In fully programmable openGL both are required. Your code should be:

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

在将着色器附加到程序之后,由于顶点着色器和片段着色器都是必需的,因此链接失败.

Linking happens after shaders are attached to a program, and since both vertex and fragment shaders are required linking failed.

此外,您基本上是在GLSL中编写Cg.

Moreover you are basically writing Cg in GLSL.

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

重点是GLSL不会像语义一样使用Cg,您需要使用GLSL特殊输出变量.检查以下psudo-GLSL代码.

The point is that GLSL doen't use Cg like semantics and you need to use GLSL special out variables. Check the following psudo-GLSL code.

 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;
    }

我实际上建议您选择GLSL语言教程,例如这个.

I actually recommend that you pick a GLSL language tutorial like this one.

这篇关于GLSL:着色器链接失败(但没有日志)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 05:38