Strange behaviour of a uniform integer variable using GLSL

I’m coding a graphic engine using OpenGL + GLSL shaders. Currently, I manage several lights in my scene (per-pixel lighting mode). So, I have a loop to access to the properties of all lights in the scene for each pixel. If I put the light count value directly in the loop condition there’s not problem but if I want to do this job in a dynamic way by sending an integer uniform variable from my C++ code it does not work. But I checked in the fragment shader the value of the variable and this one is correct.


    for(y=0; y<2; y++)
    {
        linear_color += apply_lights(light_par[y],worldPos,worldNormal,surfaceToCamera,mat_specular,mat_diffuse,mat_transparent,light_type) ;
    }

below one does not work correctly


    for(y=0; y<no_of_lights; y++)
    {
        linear_color += apply_lights(light_par[y],worldPos,worldNormal,surfaceToCamera,mat_specular,mat_diffuse,mat_transparent,light_type) ;
    }

I have passed no_of_lights as uniform integer variable.


uniform int no_of_lights;

In C++,


GLuint unilight_no = glGetUniformLocation(program, "no_of_lights");
glUniform1i(unilight_no, 2);

What may be the issue?

Thanks in advance,

You haven’t really provided enough information here:

Are you checking for shader compile and link errors, as well as GL errors?
What #version of GLSL are your shaders targeting?
What GPU and GPU driver are you running this on?
What is “light_par[]”? Let’s see the shader declaration for it.
Does light_par[] involve uniform blocks and/or samplers?
Are you doing anything else in your loop with “y” or “no_of_lights” besides indexing light_par[]?

-> No shader compilation and linking error
-> GLSL Version 3
-> GPU Driver : i915
-> light_par[] declaration is a uniformblock

In GLSL,


        struct param
        {
            vec4 color;
            vec3 position;
            vec4 spot;

            float const_atten;
            float linear_atten;
            float quad_atten;
            float fall_off_angle;
            float fall_off_exp;

        };

        layout(std140) uniform light_block
        {
            param light_par[2];
        };

In CPP,


        struct light_source
         {

            glm::vec4 color;
            glm::vec3 position;
            float tmp;//for padding
            glm::vec4 spot;

            float const_atten;
            float linear_atten;
            float quad_atten;
            float fall_off_angle;
            float fall_off_exp;

        };

        GLuint program_index = glGetUniformBlockIndex(program_handle, "light_block");

        glUniformBlockBinding(program, program_index, ubo_index);

        glGenBuffers(1, &ubo);

          glBindBuffer(GL_UNIFORM_BUFFER, ubo);

        glBufferData(GL_UNIFORM_BUFFER, sizeof(light) * num_light_nodes, NULL, GL_STREAM_DRAW);

        glBindBufferBase(GL_UNIFORM_BUFFER, program_index, ubo);

        glBindBuffer(GL_UNIFORM_BUFFER, 0);


          glBindBuffer(GL_UNIFORM_BUFFER, ubo);

          glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(light_source) * num_light_nodes , light);

          glBindBuffer(GL_UNIFORM_BUFFER, 0);

-> No, I am using “no_of_lights” only in that loop for indexing ligt_par[].

No one knows?

There’s no such thing. The GLSL version numbers jumped from 1.50 (for OpenGL 3.2) to 3.30 (for OpenGL 3.3). Ensure that you have a valid #version directive; conforming implementations will use GLSL 1.1 for shaders lacking a #version directive.

Also: does using light_par.length() work?

You could be dealing with a driver bug.

See this for some relevant background.

Failing that, post a short stand-alone GLUT test program that illustrates the problem so folks can take a closer look at this, try it on their drivers/GPUs, and give you feedback.

Thanks for your reply :). I solved the issue.

In C++,

Code cpp:

GLuint unilight_no = glGetUniformLocation(program, “no_of_lights”);
glUniform1i(unilight_no, 2);

I had added the above into a loop. That’s why it sends wrong constant value to the shader for each time the loop execute. Now i have added it before that loop it’s working fine.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.