3
\$\begingroup\$

So, I built some code to draw a spinning cube with a red light on the right side, and a blue one on the left. I run it on my laptop with optimus graphics, and on my desktop with nvidia. On the laptop, while running with the integrated intel, it looks ok, and also on the desktop with the nvidia, but for some reason, when running with primusrun on the laptop, I get a cube with a blue light on the right side, and a black one on the left.

This is with intel graphics:

with intel graphics

This is with the optimus nvidia card:

enter image description here

intel with only the first light:

enter image description here

nvidia with only the first light:

enter image description here

As you can see, the result is quite weird. It seems with the nvidia card, it completely ignored the first light ( red ) all the time, but I do get the specular part of it... The shader is as follows: vertex

#if (__VERSION__ > 120)
# define IN in
# define OUT out
#else
# define IN attribute
# define OUT varying
#endif // __VERSION
#define MAX_LIGHTS 8

struct SLight
    {
    vec3 Position;
    vec3 DiffuseColor;
    };

uniform SLight Lights[MAX_LIGHTS];
uniform int LightCount;

IN vec3 VertexPosition, VertexNormal;
IN vec2 VertexTexCoord;
IN vec4 VertexColor;

uniform bool ColoringEnabled, TexturingEnabled, LightingEnabled;
uniform mat4 ModelViewMatrix, ProjectionMatrix;

OUT vec2 VertexOut_TexCoord;
OUT vec4 VertexOut_Color;
OUT vec3 VertexOut_ViewSpaceNormal, VertexOut_ViewVector, VertexOut_LightVectors[MAX_LIGHTS];

void main()
    {
    vec4 ViewSpaceCoordinate = ModelViewMatrix * vec4 ( VertexPosition,     1.0 );

    // Calculate normal in view-space
    VertexOut_ViewSpaceNormal = mat3 ( ModelViewMatrix ) * VertexNormal;

    // Calculate light vectors
    for ( int cont = 0; cont < LightCount; ++cont )
        VertexOut_LightVectors[cont] = Lights[cont].Position -     ViewSpaceCoordinate.xyz;

    // Calculate view vector
    VertexOut_ViewVector = -ViewSpaceCoordinate.xyz;

    gl_Position = ProjectionMatrix * ViewSpaceCoordinate;
    VertexOut_TexCoord = VertexTexCoord;
    if ( ColoringEnabled )
        VertexOut_Color = VertexColor;
    else
        VertexOut_Color = vec4 ( 0, 0, 0, 1 );
    }

frag

#if (__VERSION__ > 120)
# define IN in
#else
# define IN varying
#endif // __VERSION __

#if ( __VERSION__ > 330 )
# define texture2D texture
#endif

#if ( __VERSION__ > 300 )
# define FRAG_OUTPUT FragOutput
out vec4 FragOutput;
#else
# define FRAG_OUTPUT gl_FragColor
#endif

#ifdef GL_ES
precision mediump float;
#endif

#define MAX_LIGHTS 8

struct SLight
    {
    vec3 Position;
    vec3 DiffuseColor;
    };

uniform SLight Lights[MAX_LIGHTS];
uniform int LightCount;

IN vec2 VertexOut_TexCoord;
IN vec4 VertexOut_Color;
IN vec3 VertexOut_ViewSpaceNormal, VertexOut_ViewVector,     VertexOut_LightVectors[MAX_LIGHTS];

uniform vec3 MaterialSpecularColor, MaterialDiffuseColor,     MaterialAmbientColor;
uniform float MaterialShininess;

uniform bool ColoringEnabled, TexturingEnabled, LightingEnabled;
uniform sampler2D TextureSampler;

void main()
    {
    vec4 LightResult, FinalColor;
    LightResult = vec4 ( 0, 0, 0, 1 );
    if ( LightingEnabled )
        {
        for ( int cont = 0; cont < LightCount; ++cont )
            {
            // Normalize the incoming N, L and V vectors
            vec3 N = normalize ( VertexOut_ViewSpaceNormal );
            vec3 L = normalize ( VertexOut_LightVectors[cont] );
            vec3 V = normalize ( VertexOut_ViewVector );
            vec3 H = normalize ( L + V );

            // Compute the diffuse and specular components for each     fragment
            vec3 diffuse = max ( dot ( N, L ), 0.0 ) *     MaterialDiffuseColor * Lights[cont].DiffuseColor;
            vec3 specular = pow ( max ( dot ( N, H ), 0.0 ), MaterialShininess ) * MaterialSpecularColor;

            // Final color contribution from this light
            LightResult += vec4 ( diffuse + specular, 1.0 );
            }
        }
    else
        LightResult = vec4 ( 1, 1, 1, 1 );

    if ( TexturingEnabled )
        FinalColor = texture2D ( TextureSampler, VertexOut_TexCoord );
    else if ( ColoringEnabled )
        FinalColor = VertexOut_Color;
    else
        FinalColor = vec4 ( 1, 1, 1, 1 );

    FRAG_OUTPUT = LightResult * FinalColor;
    }

I'm using a core opengl profile. Intel integrated gives me opengl 3.0, with glsl 1.30. With the nvidia card, I get opengl 4.4 and glsl 4.4 ( version string is 4.40 NVIDIA via Cg compiler ) The desktop nvidia card gets me the same version strings. What can I be doing wrong?

EDIT: I am indeed providing a version definition to the shader with this:

snprintf ( ShaderHeader, sizeof ( ShaderHeader ), "#version %d\n", In_GLSLVersion.Major * 100 + In_GLSLVersion.Minor );

and then calling glShaderSource with 2 shader sources neatly placed in an array...

If i call glGetShaderSource on the compiled object, i do get the correct source with the version info. sorry for omitting that.

EDIT #2: So, took both suggestions presented here. vertex:

#if (__VERSION__ > 120)
# define IN in
# define OUT out
#else
# define IN attribute
# define OUT varying
#endif // __VERSION
#define MAX_LIGHTS 8

struct SLight
{
vec3 Position;
vec3 DiffuseColor;
};

uniform SLight Lights[MAX_LIGHTS];
uniform int LightCount;

IN vec3 VertexPosition, VertexNormal;
IN vec2 VertexTexCoord;
IN vec4 VertexColor;

uniform bool ColoringEnabled, TexturingEnabled, LightingEnabled;
uniform mat4 ModelViewMatrix, ProjectionMatrix;

OUT vec2 VertexOut_TexCoord;
OUT vec4 VertexOut_Color;
OUT vec3 VertexOut_ViewSpaceNormal, VertexOut_ViewVector, VertexOut_LightVectors[MAX_LIGHTS];

void main()
{
vec4 ViewSpaceCoordinate = ModelViewMatrix * vec4 ( VertexPosition, 1.0f );

// Calculate normal in view-space
VertexOut_ViewSpaceNormal = mat3 ( ModelViewMatrix ) * VertexNormal;

// Calculate light vectors
for ( int cont = 0; cont < LightCount; ++cont )
    VertexOut_LightVectors[cont] = Lights[cont].Position - ViewSpaceCoordinate.xyz;

// Calculate view vector
VertexOut_ViewVector = -ViewSpaceCoordinate.xyz;

gl_Position = ProjectionMatrix * ViewSpaceCoordinate;
VertexOut_TexCoord = VertexTexCoord;
if ( ColoringEnabled )
    VertexOut_Color = VertexColor;
else
    VertexOut_Color = vec4 ( 0.0f, 0.0f, 0.0f, 1.0f );
}

frag:

#ifdef GL_ES
precision mediump float;
#endif

#if (__VERSION__ > 120)
# define IN in
#else
# define IN varying
#endif // __VERSION __

#if ( __VERSION__ > 330 )
# define texture2D texture
#endif

#if ( __VERSION__ > 300 )
# define FRAG_OUTPUT FragOutput
out vec4 FragOutput;
#else
# define FRAG_OUTPUT gl_FragColor
#endif

#define MAX_LIGHTS 8

struct SLight
{
vec3 Position;
vec3 DiffuseColor;
};

uniform SLight Lights[MAX_LIGHTS];
uniform int LightCount;

IN vec2 VertexOut_TexCoord;
IN vec4 VertexOut_Color;
IN vec3 VertexOut_ViewSpaceNormal, VertexOut_ViewVector, VertexOut_LightVectors[MAX_LIGHTS];

uniform vec3 MaterialSpecularColor, MaterialDiffuseColor, MaterialAmbientColor;
uniform float MaterialShininess;

uniform bool ColoringEnabled, TexturingEnabled, LightingEnabled;
uniform sampler2D TextureSampler;

void main()
{
vec4 LightResult, FinalColor;
LightResult = vec4 ( 0.0f, 0.0f, 0.0f, 1.0f );
if ( LightingEnabled )
    {
    for ( int cont = 0; cont < LightCount; ++cont )
        {
        // Normalize the incoming N, L and V vectors
        vec3 N = normalize ( VertexOut_ViewSpaceNormal );
        vec3 L = normalize ( VertexOut_LightVectors[cont] );
        vec3 V = normalize ( VertexOut_ViewVector );
        vec3 H = normalize ( L + V );

        // Compute the diffuse and specular components for each fragment
        vec3 diffuse = max ( dot ( N, L ), 0.0f ) * MaterialDiffuseColor * Lights[cont].DiffuseColor;
        vec3 specular = pow ( max ( dot ( N, H ), 0.0f ), MaterialShininess ) * MaterialSpecularColor;

        // Final color contribution from this light
        LightResult += vec4 ( diffuse + specular, 1.0f );
        }
    }
else
    LightResult = vec4 ( 1.0f, 1.0f, 1.0f, 1.0f );

if ( TexturingEnabled )
    FinalColor = texture2D ( TextureSampler, VertexOut_TexCoord );
else if ( ColoringEnabled )
    FinalColor = VertexOut_Color;
else
    FinalColor = vec4 ( 1.0f, 1.0f, 1.0f, 1.0f );

FRAG_OUTPUT = LightResult * FinalColor;
}

Still the same result... I am now inserting a hard coded #version 440 on the top while this problem lasts. Also tried disabling all texture-related stuff ( even though I knew it wouldn't affect it ), and same result... Any more ideas?

\$\endgroup\$
  • \$\begingroup\$ Not 100% sure but: opengl.org/wiki/GLSL_:_common_mistakes Try using texture instead of texture2D. I'm having lots of problems with NVIDIA as-well. Justh ave to be very specific. declare everything that are floats as floats. vec4(0.0f, 0.0f, 0.0f, 1.0f) instead of vec4(0, 0, 0, 1). Go through each variable/uniform, ensure it is being used. \$\endgroup\$ – mythos Mar 18 '16 at 3:04
  • 1
    \$\begingroup\$ @sakul_ca I had those problems too. You just need to specify a version explicitely using #version. Then your driver will ensure that only proper syntax is used. At least nvidia driver does this. I had NO problems with incompatible shaders after that. OP, you should add this directive an fix all errors that you will get after this. \$\endgroup\$ – HolyBlackCat Mar 18 '16 at 13:39
  • \$\begingroup\$ Of course, you select lowest GLSL version you want to support. \$\endgroup\$ – HolyBlackCat Mar 18 '16 at 14:08
  • \$\begingroup\$ Sorry, my mistake. I AM indeed appending the #version directive before all that. Forgot to say that. I just get the current GLSL version, and paste it into a string, and pass it to glShaderSource. Edited the question to show this \$\endgroup\$ – Joao Pincho Mar 18 '16 at 14:43
  • \$\begingroup\$ @sakul_ca I will try again later today when i get home, with your suggestion about explicit floats. Maybe that's it. \$\endgroup\$ – Joao Pincho Mar 18 '16 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.