我正在尝试为窗口的亮度和对比度创建一个小的着色器(我见过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.
我还在做错什么?
答案 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语言教程。