This is a little long but I want to be as clear as possible.
Here is a brief description of my problem: I am successfully rendering a simple scene using deferred shading and light maps. Everything looks great. I’m now attempting to create an omnidirectional light map using a GL_TEXTURE_CUBE_MAP. In the fragment shader for the light pass that reads said cube map, I am reading from, and checking the value of, the texture using something like:
uniform samplerCube tShadowMapCube;
...
float zBuffer = textureCube(tShadowMapCube, -normalized_frag_to_light_vector).z;
gl_FragColor = vec4(zBuffer, zBuffer, zBuffer, 1.0);
where normalized_frag_to_light_vector is a vec3 that is what it says. This produces a link error. What is the error you ask? Well, the info log doesn’t have anything in it, so I don’t know!
I can verify that I usually get an error message when a link error is produced, like “ERROR: 0:32: error(#172) Too many arguments constructor” or some such thing. No error message is given in this case.
I can verify that normalized_frag_to_light_vector holds sensible values, because if I just ignore the light map and use normalized_frag_to_light_vector to produce plain, unshadowed lighting, it works perfectly. Also, it’s the same as what is in the directional light fragment shader, which works perfectly.
The most puzzling thing is this: If I simply ignore the link error, everything works as expected. The code snippet above produces exactly the expected results, and shows that it’s reading sensible values from the samplerCube.
Another puzzling thing is that if I replace normalized_frag_to_light_vector in the snippet above with something like vec3(texCoord, 1.0), where texCoord is the varying vec2 representing the GBuffer coordinates, then no link error is produced (but obviously that’s not where I want to sample the samplerCube from). I can also replace it with something like vec3(any constant values here) and no link error is produced.
So, what is going on? Is there something obvious I’m missing?
Here are lots of details (I can provide more if you need):
I’m using Java with the the “jogl-1.1.1-rc8-linux-amd64” version of JOGL (maybe this is a bit old?). I have an Radeon HD 6700, using Catalyst 11.12 drivers for linux (maybe this has some problems?). Output from relevant glGetStrings:
GL_VENDOR: ATI Technologies Inc.
GL_RENDERER: AMD Radeon HD 6700 Series
GL_VERSION: 4.2.11318 Compatibility Profile Context
The full fragment shader is here (obviously this will produce weird looking results, but I’m just testing the cube map values, and if I ignore the link error, the results are exactly what one would expect).
#ifdef GL_ES
precision highp float;
#endif
uniform vec3 lightPosition;
uniform vec3 lightColor;
uniform sampler2D tColor;
uniform sampler2D tPosition;
uniform sampler2D tNormal;
uniform samplerCube tShadowMapCube;
varying vec2 texCoord;
void main()
{
//read gbuffer data
vec4 color = vec4(vec3(texture2D(tColor, texCoord)), 1.0);
vec3 fragPosition = vec3(texture2D(tPosition, texCoord));
vec3 normal = vec3(texture2D(tNormal, texCoord));
//get dist and normalized vector from vertex to light
vec3 frag_to_light_vector = lightPosition - fragPosition;
float d = length(frag_to_light_vector);
vec3 normalized_frag_to_light_vector = frag_to_light_vector / d;
//get cube map value
//if I use either commented version of ltf, no link error is produced
//vec3 ltf = vec3(1.0, 1.0, 1.0);
//vec3 ltf = vec3(texCoord.xy, 1.0);
vec3 ltf = -normalized_frag_to_light_vector;
float zBuffer = textureCube(tShadowMapCube, ltf).z;
gl_FragColor = vec4(zBuffer, zBuffer, zBuffer, 1.0);
}
Here is the code that is finding the link error:
private void checkLinkAndValidationErrors(GL gl, int id) {
IntBuffer status = BufferUtil.newIntBuffer(1);
gl.glGetProgramiv(id, GL.GL_LINK_STATUS, status);
if (status.get() == GL.GL_FALSE) {
getInfoLog(gl, id);
} else {
status.rewind();
gl.glValidateProgram(id);
gl.glGetProgramiv(id, GL.GL_VALIDATE_STATUS, status);
if (status.get() == GL.GL_FALSE) {
getInfoLog(gl, id);
} else {
System.out.println("Successfully linked program " + id);
}
}
}
private void getInfoLog(GL gl, int id) {
IntBuffer infoLogLength = BufferUtil.newIntBuffer(1);
gl.glGetShaderiv(id, GL.GL_INFO_LOG_LENGTH, infoLogLength);
ByteBuffer infoLog = BufferUtil.newByteBuffer(infoLogLength.get(0));
gl.glGetShaderInfoLog(id, infoLogLength.get(0), null, infoLog);
String infoLogString =
Charset.forName("US-ASCII").decode(infoLog).toString();
throw new Error("Shader compile error
" + infoLogString);
}
Which is referred to in the following (if I simply comment out the “checkLinkAndValidationErrors”, everything works as expected)
public ShaderLightPassShadowedCube(GL gl){
int v = gl.glCreateShader(GL.GL_VERTEX_SHADER);
int f = gl.glCreateShader(GL.GL_FRAGMENT_SHADER);
//read shader sources and compile
gl.glShaderSource(v, 1, readShaderResource("ShaderLightPassVert.glsl"), null);
gl.glCompileShader(v);
checkCompileError(gl, v);
gl.glShaderSource(f, 1, readShaderResource("ShaderLightPassShadowedCubeFrag.glsl"), null);
gl.glCompileShader(f);
checkCompileError(gl, f);
//create shader program and attach shaders
shaderProgram = gl.glCreateProgram();
gl.glAttachShader(shaderProgram, v);
gl.glAttachShader(shaderProgram, f);
gl.glBindAttribLocation(shaderProgram, 0, "vertexPosition");
gl.glBindAttribLocation(shaderProgram, 1, "vertexTex");
//link the shader program
gl.glLinkProgram(shaderProgram);
gl.glValidateProgram(shaderProgram);
//if I simply comment this out, everything works as expected
checkLinkAndValidationErrors(gl, shaderProgram);
//get locations of data arrays
vertexPositionAttribute = gl.glGetAttribLocation(shaderProgram, "vertexPosition");
vertexTexAttribute = gl.glGetAttribLocation(shaderProgram, "vertexTex");
//some lighting info
lightPositionUniform = gl.glGetUniformLocation(shaderProgram, "lightPosition");
lightColorUniform = gl.glGetUniformLocation(shaderProgram, "lightColor");
//these are the gbuffer "textures"
tColorUniform = gl.glGetUniformLocation(shaderProgram, "tColor");
tPositionUniform = gl.glGetUniformLocation(shaderProgram, "tPosition");
tNormalUniform = gl.glGetUniformLocation(shaderProgram, "tNormal");
//this is the light map texture
tShadowMapCubeUniform = gl.glGetUniformLocation(shaderProgram, "tShadowMapCube");
}
This is super long now and I’m not even sure what more of the code would be relevant to post, since, as I said, everything is producing correct results if I just ignore the strange, uninformative link error. I can post whatever else you’d like to see, though.