• Advertisement
Sign in to follow this  

GLSL - Using multiple textures

This topic is 4432 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there! I'm trying to create a simple shader that uses multiple textures (using one texture worked flawlessly). Here's the code (I use the same set of coords for both textures, is that ok?):
uniform sampler2D tex1;
uniform sampler2D tex2;

void main()
{
	vec4 col1 = texture2D( tex1, gl_TexCoord[0].st );
	vec4 col2 = texture2D( tex2, gl_TexCoord[0].st );

	//gl_FragColor = col1;
	gl_FragColor = col2;
}


The strange thing is that the shader always displays the same texture, no matter which of the two lines I comment out! Here's the code of my application, where the textures are set and the quad is drawn:
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
bind(texColor);

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
bind(texColor);

glActiveTextureARB(GL_TEXTURE0_ARB);

glBegin(GL_QUADS);

glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.0f, 0.0f );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0.0f, 0.0f );
glVertex3f( -20.0f, -20.0f, 0.0f );

glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.0f, 1.0f );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0.0f, 1.0f );
glVertex3f( -20.0f,  20.0f, 0.0f );

glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1.0f, 1.0f );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1.0f, 1.0f );
glVertex3f(  20.0f,  20.0f, 0.0f );

glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1.0f, 0.0f );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1.0f, 0.0f );
glVertex3f(  20.0f, -20.0f, 0.0f );

glEnd();

IMHO the whole code is very simple and nothing can go wrong. But obviously it does. I always see the texture in unit 0, no matter what I do (of course, when I switch the two bind-lines I see the other texture). How can that be?

Share this post


Link to post
Share on other sites
Advertisement
yes, using the same texture coords for both texture lookups is fine.

The reason why it uses the same texture is, although you bind the textures to different units, you never tell OpenGL that the samplers in your code should hold any value, as such they both default to 0, meaning that both texture lookups come from texture unit 0.

Share this post


Link to post
Share on other sites
there could be many things (u havent posted the relevant parts) in what u have posted this is wrong

vec4 col1 = texture2D( tex1, gl_TexCoord[0].st );
vec4 col2 = texture2D( tex2, gl_TexCoord[0].st );

is not

glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.0f, 0.0f );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0.0f, 0.0f );

but shouldnt make a diff
all the glEnable(GL_TEXTURE_2D); etc calls arent needed
also u seem to binding the same texture to different texture units

Share this post


Link to post
Share on other sites
Need to see the code for your bind() function.
You need to bind the texture object to the texture unit and then set the uniform shader variables to the texture unit number:


GLint loc;

glActiveTexture(<texture unit>);
glEnable(<texture target>);
loc = glGetUniformLocation(<shader program object>, <texture variable name>);
glUniform1i(loc, <texture unit>);
glBindTexture(<texture target>, <texture object>);



Share this post


Link to post
Share on other sites
Thanks for the reply! That sounds good ;-)
I added the following code to my initialization method:


// Get the texture's OpenGL names
int tex1 = texColor->mTexID;
int tex2 = texLight->mTexID;

// Get the locations of the variables
int tex1Loc, tex2Loc;
tex1Loc = glGetUniformLocationARB( prgmBMap, "tex1" );
tex2Loc = glGetUniformLocationARB( prgmBMap, "tex2" );

// Set the variables
glUniform1fARB( tex1Loc, tex1 );
glUniform1fARB( tex2Loc, tex2 );



The sad thing is that this does not help :-(
What am I doing wrong?

Share this post


Link to post
Share on other sites
"also u seem to binding the same texture to different texture units"

Ooopps, copy&paste bug ;-)
In my app these are two diferent textures...

Share this post


Link to post
Share on other sites
Hum! Good to know...
So I changed

int tex1 = texColor->mTexID;
int tex2 = texLight->mTexID;

to

int tex1 = 0;
int tex2 = 1;

But it still aint working. Same problem as before.

Share this post


Link to post
Share on other sites
just as a sanity check, are you sure its using your shader?
try changing the shader so it just writes out red all the time (dont touch the rest of the code).
Also, I ment to ask, which texture is it showing?

Share this post


Link to post
Share on other sites
The first texture (unit 0) is shown, and yes, the shader works. [help]

Share this post


Link to post
Share on other sites
The locations are set 0 and 1 after the call. Is that a good value?

Maybe I'll post more of the code:

Vertex shader:


void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}




Fragment shader:


uniform sampler2D tex1;
uniform sampler2D tex2;

void main()
{
vec4 col1 = texture2D( tex1, gl_TexCoord[0].st );
vec4 col2 = texture2D( tex2, gl_TexCoord[0].st );

//gl_FragColor = col1;
gl_FragColor = col2;

}




Application:



#include "Headers.h"


PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB ;
PFNGLDELETEOBJECTARBPROC glDeleteObjectARB ;
PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB ;
PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB ;
PFNGLSHADERSOURCEARBPROC glShaderSourceARB ;
PFNGLCOMPILESHADERARBPROC glCompileShaderARB ;
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
PFNGLATTACHOBJECTARBPROC glAttachObjectARB ;
PFNGLGETINFOLOGARBPROC glGetInfoLogARB ;
PFNGLLINKPROGRAMARBPROC glLinkProgramARB ;
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB ;
PFNGLUNIFORM4FARBPROC glUniform4fARB ;
PFNGLUNIFORM3FARBPROC glUniform3fARB ;
PFNGLUNIFORM1FARBPROC glUniform1fARB ;
PFNGLUNIFORM1IARBPROC glUniform1iARB ;
PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB;
PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB ;
PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;

CTexture* texColor;
CTexture* texLight;


GLhandleARB prgmBMap,frgBMap,vrtBMap; //Aspects of the shader, and the shader itself


void createExtensions( void )
{
... LEFT OUT
}


bool CGame::Init( void )
{
InitView();
glEnable(GL_TEXTURE_2D);
glDisable(GL_CULL_FACE);

createExtensions();





char *vs,*fs; //The textfiles
prgmBMap = glCreateProgramObjectARB(); //Create the shader

// Create the two parts of the shader
vrtBMap = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
frgBMap = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
//Read in the shader
vs = textFileRead("Shaders/Test1.vert"); //assuming this is the path and name!
fs = textFileRead("Shaders/Test1.frag");
//Create temporary variables and compile the shaders
const char * vvBMap = vs;
const char * ffBMap = fs;

glShaderSourceARB(vrtBMap, 1, &vvBMap,NULL);
glShaderSourceARB(frgBMap, 1, &ffBMap,NULL);

free(vs);
free(fs);

glCompileShaderARB(vrtBMap);
glCompileShaderARB(frgBMap);


int cStatus = 0;
glGetObjectParameterivARB( vrtBMap, GL_OBJECT_COMPILE_STATUS_ARB, &cStatus );
if( cStatus != 1 )
{
int len, tmp;
glGetObjectParameterivARB( vrtBMap, GL_OBJECT_INFO_LOG_LENGTH_ARB, &len );

mc.mLog << "Cannot compile vertex shader! Infolog (length " << len << "):<br>";

char* logText = new char[len];
glGetInfoLogARB( vrtBMap, len, &tmp, logText );
mc.mLog << logText;
delete[] logText;

mc.mLog << "<br>";
}//end if

glGetObjectParameterivARB( frgBMap, GL_OBJECT_COMPILE_STATUS_ARB, &cStatus );
if( cStatus != 1 )
{
int len, tmp;
glGetObjectParameterivARB( frgBMap, GL_OBJECT_INFO_LOG_LENGTH_ARB, &len );

mc.mLog << "Cannot compile fragment shader! Infolog (length " << len << "):<br>";

char* logText = new char[len];
glGetInfoLogARB( frgBMap, len, &tmp, logText );
mc.mLog << logText;
delete[] logText;

mc.mLog << "<br>";
}//end if


//put the parts of the shader into the shader.
glAttachObjectARB(prgmBMap,vrtBMap);
glAttachObjectARB(prgmBMap,frgBMap);

// Free shit
glDeleteObjectARB(vrtBMap);
glDeleteObjectARB(frgBMap);

//Make the shader ready to go!
glLinkProgramARB(prgmBMap);


glUseProgramObjectARB(prgmBMap);


// CREATE TEXTURES ----------------------------------

texColor = mc.mTexMan->add( "data/texColor.bmp", true );
texLight = mc.mTexMan->add( "data/texLight.bmp", true );

// Texture units
int tex1 = 0;
int tex2 = 1;

// Get the locations of the variables
int tex1Loc, tex2Loc;
tex1Loc = glGetUniformLocationARB( prgmBMap, "tex1" );
tex2Loc = glGetUniformLocationARB( prgmBMap, "tex2" );

// Set the variables
glUniform1fARB( tex1Loc, tex1 );
glUniform1fARB( tex2Loc, tex2 );

return true;
}//end Init


bool CGame::UnInit( void )
{
glUseProgramObjectARB(0);

return true;
}//end Init


void CGame::Update( float dt )
{
// Common preperations
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );


mc.mTexMan->glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
mc.mTexMan->bind(texColor);

mc.mTexMan->glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
mc.mTexMan->bind(texLight);

mc.mTexMan->glActiveTextureARB(GL_TEXTURE0_ARB);


glBegin(GL_QUADS);

mc.mTexMan->glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.0f, 0.0f );
mc.mTexMan->glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0.0f, 0.0f );
glVertex3f( -20.0f, -20.0f, 0.0f );

mc.mTexMan->glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0.0f, 1.0f );
mc.mTexMan->glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 0.0f, 1.0f );
glVertex3f( -20.0f, 20.0f, 0.0f );

mc.mTexMan->glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1.0f, 1.0f );
mc.mTexMan->glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1.0f, 1.0f );
glVertex3f( 20.0f, 20.0f, 0.0f );

mc.mTexMan->glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 1.0f, 0.0f );
mc.mTexMan->glMultiTexCoord2fARB( GL_TEXTURE1_ARB, 1.0f, 0.0f );
glVertex3f( 20.0f, -20.0f, 0.0f );

glEnd();

}//end Init



Thanks so much for your help!

Share this post


Link to post
Share on other sites
That does look correct to me. Have you double checked that both textures are really working? Bind the second texture to unit 0 and it should appear instead of the first texture.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement