Skip to main content
GameDev.net gamedev.net
🔒 Locked

GLSL and multitexturing

Started by cwhite Jan 29, 2006 at 3:57 PM 6 replies 1.6k views
Original Post
cwhite
cwhite
I have been having problems with GLSL and multi-texturing. First off, I know my card supports multi-texturing because I have implemented it before without a shader. However, I am trying to do some unique shading with two textures that can't be done with the standard issue texture combining functions. Here is how I initialize my textures

glGenTextures( 1, &fbTexture );

glBindTexture( GL_TEXTURE_2D, fbTexture );
	
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 
	          256, 256, 
	          0, GL_RGBA, GL_UNSIGNED_BYTE, testTexture2 );

glGenTextures( 1, &fbTexture2 );

glBindTexture( GL_TEXTURE_2D, fbTexture2 );
	
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
	
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 
	          256, 256, 
	          0, GL_RGBA, GL_UNSIGNED_BYTE, testTexture1 );

Where testTexture1 and testTexture2 are procedurally generated textures meant to be very distinguishable from one another for the purpose of debugging (one of them is perlin noise and the other is solid white). Before rendering, I set up my texture units as follows:

glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fbTexture);

glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fbTexture2);

In the fragment shader, I set up my samplers as follows

uniform sampler2D tex1, tex2;

From everything I've read or seen about GLSL, this should bind tex1 to GL_TEXTURE0 and tex2 to GL_TEXTURE1. However, the following two statements in the fragment shader will give the exact same value:

gl_FragColor.rgb = texture2D(tex1, gl_TexCoord[0].st).rgb; //gives correct output
gl_FragColor.rgb = texture2D(tex2, gl_TexCoord[0].st).rgb; //gives same output as line above, which is highly incorrect, because tex2 != tex1

Any thoughts on this? Is there some arcane state that can screw this up? Have I initialized something wrong? This is extremely frustrating. Rate++ for tips that lead to a solution.
Expandable
Expandable
If I remember correctly you have to assign the textureID to your tex2 uniform sampler2D in the shader.

I had a multi-textured cube which worked fine using the fixed function pipeline, and I thought the textures would be automatically bound to the fragment shader. Well, the first texture was automatically bound, but not the second one. I didn't investigate this further, however.
cwhite
cwhite
Quote:
Original post by Expandable
If I remember correctly you have to assign the textureID to your tex2 uniform sampler2D in the shader.

I had a multi-textured cube which worked fine using the fixed function pipeline, and I thought the textures would be automatically bound to the fragment shader. Well, the first texture was automatically bound, but not the second one. I didn't investigate this further, however.


Expandable... do you remember the syntax for doing that? I don't see any references to this in the Orange book or in any of the on-line tutorials. Maybe it's something that has to be done only on older cards.
Expandable
Expandable
I just found the sourcecode again, this is the part that does the binding:

glUniform1i(glGetUniformLocation(shaderProgram, "checker"), tex1);glUniform1i(glGetUniformLocation(shaderProgram, "face"), tex2);


What it does is simple: It looks for a uniform location (glGetUniformLocation), shaderProgram holds the currently active shader program, "checker" and "face" are the names of the sampler2Ds in the shader, and tex1 and tex2 are the texture IDs generated by OpenGL (glGenTextures).

If you don't use OpenGL 2.0, you have to use the ARB-extension-style function names.

If I remove those lines, no multitexturing is being performed. I find that a bit strange, I also thought that the texture binding to the shader would be done automatically by OpenGL.
Expandable
Expandable
Well, apparently this is how it has to be done. In "More OpenGL Game Programming" they also use the code I posted above to tell the GLSL program where to sample from. Strange though that it works on the first texture just fine...
cwhite
cwhite
Quote:
Original post by Expandable
Well, apparently this is how it has to be done. In "More OpenGL Game Programming" they also use the code I posted above to tell the GLSL program where to sample from. Strange though that it works on the first texture just fine...


Strange indeed. It works now. Thank you.
Expandable
Expandable
I'm glad that I could help ;)
StPapyna
StPapyna
glUniform1i(),send the number of tex unit

in vertex shader you should add this:
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_MultiTexCoord1;

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.