# GLSL to Cg: why is the effect different?

With reference to this question, where I was trying to make the shader compile, I am now trying to make an effect appear. The effect can be shown here, through a GLSL shader:

But when I use the equivalent Cg shader, the result becomes this:

Using the same images (color map + normal map) and the same code (except the way to retrieve variables).

Here is the original GLSL shader;

uniform sampler2D color_texture;
uniform sampler2D normal_texture;

void main() {
// Extract the normal from the normal map
vec3 normal = normalize(texture2D(normal_texture, gl_TexCoord[0].st).rgb * 2.0 - 1.0);

// Determine where the light is positioned (this can be set however you like)
vec3 light_pos = normalize(vec3(1.0, 1.0, 1.5));

// Calculate the lighting diffuse value
float diffuse = max(dot(normal, light_pos), 0.0);

vec3 color = diffuse * texture2D(color_texture, gl_TexCoord[0].st).rgb;

// Set the output color of our current pixel
gl_FragColor = vec4(color, 1.0);
}


And here is the Cg shader I wrote;

struct fsOutput {
float4 color : COLOR;
};

uniform sampler2D color_texture : TEXUNIT0;
uniform sampler2D normal_texture : TEXUNIT1;

fsOutput FS_Main(float2 colorCoords : TEXCOORD0,
float2 normalCoords: TEXCOORD1)
{

fsOutput fragm;

float4 anorm = tex2D(normal_texture, normalCoords);
float3 normal = normalize(anorm.rgb * 2.0f - 1.0f);
float3 light_pos = normalize(float3(1.0f, 1.0f, 1.5f));
float diffuse = max(dot(normal, light_pos), 0.0);
float3 color = diffuse * tex2D(color_texture, colorCoords).rgb;
fragm.color = float4(color,1.0f);
return fragm;
}


Please let me know if something needs to be changed in order to obtain the effect, or if you need the C++ code.

• Thanks, you're right. Edited (the problem remains the same). – Ety Jul 22 '14 at 11:36

They are not equivalent. In the GLSL shader you use the same texture coordinate for your diffuse and normal map (gl_TexCoord[0]). In the CG shader you use separate ones (TEXCOORD0 and TEXCOORD1, which is presumably not set).

• Really? I tried to find an equivalent to "gl_TexCoord[0]" but could only find this! Can you help with a suggestion? – Ety Jul 22 '14 at 12:01
• Yes, TEXCOORD0 is the equivalent for gl_TexCoord[0], which you are using as texture coordinates for both the diffuse and normal map in the GLSL shader. But you use TEXCOORD1 in the CG shader, which would be gl_TexCoord[1] in a GLSL shader. You could just use colorCoords in the CG shader for both your diffuse and normal map lookup and it should work. Or you can supply a separate set of texture coordinates just for the normal map. – kolrabi Jul 22 '14 at 12:12
• Sorry but that won't work (colorCoords for both). Still the same result. – Ety Jul 22 '14 at 12:28
• Okay, then it's probably not that. What about the normal map itself? Is its content correct, is it bound to the corrent texture state? Try setting color to just the .rgb values of anorm. Does the result look like your normal map? – kolrabi Jul 22 '14 at 13:10
• Absolutely not! The result is still the same! And yes, the normal map is correct because it works wonderful in GLSL as I said. The shader is correctly bound because if I remove some key word it won't execute at all. – Ety Jul 22 '14 at 13:20

The shader was fine. But when I tried to use other shaders I realized what was wrong.

It was the C++ code that was lacking lines (rrr!! This is the reason why I hate shaders! It's so complicated to make a link in your head between every line you write in one file and what must be written in the other for it to be recognized!).

In the display function, I had:

[clearing + loading identity matrix]

cgGLBindProgram(VertexProgram);
cgGLBindProgram(FragmentProgram);

[buffers swapping]


The very important thing that was missing before binding was:

cgGLEnableProfile(VertexProfile);
cgGLEnableProfile(FragmentProfile);


Only then the shader effect is displayed proprerly. Simple mistakes make worst time wastes!