Using Multitexturing With GLSL

Published May 05, 2009
Advertisement
Hi There!

Time for another entry in my o so very exciting Development Journal (It will become more interesting when I have decent screenshots to show you).

I recently implemented multitexturing into my graphics engine. Doing so with the Fixed Function Pipeline (FFP) is relatively straightforward, and indeed doing it with GLSL (or CG for that matter) is also relatively simple. However, there are a number of things that you need to watch out for.

My first mistake was that I assumed then when I declared a uniform sampler2d in my shader, that it would know which Texture Unit to reference, based on the order in which the samplers were declared. This is what I struggled with. I had told OpenGL to do multitexturing, binding different textures to different Texture Units, and I had my GLSL getting the Texel from each texture sampler based on the texture coordinates. (I've posted my code below).

Now in hindsight this seems like a really stupid, and I'm not entirely sure why I thought it. Anyway, after much searching on Google I finally came across the fact that I need to manually set which Texture Unit each Sampler refers to. This is done simply using the line:

glUniform1i(loc, texUnit);


Where loc is the value returned from glGetUniformLocation(), and texUnit is the Texture Unit you want to have assigned to that Sampler.

After I called this function, it all started working.

There are tutorials out there which deal with the FFP part of multitexturing, and there are tutorials out there which deal with the GLSL part of multitexturing. Howevere, those dealing with GLSL don't deal with the calls you need to perform within your application. Below is my code which allows me to do multitexturing. I hope that my mistakes will help benefit other people.

Code from my C++ App:
glActiveTextureARB(GL_TEXTURE0_ARB);glBindTexture(GL_TEXTURE_2D, models->Materials[j].textureID[0]);glUniform1i(glGetUniformLocation(models->EffectProgramID, "diff_Map"), 0);glActiveTextureARB(GL_TEXTURE1_ARB);glBindTexture(GL_TEXTURE_2D, models->Materials[j].textureID[1]);glUniform1i(glGetUniformLocation(models->EffectProgramID, "norm_Map"), 1);glActiveTextureARB(GL_TEXTURE2_ARB);glBindTexture(GL_TEXTURE_2D, models->Materials[j].textureID[2]);glUniform1i(glGetUniformLocation(models->EffectProgramID, "fx_Map"), 2);glActiveTextureARB(GL_TEXTURE3_ARB);glBindTexture(GL_TEXTURE_2D, models->Materials[j].textureID[3]);glUniform1i(glGetUniformLocation(models->EffectProgramID, "misc_Map"), 3);


Code from my GLSL Shader:
uniform sampler2D diff_Map;	// Diffuse Mapuniform sampler2D norm_Map;	// Normal Mapuniform sampler2D fx_Map;	// FX Mapuniform sampler2D misc_Map;	// Misc Mapvoid main(){	vec4 diffuse = texture2D(diff_Map, gl_TexCoord[0].st);	vec4 normal = texture2D(norm_Map, gl_TexCoord[0].st);	gl_FragColor = diffuse * 0.5;}
Previous Entry Frame Buffer Object
0 likes 1 comments

Comments

zedz
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, models[i]->Materials[j].textureID[0]);
glUniform1i(glGetUniformLocation(models[i]->EffectProgramID, "diff_Map"), 0);

unlike the first two commands
the glUniform..(...) dont need to be set each time u use the shader
thus only set them when u create the shader, the sjader will remember the uniforms values, the only time u need to call glUniform again is if u change the uniforms (something that u wont be doing with texture units)
May 05, 2009 01:49 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement