I am using JOGL to develop small OpenGL applications in Java. I am facing the following issue: I have a Uniform Buffer Object "Light" declared in the fragment shader as follows:
struct PerLight
{
vec4 cameraSpaceLightPos;
vec4 lightIntensity;
};
const int numberOfLights = 4;
uniform Light
{
vec4 ambientIntensity;
float lightAttenuation;
PerLight lights[numberOfLights];
} Lgt;
As I understand, the only not straightforward part when putting data inside the UBO is that the float "lightAttenuation" will need to be padded with 3 floats.
I put the data in my buffer as follows (all values except lightAttenuation are arrays with 4 float values):
gl.glBindBuffer(GL2.GL_UNIFORM_BUFFER, lightUniformBuffer[0]);
FloatBuffer buffer = Buffers.newDirectFloatBuffer(2 * (2 + DynamicRangeLights.NUMBER_OF_LIGHTS * 2) * 4);
buffer.put(lightData.ambientIntensity.getArray());
buffer.put(new float[] { lightData.lightAttenuation, 0.0f, 0.0f, 0.0f });
for (int i = 0; i < 4; ++i) {
buffer.put(lightData.lights[i].cameraSpaceLightPos.getArray());
buffer.put(lightData.lights[i].lightIntensity.getArray());
}
buffer.rewind();
gl.glBufferSubData(GL2.GL_UNIFORM_BUFFER, 0, sizeLightBlock, buffer);
But the result I get is wrong: the colors and intensities of the lights are completely off.
If I rewrite the UBO in my fragment shader as follows, everything works fine:
uniform Light
{
vec4 ambientIntensity;
float lightAttenuation;
vec4 cameraSpaceLightPos0;
vec4 lightIntensity0;
vec4 cameraSpaceLightPos1;
vec4 lightIntensity1;
vec4 cameraSpaceLightPos2;
vec4 lightIntensity2;
vec4 cameraSpaceLightPos3;
vec4 lightIntensity3;
} Lgt;
According to me, the two UBOs should receive the same data and display the same result, but apparently I am wrong. What is the difference between these two UBOs, and how should I buffer the data in the first one to get the same result as the second one?
Edit: I forgot to mention it, but I use in my shaders
layout(std140) uniform;
So if I am not wrong, all uniforms use the std140 layout.