I'm trying to implement an OpenGL deferred renderer, in order to process multiple lights.
I have a structure defined in both C++ and GLSL that defines a simple point light, thus: C++
struct LightData
{
glm::vec4 colour;
glm::vec4 position;
glm::vec4 attenuation;
float intensity;
};
GLSL:
struct LightData
{
vec4 colour;
vec4 position;
vec4 attenuation;
float intensity;
};
Upon examination, using sizeof(LightData)
, I find that the size of the C++ struct is 52 bytes, which makes sense. (3x 16 bytes, plus 4 bytes, plus 3x 4 bytes padding for memory alignment)
However, given that I am writing a deferred renderer to work on multiple lights, I populate a GL Uniform Buffer with an array of such structs, and access them like so:
layout (std140) uniform PointLights
{
LightData points[MAX_NUM_POINT_LIGHTS];
};
Upon examination of the data on the GPU, using Nsight, I find that after the first light, all following light structs are accessed differently as if the alignment is off. From examining the offsets of the struct members in Nsight, it seems that the light struct in GLSL is padded up to 64 bytes in size, causing it to read values from the incorrect memory address
C++ offset GLSL offset
0 vec4 colour; 0 0
0 vec4 position; 16 16
0 vec4 attenuation; 32 32
0 float intensity; 36 48
1 vec4 colour; 52 64
1 vec4 position; 68 80
1 vec4 attenuation; 84 96
1 float intensity; 100 112
How would I go about fixing this discrepancy so that the data is retrieved from the correct memory address?