I've been having an issue running glGetUnfiormLocation calls. While building a project on school computers running ATI graphics cards, the program functions flawlessly. However, using the school computers running nvidia cards, the calls to glGetUniformLocation return -1.
//c++ side
glLinkProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not link the shader program");
ModelMatrixUniformLocaion = glGetUniformLocation(ShaderIds[0], "ModelMatrix");
ViewMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ViewMatrix");
ProjectionMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ProjectionMatrix");
ExitOnGLError("ERROR: Could not get the shader uniform locations");
And here is the vertex shader
layout(location=0) in vec4 in_Position;
layout(location=1) in vec4 in_Color;
layout(location=2) in vec2 in_Coord;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
varying vec2 v_UVCoord;
out vec4 ex_Color;
void main(void)
{
gl_Position = (ProjectionMatrix * ViewMatrix * ModelMatrix) * in_Position;
gl_PointSize = in_Coord.x;
ex_Color = in_Color;
v_UVCoord = in_Coord;
}
From what I can tell, it shouldn't be giving me -1 based on optimization of the uniforms, because they are all in use, as are the attributes. Any insight into the matter would be greatly appreciated.
Linking an OpenGL program does not give an OpenGL error when it fails. You must actually check to see if the program linked properly.
Related
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?
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.
I wrote a pair of shaders to display the textures as greyscale instead of full color. I used these shaders with libGDX's built in SpriteBatch class and it worked. Then when I tried to use it with the built in SpriteCache class it didn't work. I looked at the SpriteCache code and saw that it set some different uniforms that I tried to take into account but I seem to have gone wrong somwhere.
The SpriteCache class in libGDX sets the following uniforms:
customShader.setUniformMatrix("u_proj", projectionMatrix);
customShader.setUniformMatrix("u_trans", transformMatrix);
customShader.setUniformMatrix("u_projTrans", combinedMatrix);
customShader.setUniformi("u_texture", 0);
This is my vertex shader:
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_proj;
uniform mat4 u_projTrans;
uniform mat4 u_trans;
varying vec4 v_color;
varying vec2 v_texCoords;
void main() {
v_color = a_color;
v_texCoords = a_texCoord0;
gl_Position = a_position* u_proj * u_trans;
}
and this is the fragment shader:
varying vec4 v_color;
varying vec2 v_texCoords;
uniform sampler2D u_texture;
uniform u_projTrans;
void main() {
vec4 color = texture2D(u_texture, v_texCoords).rgba;
float gray = (color.r + color.g + color.b) / 3.0;
vec3 grayscale = vec3(gray + 0* u_projTrans[0][0]);
gl_FragColor = vec4(grayscale, color.a);
}
The error I get is:
Exception in thread "LWJGL Application" java.lang.IllegalArgumentException: no uniform with name 'u_proj' in shader
...
com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:206)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)ackends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:206)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
I guess do any of you guys know why this isn't working? There is a uniform with the name u_proj.
Thank you all!
What Reto Koradi said was true I had forgotten to put a mat4 tag before u_projTrans, that helped me.
Then what Tenfour04 said was a huge help too! I hadn't known about:
if (!shader.isCompiled()) throw new GdxRuntimeException("Couldn't compile shader: " + shader.getLog());
What helped me most in the long run was finding that glsl, when compiling, would do away with unused imports and that if you weren't able to trick the compiler into thinking that unused imports were used being used the shader would compile and then crash on runtime.
In libgdx there is a static "pedantic" variable that you can set. If it is set to false the application won't crash if variables are sent to the shader that the shader isn't using, they will simply be ignored. The code in my libgdx program looked something like this:
ShaderProgram.pedantic = false;
Thanks for your help all! I hope this can help someone in the future
Make sure that you check the success of your shader compilation/linking. Your fragment shader will not compile:
uniform u_projTrans;
This variable declaration needs a type. It should be:
uniform mat4 u_projTrans;
You can use the following calls to test for errors while setting up your shader programs:
glGetShaderiv(shaderId, GL_COMPILE_STATUS, ...);
glGetShaderInfoLog(shaderId, ...);
glGetProgramiv(programId, GL_LINK_STATUS, ...);
glGetProgramInfoLog(programId, ...);
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.
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/