• Advertisement
Sign in to follow this  

Multiple textures in cg fragment program

This topic is 3037 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, I've been following the phong shading example in the cg tutorial (http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter05.html). The example doesn't handle textures at all, so I first added the regular texture, by adding a uniform variable - "uniform sampler2D decal". Then, I multiple the caclulated color, with the texture color (using "tex2D(decal0, texCoord0)"). Now, I need to also add the lightmap texture. I'm using the GL_ARB_multitexture to do it without the shaders. I'm wondering, how do I pass the second bounded texture (the lightmap) to the fragment program? thanks, Vince

Share this post


Link to post
Share on other sites
Advertisement
Are you binding the light map as the second active texture? If not, look into glActiveTexture. You also need to set the value of the second sampler to 1, i.e. the second active texture.

Basically, something along the lines of:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, decal);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, lightmap);

// ...

// These are the opengl calls. If you are using only CG, there's a cg call that
// does this. You're just telling the program to use the texture bound to
// GL_TEXTURE0 for your decal, and use the texture bound to GL_TEXTURE1 for your
// lightmap.
glUniform1i(locationOfDecalSamplerUniform, 0);
glUniform1f(locationOfLightmapSamplerUniform, 1);



See also: Common mistakes in binding textures

Share this post


Link to post
Share on other sites
When I render the scence, I indeed use glActiveTexture() function, and without shaders everything is OK. The fragment program I use (which is a slight modification from the one in the tutorial, that doesn't handle texture at all), is as follows


void C5E3f_basicLight(float2 texCoord0 : TEXCOORD0,
float2 texCoord1 : TEXCOORD1,
float4 position : TEXCOORD2,
float3 normal : TEXCOORD3,

out float4 color : COLOR,

uniform sampler2D decal0,
uniform sampler2D decal1,

uniform float3 globalAmbient,
uniform float3 lightColor,
uniform float3 lightPosition,
uniform float3 eyePosition,
uniform float3 Ka,
uniform float3 Kd,
uniform float3 Ks,
uniform float shininess)
{
globalAmbient = (0.1,0.1,0.1);
lightColor = (0.9,0.9,0.9);

lightPosition = (100, 0, 0, 1);
eyePosition = (0, 0, 100, 1);

float3 P = position.xyz;
float3 N = normalize(normal);

// Compute ambient term
float3 ambient = Ka * globalAmbient;

// Compute the diffuse term
float3 L = normalize(lightPosition - P);
float diffuseLight = max(dot(L, N), 0);
float3 diffuse = Kd * lightColor * diffuseLight;

// Compute the specular term
float3 V = normalize(eyePosition - P);
float3 H = normalize(L + V);
float specularLight = pow(max(dot(H, N), 0), shininess);
if (diffuseLight <= 0) specularLight = 0;
float3 specular = Ks * lightColor * specularLight;

color.xyz = (ambient + diffuse + specular)*tex2D(decal0, texCoord0);

color.xyz = color.xyz + tex2D(decal1, texCoord1);

color.w = 1;
}



It seems that although, I'm adding the second texture, there is no effect on the result.

Share this post


Link to post
Share on other sites
Calling glActiveTexture() is not enough. You need to bind samplers probably. I am not a Cg expert, but I see you have

uniform sampler2D decal0,
uniform sampler2D decal1,

You need to setup these 2 otherwise they both are equal to 0.

With GLSL, it is done like this
glUseProgram(TheShader); //Binding the shader
glUniform1i(locationOfDecalSamplerUniform, 0);
glUniform1i(locationOfLightmapSamplerUniform, 1);

Share this post


Link to post
Share on other sites
You need to specify textureunits to sample from, eg:
GL-code:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, decal);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, lightmap);


Cg-code:

uniform sampler2D decal: TEXUNIT0,
uniform sampler2D lightmap: TEXUNIT1,

Share this post


Link to post
Share on other sites
Thanks all for the suggestions.

stalef - what you suggested works fine. But now I came to the problem, that sometimes I have a lightmap and sometimes not. Can I use the same cg program (that accepts two TEXUNIT semantics parameters), even I only use one texture? For some reason, only after I rendere an object with a lightmap, I can render also objects that don't have a lightmap...

Share this post


Link to post
Share on other sites
Yes, you can use the same program. Use a uniform flag to indicate if you want to use the lightmap or not.


void FragmentProgram( uniform sampler2D decal : TEXUNIT0,
uniform sampler2D lightmap : TEXUNIT1,
uniform int ApplyLightmap,
....
out float4 Result : COLOR0 )
{
....
if( ApplyLightmap == 1 )
{
// Apply your lightmap here
}
....
}


Share this post


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

  • Advertisement