I'm trying to go about copying a bunch of floats into a uniform block in one of my shaders. The book I'm reading uses memcpy, so I'm having issues translating its code into Java.
In my fragment shader, I have
uniform BlobSettings {
vec4 InnerColor;
vec4 OuterColor;
float RadiusInner;
float RadiusOuter;
};
Then, to try and set that uniform block
public static void initUniformBlockBuffer(){
// get the block's index
int blockIndex = GL31.glGetUniformBlockIndex(program.getHandle(),
"BlobSettings");
// how many bytes is the block?
int blockSize = GL31.glGetActiveUniformBlock(program.getHandle(),
blockIndex, GL31.GL_UNIFORM_BLOCK_DATA_SIZE);
// allocate a bytebuffer
ByteBuffer blockBuffer = BufferUtils.createByteBuffer(blockSize);
// this prints out 48, even though there's only 10 floats
System.out.println(blockSize + " bytes");
// query for offsets of each block variable
String[] names = { "InnerColor", "OuterColor", "RadiusInner",
"RadiusOuter" };
// get uniform indices
IntBuffer indices = BufferUtils.createIntBuffer(4);
GL31.glGetUniformIndices(program.getHandle(), names, indices);
// get uniform byte offsets
IntBuffer offset = BufferUtils.createIntBuffer(4);
GL31.glGetActiveUniforms(program.getHandle(), indices,
GL31.GL_UNIFORM_OFFSET, offset);
// data
float[] outerColor = { 0.0f, 0.0f, 0.0f, 0.0f };
float[] innerColor = { 1.0f, 1.0f, 0.75f, 1.0f };
float innerRadius = 0.25f, outerRadius = 0.45f;
// put outer color colors into the bytebuffer (add 4 * i because 4 bytes/float)
for (int i = 0; i < innerColor.length; i++) {
blockBuffer.putFloat(offset.get(0) + (4 * i), innerColor[i]);
}
// put inner colors into the bytebuffer
for (int i = 0; i < outerColor.length; i++) {
blockBuffer.putFloat(offset.get(1) + (4 * i), outerColor[i]);
}
// put inner and outer radius into bytebuffer
blockBuffer.putFloat(offset.get(2), innerRadius);
blockBuffer.putFloat(offset.get(3), outerRadius);
// create buffer object and copy the data
int uboHandle = GL15.glGenBuffers();
GL15.glBindBuffer(GL31.GL_UNIFORM_BUFFER, uboHandle);
GL15.glBufferData(GL31.GL_UNIFORM_BUFFER, blockBuffer,
GL15.GL_DYNAMIC_DRAW);
// bind buffer object to the uniform block
GL30.glBindBufferBase(GL31.GL_UNIFORM_BUFFER, blockIndex, uboHandle);
}
My main point of confusion is that when GL31.glGetActiveUniformBlock(program.getHandle(), blockIndex, GL31.GL_UNIFORM_BLOCK_DATA_SIZE) is called, it returns 48 bytes.
I'm pretty sure that a float in Java is 4 bytes. I have 10 floats in my shader, that should equate to 40 bytes. Why is there room for 2 extra floats?
All of the offsets returned by GL31.glGetActiveUniforms(program.getHandle(), indices, GL31.GL_UNIFORM_OFFSET, offset); show the data being at the correct positions as if each float were 4 bytes- InnerColor is at 0, OuterColor is at 16, InnerRadius is at 32 and OuterRadius is at 36. I checked to make sure my data was copied into the ByteBuffer correctly by using its asFloatBuffer method and printing out the values. Everything was fine except for two blank floats (0.0f) at the end of it after OuterRadius. If I try to print out the active uniforms for my program, it prints out everything in the block at location -1, so it appears as though my data is binding at all, so my problem might be with GL30.glBindBufferBase(GL31.GL_UNIFORM_BUFFER, blockIndex, uboHandle);
Anybody have any advice? Is there a better way to go about this?