0
\$\begingroup\$

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?

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

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)

Your calculations here are wrong.

16 + 16 + 16 + 4 is 52, so your value of 52 bytes excludes the 3x4 padding bytes.

If we include the pad bytes we get: 16 + 16 + 16 + 4 + (3x4), or 64, which is the correct value.

\$\endgroup\$
1
  • \$\begingroup\$ Aha, why did I not see that? Thanks \$\endgroup\$
    – Ian Young
    Commented Mar 31, 2017 at 14:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .