Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

A while ago, I picked up a copy of the OpenGL SuperBible fifth edition and slowly and painfully started teaching myself OpenGL the 3.3 way, after having been used to the 1.0 way from school way back when. Making things more challenging, I am primarily a .NET developer, so I was working in Mono with the OpenTK OpenGL wrapper. On my laptop, I put together a program that let the user walk around a simple landscape using a couple shaders that implemented per-vertex coloring and lighting and texture mapping. Everything was working brilliantly until I ran the same program on my desktop.

Disaster! Nothing would render! I have chopped my program down to the point where the camera sits near the origin, pointing at the origin, and renders a square (technically, a triangle fan). The quad renders perfectly on my laptop, coloring, lighting, texturing and all, but the desktop renders a small distorted non-square quadrilateral that is colored incorrectly, not affected by the lights, and not textured.

I suspect the graphics card is at fault, because I get the same result whether I am booted into Ubuntu 10.10 or Win XP. I did find that if I pare the vertex shader down to ONLY outputting the positional data and the fragment shader to ONLY outputting a solid color (white) the quad renders correctly. But as SOON as I start passing in color data (whether or not I use it in the fragment shader) the output from the vertex shader is distorted again. The shaders follow. I left the pre-existing code in, but commented out so you can get an idea what I was trying to do. I'm a noob at glsl so the code could probably be a lot better.

My laptop is an old lenovo T61p with a Centrino (Core 2) Duo and an nVidia Quadro graphics card running Ubuntu 10.10 My desktop has an i7 with a Radeon HD 4850 x2 (single card, dual GPU) from Saphire dual booting into Ubuntu 10.10 and Windows XP. The problem occurs in both XP and Ubuntu.

Can anyone see something wrong that I am missing? What is "special" about my HD 4850x2?

string vertexShaderSource = @"
#version 330

precision highp float;

uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
//uniform mat4 normal_matrix;
//uniform mat4 cmv_matrix;  //Camera modelview.  Light sources are transformed by this matrix.
//uniform vec3 ambient_color;
//uniform vec3 diffuse_color;
//uniform vec3 diffuse_direction;

in vec4 in_position;
in vec4 in_color;
//in vec3 in_normal;
//in vec3 in_tex_coords;

out vec4 varyingColor;
//out vec3 varyingTexCoords; 

void main(void)
{
  //Get surface normal in eye coordinates
  //vec4 vEyeNormal = normal_matrix * vec4(in_normal, 0);

  //Get vertex position in eye coordinates
  //vec4 vPosition4 = modelview_matrix * vec4(in_position, 0);
  //vec3 vPosition3 = vPosition4.xyz / vPosition4.w;

  //Get vector to light source in eye coordinates
  //vec3 lightVecNormalized = normalize(diffuse_direction);
  //vec3 vLightDir = normalize((cmv_matrix * vec4(lightVecNormalized, 0)).xyz);

  //Dot product gives us diffuse intensity
  //float diff = max(0.0, dot(vEyeNormal.xyz, vLightDir.xyz));

  //Multiply intensity by diffuse color, force alpha to 1.0
  //varyingColor.xyz = in_color * diff * diffuse_color.xyz;
  varyingColor = in_color;

  //varyingTexCoords = in_tex_coords;
  gl_Position = projection_matrix * modelview_matrix * in_position;
}";

        string fragmentShaderSource = @"
#version 330
//#extension GL_EXT_gpu_shader4 : enable

precision highp float;

//uniform sampler2DArray colorMap;

//in vec4 varyingColor;
//in vec3 varyingTexCoords;

out vec4 out_frag_color;

void main(void)
{
  out_frag_color = vec4(1,1,1,1);
  //out_frag_color = varyingColor;
  //out_frag_color = vec4(varyingColor, 1) * texture(colorMap, varyingTexCoords.st);
  //out_frag_color = vec4(varyingColor, 1) * texture(colorMap, vec3(varyingTexCoords.st, 0));
  //out_frag_color = vec4(varyingColor, 1) * texture2DArray(colorMap, varyingTexCoords);
}";

Note that in this code the color data is accepted but not actually used. The geometry is outputted the same (wrong) whether the fragment shader uses varyingColor or not. Only if I comment out the line varyingColor = in_color; does the geometry output correctly. Originally the shaders took in vec3 inputs, I only modified them to take vec4s while troubleshooting.

share|improve this question
    
Make sure that you are in fact using OpenGL 3.3 in both cases. glGetString(GL_VERSION) should return something like: "3.3.10317 Core Profile Context" –  Luker Jan 15 '11 at 9:05
    
The nVidia and ATI compilers have been notoriously different in the way they accept some small nuances of glsl. Be sure to check any compilation and linking logs. –  Jari Komppa Jan 15 '11 at 10:45
1  
By all rights, the shaders as you have written them should not link at all. Your vertex shader outputs varyingColor, but your fragment shader doesn't input it. That's not legal according to the spec (not that that's ever stopped NVIDIA before). AMD's drivers are rather more likely to do what the spec says. So are you sure the program links correctly? Show us the code you use to compile your shaders and link your programs. –  Nicol Bolas Dec 31 '11 at 5:34

1 Answer 1

NVidia has their own shading language called Cg, and their drivers have a common compiler between Cg and GLSL as GLSL is considered Cg compatible. Because of this, what will compile on an NVidia card may not be pure GLSL as defined by the spec. The ATI/AMD GLSL compiler is extremely strict about sticking to the spec.

Try running your shaders through AMD GPU ShaderAnalyzer to see what types of errors you will receive on ATI cards. As a bonus the tool will show you the compiled assembly of your shader.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.