Problem passing point lights in fragment shader

I’m trying to pass a point light to a CalcPoint function in my fragment shader. Here’s the relevant code.


#define TOTAL_LIGHTS 2
struct PLight
{
    vec4 pos;

    vec4 diff;
    vec4 spec;
    vec4 amb;

    float con;
    float lin;
    float quad;
};

layout(std140) uniform Light
{
    PLight pLights[TOTAL_LIGHTS];
}light;

vec3 CalcPoint(in PLight p) 
{
    ...
}

When I pass in the point light from main using hard coded values everything works fine.


void main()
{
    ...
    pointLight += CalcPoint(light.pLights[0]);
    pointLight += CalcPoint(light.pLights[1]);
    ...
}

But, when I try to use a loop, The second light is not calculated correctly.


for(int i = 0; i < TOTAL_LIGHTS; i++)
    pointLight += CalcPoint(light.pLights[i]);

Any thoughts as to why the loop is not working?
Thanks

I hacked at this most the this morning and I’m no closer to a resolution. I’ve tried it on three different computers. My old laptop running Win 7 and almost GL 3.1, another laptop with Win 8 and GL 4.1 and a desktop with Win 10 and GL4.5. Each is a little different. The second laptop just renders everything black after adding the second light no matter if I use hard coded values, constants, or anything else.

The other two computers seem to render fine when using hard coded values and other hacks. However, when trying to loop through the lights, everything rendered by this shader is black. It’s still there, it’s just black. Everything rendered in the scene with other shaders looks fine.

Also, I should add that the shader compiles without even a warning on all three computers I tried.

I’ve tried all different shader versions, but started with 330 and went up from there. Also, my drivers are as up to date as they’re going to get. I don’t expect anything new for my old laptop.

What I really don’t understand is that I’m doing the exact same thing with a regular old uniform and it works:


struct PointLight
{
	vec3 position;
	
	vec3 diffuse;
	vec3 specular;
	vec3 ambient;
	
	float constant;
	float linear;
	float quadratic;
};
#define TOTAL_LIGHTS 2
uniform PointLight pointLight[TOTAL_LIGHTS];

vec3 CalculatePoint(PointLight p)
{
...
}

void main()
{
...
vec3 point = vec3(0.0);
	for(int i = 0; i < TOTAL_LIGHTS; i++)
		point += CalculatePoint(pointLight[i]);
...
}

I don’t understand why this works and the other doesn’t.

I would like to use a ubo to ease access to the data with multiple shaders. If anyone has any ideas why this loop works and the ubo loop doesn’t I’d be glad to hear it; I’m stumped.

Hi!

Data alignement problem maybe; that’s pain in the ass with openGL and drivers… maybe your std140 is bad here…