pouët.net

OpenGL/GLSL texture coordinates.

category: general [glöplog]
 
Hi alll.

I'm not quite sure what I experience is a but or correct behaviour, because I use an scenegraph library, so I'm asking around here.
I have an application that uses textures in units 0-3 in a GLSL shader. I always use texture coordinates from unit 0 ("gl_TexCoord[0] = gl_MultiTexCoord0;" in the vertex shader) for all samplers. Then in the fragment shader I do "vec2 texCoord = gl_TexCoord[0].st;" and work with that (vec4 color = texture2D(bla, texCoord);). Now, if I have NO texture in unit 0 (but still some in 1-3) the texture coordinates in unit 0 are always (1.0, 0.0).
Is this specified OpenGL behaviour or is it the library screwing up here?
added on the 2009-03-27 12:46:32 by raer raer
Sorry for the typos. Example code:

Vertex shader
Code: varying vec3 lightVec; varying vec3 halfVector; varying vec2 texCoord; void main(void) { gl_Position = ftransform(); texCoord = gl_MultiTexCoord0.xy; vec3 normal = normalize(gl_NormalMatrix * gl_Normal); mat3 trans = transpose(gl_NormalMatrix); vec3 tangent = normalize(gl_NormalMatrix * trans[0]); vec3 binormal = normalize(gl_NormalMatrix * trans[1]); vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex); vec3 tmpVec = gl_LightSource[0].position.xyz - vVertex; lightVec.x = dot(tmpVec, tangent); lightVec.y = dot(tmpVec, binormal); lightVec.z = dot(tmpVec, normal); halfVector = reflect(-tmpVec, gl_Normal); halfVector.x = dot(tmpVec, tangent); halfVector.y = dot(tmpVec, binormal); halfVector.z = dot(tmpVec, normal); }

Fragment shader
Code: uniform sampler2D colorMap; uniform sampler2D normalMap; uniform sampler2D heightMap; uniform float strength; uniform float scale; uniform float bias; uniform int parallax; uniform int isTexUnit0Used; varying vec3 lightVec; varying vec3 halfVector; varying vec2 texCoord; void main (void) { vec3 h = normalize(halfVector); if (parallax == 1) { float height = texture2D(heightMap, texCoord).r; height = height * scale + bias; texCoord = texCoord + (height * h.xy); } vec3 n = normalize(texture2D(normalMap, texCoord).rgb * 2.0 - 1.0); vec3 l = normalize(lightVec); float nDotL = max(0.0, dot(n, l)); float nDotH = max(0.0, dot(n, h)); float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess); vec4 ambient = gl_LightSource[0].ambient; vec4 diffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * nDotL; vec4 specular = gl_LightSource[0].specular * gl_FrontMaterial.specular * power * strength; vec4 color = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular; if (isTexUnit0Used == 0) { gl_FragColor = color; } else { gl_FragColor = color * texture2D(colorMap, texCoord); } }


Again: If there's a texture in unit 0 everything's fine. If no texture in unit 0 texture coordinates are always (1.0, 0.0).
added on the 2009-03-27 15:01:00 by raer raer
Is it (1.0, 0.0) in all cases or just the test case you've tried? I can't be bothered digging in the spec but I would guess that that value is undefined.
Haven't tried it in OpenGL. I use a scenegraph library called Coin3D.

Do you mean that the value MEANS it is undefined or the value must be undefined in this case? I read through the GL specs a bit, but didn't get any useful information.
added on the 2009-03-27 15:32:45 by raer raer
I also tried adding a
Code: if (isTexUnit0Used == 0) { texCoord = gl_MultiTexCoord1.xy; } else { texCoord = gl_MultiTexCoord0.xy; }

to the vertex shader which seems to help in some cases.
added on the 2009-03-27 15:34:46 by raer raer
Well unless I've misunderstood, what you basically have is an uninitialized variable and so the value would be undefined and possibly vary on different implementations.
Ifs in a shader?
added on the 2009-03-27 15:40:49 by xernobyl xernobyl
The question is: IS gl_MultiTexCoord0 uninitialized by definition if the texture unit 0 is not being used?! That is what I'm asking.
If it should NOT be uninitialized (imo, because the application is still passing the texture coordinate values) then the scene graph library screws up somewhere and does not pass the coordinates.
added on the 2009-03-27 15:54:29 by raer raer
Or: IS gl_MultiTexCoord0 uninitialized by the OpenGL specs definition if the texture unit 0 is not being used?
added on the 2009-03-27 15:56:00 by raer raer
maybe the engine has some code like this (found in a Maya Hardware Shader example):
Code:glClientActiveTexture(GL_TEXTURE0 + coord); if (coord < texCoordCount && texCoordArrays[coord]) { //this set exists glTexCoordPointer(2, GL_FLOAT, 0, texCoordArrays[coord]); glEnableClientState(GL_TEXTURE_COORD_ARRAY); } else { //the set does not exist glMultiTexCoord2f(GL_TEXTURE0 + coord, 1.0f, 0.0f); glDisableClientState(GL_TEXTURE_COORD_ARRAY); }
added on the 2009-03-27 15:59:29 by bartman bartman
xernobyl, welcome to 2004! \o/
added on the 2009-03-27 16:01:34 by iq iq
I don't think texture coordinates and texture units have anything to do with each other here. And gl_multitexcoord0 should probably have the last set value (immediate mode or as part of (maybe previous) vertex buffer).
But if the library doesn't use the unit and only uses the tcoord0 for the texture I guess it's fair enough that it's not spending time sending the values..
added on the 2009-03-27 16:08:35 by Psycho Psycho
well. if it is like this, it pretty much fucks up my hole concept... :(
added on the 2009-03-27 16:12:18 by raer raer
Quote:
it pretty much fucks up my hole concept

I couldn't find a better name for accessing non-existing data :)
added on the 2009-03-27 18:20:44 by hfr hfr
Rare[etc], if you can modify shaders, can't you just trick the scenegraph library by enabling a texture on unit 0? I assume all you're trying to do is index another texture with the coordinates in unit 0...?
thanks for answering, people. The library disabled texture coordinates when there's no texture in the unit, as bartman and psycho pointed out.
I put in a dummy texture now, which works to some extent. coordinates are still wrong though, but that is a problem in the scene graph...
added on the 2009-03-30 17:23:09 by raer raer

login