GLSL compilation error when using QGLShaderProgram - c++

I'm currently trying out some of the opengl components in Qt 5, I'm compiling on Mac OSX 10.8 with QtCreator 2.6.2, clang 4.2
I've written a very basic GLSL shader that compiles and links well in OpenGl Shader Builder, but when I try to load it using a QGLShader, it fails to compile and the log function returns no error message.
Vertex Shader:
attribute vec4 in_position;
attribute vec3 in_normal;
attribute vec3 in_color;
attribute vec2 in_tex;
uniform vec4 lightPosition;
varying vec2 texCoords;
varying vec3 normal;
varying vec3 vertToLightDir;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * in_position;
vec4 worldVert = gl_ModelViewMatrix * in_position;
vertToLightDir = normalize(vec3(lightPosition - worldVert));
normal = gl_NormalMatrix * in_normal;
texCoords = in_tex;
}
Fragment Shader:
uniform sampler2D texture0;
uniform vec4 lightColor;
varying vec2 texCoords;
varying vec3 normal;
varying vec3 vertToLightDir;
void main(void)
{
float lightIntensity = clamp(dot(normal, vertToLightDir), 0.0, 1.0);
gl_FragColor = (texture2D(texture0, texCoords) + (lightColor * lightIntensity)) * 0.5;
}
The code that loads the shaders:
QGLShader fragShader(QGLShader::Fragment);
bool success = fragShader.compileSourceFile("Fragment.glsl");
qDebug() << fragShader.log();
I used the debugger to see that the compileSourceFile function returns false, I also used access("Fragment.glsl", F_OK) to see if the program manages to find the file and it does, the same goes for the vertex shader file, I can't seem to find the reason they won't compile. Is there something I'm doing wrong ?

After some debugging I realized I was trying to compile the shaders before a valid context was created. My bad.

Related

uniform sampler2D in Vertex Shader

I tried to realize height map with GLSL.
For it, i need to sent my picture to VertexShader and get grey component.
glActiveTexture(GL_TEXTURE0);
Texture.bind();
glUniform1i(mShader.getUniformLocation("heightmap"), 0);
mShader.getUniformLocation uses glGetUniformLocation and work good for other uniforms values, that used in Fragment, Vertex Shaders. But for heightmap return -1...
VertexShader code:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
layout (location = 2) in vec2 texCoords;
layout (location = 3) in vec3 normal;
out vec3 Normal;
out vec3 FragPos;
out vec2 TexCoords;
out vec4 ourColor;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform sampler2D heightmap;
void main()
{
float bias = 0.25;
float h = 0.0;
float scale = 5.0;
h = scale * ((texture2D(heightmap, texCoords).r) - bias);
vec3 hnormal = vec3(normal.x*h, normal.y*h, normal.z*h);
vec3 position1 = position * hnormal;
gl_Position = projection * view * model * vec4(position1, 1.0f);
FragPos = vec3(model * vec4(position, 1.0f));
Normal = mat3(transpose(inverse(model))) * normal;
ourColor = color;
TexCoords = texCoords;
}
may be algorithm of getting height is bad, but error with getting uniformlocation stops my work..
What is wrong? Any ideas?
UPD: texCoords (not TexCoords) of course is using in
h = scale * ((texture2D(heightmap, texCoords).r) - bias);
my mistake, but it doesn't solve the problem. Having same error..
My bet is your variable has been optimized out by driver or the shader did not compile/link properly. After trying to compile your shader (on my nVidia) I got this in the logs:
0(9) : warning C7050: "TexCoords" might be used before being initialized
You should always check the GLSL compile/link logs ? see
How to debug GLSL Fragment shader
especially how the glGetShaderInfoLog is used.
In line
h = scale * ((texture2D(heightmap, TexCoords).r) - bias);
You are using TexCoords which is output variable and not yet set so the behavior is undefined and most likely your gfx driver throw that line away (and may be others) removing the TexCoords from shader completely but that is just my assumption.
What driver and gfx card you got?
What returns the logs on your setup?

Light with vertex/fragment shader. Using varying variables. (openGL)

I was looking for a lot of this problem. I found this question Passing data into different shaders but this problem not mine. I get "The fragment shader uses varying "normal", but previous shader does not write to it." error message.
My vertey shader code:
#version 430
in layout(location=0) vec3 position;
in layout(location=1) vec3 normal;
out vec3 norm;
uniform mat4 transformation;
void main()
{
gl_Position = transformation * vec4(position, 1.0);
norm = (transformation * vec4(normal, 0.0)).xyz;
}
And my fragment shader code:
#version 430
in vec3 normal;
out vec4 colour;
vec3 lightPos = vec3(0,50,0);
vec3 lightColor = vec3(0.5, 0, 0);
vec3 materialColor = vec3(0, 1.0, 0);
void main() {
float cosTheta = dot(-lightPos, normalize(normal));
vec3 temp = materialColor * lightColor * cosTheta;
colour = vec4(temp, 1.0);
}
What is the main problem? I don't understand this message my vertex shader using the normal vector and it passing into fragment shader. I don't see difference between the linked code and mine. Please tell me some idea :\
If you want to use different variable names for some reason you can specify a location to match in- and output variables.
For example, in your case:
.vert:
out layout(location = 7) vec3 norm;
.frag:
in layout(location = 7)vec3 normal;

Simple GLSL Shader (Light) causes flickering

I'm trying to implement some basic lighting and shading following the tutorial over here and here.
Everything is more or less working but I get some kind of strange flickering on object surfaces due to the shading.
I have two images attached to show you guys how this problem looks.
I think the problem is related to the fact that I'm passing vertex coordinates from vertex shader to fragment shader to compute some lighting variables as stated in the above linked tutorials.
Here is some source code (stripped out unrelated code).
Vertex Shader:
#version 150 core
in vec4 pos;
in vec4 in_col;
in vec2 in_uv;
in vec4 in_norm;
uniform mat4 model_view_projection;
out vec4 out_col;
out vec2 passed_uv;
out vec4 out_vert;
out vec4 out_norm;
void main(void) {
gl_Position = model_view_projection * pos;
out_col = in_col;
out_vert = pos;
out_norm = in_norm;
passed_uv = in_uv;
}
and Fragment Shader:
#version 150 core
uniform sampler2D tex;
uniform mat4 model_mat;
in vec4 in_col;
in vec2 passed_uv;
in vec4 vert_pos;
in vec4 in_norm;
out vec4 col;
void main(void) {
mat3 norm_mat = mat3(transpose(inverse(model_mat)));
vec3 norm = normalize(norm_mat * vec3(in_norm));
vec3 light_pos = vec3(0.0, 6.0, 0.0);
vec4 light_col = vec4(1.0, 0.8, 0.8, 1.0);
vec3 col_pos = vec3(model_mat * vert_pos);
vec3 s_to_f = light_pos - col_pos;
float brightness = dot(norm, normalize(s_to_f));
brightness = clamp(brightness, 0, 1);
gl_FragColor = out_col;
gl_FragColor = vec4(brightness * light_col.rgb * gl_FragColor.rgb, 1.0);
}
As I said earlier I guess the problem has to do with the way the vertex position is passed to the fragment shader. If I change the position values to something static no more flickering occurs.
I changed all other values to statics, too. It's the same result - no flickering if I am not using the vertex position data passed from vertex shader.
So, if there is someone out there with some GL-wisdom .. ;)
Any help would be appreciated.
Side note: running all this stuff on an Intel HD 4000 if that may provide further information.
Thanks in advance!
Ivan
The names of the out variables in the vertex shader and the in variables in the fragment shader need to match. You have this in the vertex shader:
out vec4 out_col;
out vec2 passed_uv;
out vec4 out_vert;
out vec4 out_norm;
and this in the fragment shader:
in vec4 in_col;
in vec2 passed_uv;
in vec4 vert_pos;
in vec4 in_norm;
These variables are associated by name, not by order. Except for passed_uv, the names do not match here. For example, you could use these declarations in the vertex shader:
out vec4 passed_col;
out vec2 passed_uv;
out vec4 passed_vert;
out vec4 passed_norm;
and these in the fragment shader:
in vec4 passed_col;
in vec2 passed_uv;
in vec4 passed_vert;
in vec4 passed_norm;
Based on the way I read the spec, your shader program should actually fail to link. At least in the GLSL 4.50 spec, in the table on page 43, it lists "Link-Time Error" for this situation. The rules seem somewhat ambiguous in earlier specs, though.

GLSL vertex shader crashes computer

I've been trying to pinpoint the exact cause of a GLSL shader that crashes my computer. I'm running Mac OS X 10.8.2 with a NVIDIA GeForce 9400M. The shader renders correctly but will occasionally crash my computer, drawing regions of black over the display (including outside of the rendering window) until the computer becomes unresponsive.
I receive no errors from glGetError and no errors during shader compilation. It appears that the crash no longer occurs when I remove a uniform mat4 from the vertex shader, such as the model-view matrix, or one of the shadow matrices. Yet according to GL_MAX_VERTEX_UNIFORM_COMPONENTS my graphics card supports 4096 vertex uniform components.
Here is the vertex shader:
#version 120
attribute vec3 position;
attribute vec2 texcoord;
attribute vec3 normal;
varying vec2 v_texcoord;
varying vec3 v_normal;
varying vec3 v_halfVec;
varying vec4 v_shadowcoord0;
varying vec4 v_shadowcoord1;
varying vec4 v_shadowcoord2;
varying vec4 v_shadowcoord3;
uniform mat4 mv;
uniform mat3 nmv;
uniform mat4 mvp;
uniform mat4 shadowMatrix0;
uniform mat4 shadowMatrix1;
uniform mat4 shadowMatrix2;
uniform mat4 shadowMatrix3;
uniform vec3 lightDir;
void main()
{
vec4 p4 = vec4(position, 1.0);
v_texcoord = texcoord;
v_normal = normalize(nmv * normal);
vec3 vertexPos = vec3(mv * p4);
vec3 eyeDir = normalize(-vertexPos);
v_halfVec = normalize(eyeDir + lightDir);
v_shadowcoord0 = shadowMatrix0 * p4;
v_shadowcoord1 = shadowMatrix1 * p4;
v_shadowcoord2 = shadowMatrix2 * p4;
v_shadowcoord3 = shadowMatrix3 * p4;
gl_Position = mvp * p4;
}
I would greatly appreciate any help in tracking down the cause of this bug. Thanks!
It sounds like an issue in 10.8.2 that has also been seen here: http://news.softpedia.com/news/OS-X-10-8-2-Broken-NVIDIA-Drivers-Causing-Pixelmator-to-Crash-312907.shtml
There should be a Max OS 10.8.3 that will hopefully fix this.
UPDATES: http://www.cultofmac.com/214775/apple-releases-yet-another-10-8-3-os-x-beta-to-developers/

GLSL 2.0 Color and Texture

Hi i'm new to GLSL and i'm having a few problems.
I'm trying to create a pair of GLSL Shaders to either use color or texture but i must be doing something wrong.
The problem is that if set uUseTexture to 0 (which should indicate color) it doesn't work (object is not colored). I know the coloring code works separately, any hints why it does not work using the if statement?
Here is the code:
// Fragment
precision mediump float;
uniform int uUseTexture;
uniform sampler2D uSampler;
varying vec4 vColor;
varying vec2 vTextureCoord;
void main(void) {
if(uUseTexture == 1) {
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
} else {
gl_FragColor = vColor;
}
}
// Vertex
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
attribute vec2 aTextureCoord;
uniform int uUseTexture;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec4 vColor;
varying vec2 vTextureCoord;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
if(uUseTexture == 1) {
vTextureCoord = aTextureCoord;
} else {
vColor = aVertexColor;
}
Nothing springs to mind immediately glancing over your code, but I'd like to take a moment and point out that this use case can be covered without needing an if statement. For example, let's treat uUseTexture as a float instead of an int (you could cast it in the shader but this is more interesting):
// Vertex
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec4 vColor;
varying vec2 vTextureCoord;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
// It may actually be faster to just assign both of these anyway
vTextureCoord = aTextureCoord;
vColor = aVertexColor;
}
// Fragment
uniform float uUseTexture;
uniform sampler2D uSampler;
varying vec4 vColor;
varying vec2 vTextureCoord;
void main(void) {
// vTextureCoord is already a vec2, BTW
vec4 texColor = texture2D(uSampler, vTextureCoord) * uUseTexture;
vec4 vertColor = vColor * (1.0 - uUseTexture);
gl_FragColor = texColor + vertColor;
}
Now uUseTexture simply acts as a modulator for how much of each color source you want to use. And it's more flexible in that you could set it to 0.5 and get half texture/half vertex color too!
The thing that may surprise you is that there's a good likelihood that this is what the shader compiler is doing behind the scenes anyway when you use an if statement like that. It's typically more efficient for the hardware that way.