Hello,
I'm trying to set up UBOs in my application but I'm not able to get the uniform' sizes in my uniform block.
Here is the code I use to get the size :
private void setUpUniformsOffsetsAndSizes(UniformBufferObjectInfos uniformBufferObjectInfos) {
int shaderProgramID = uniformBufferObjectInfos.getShaderProgramID();
String[] uniformNames = uniformBufferObjectInfos.getUniformsNames();
int nbUniforms = uniformNames.length;
// Retrieve the index of each uniform
IntBuffer uniformIndices = BufferUtils.createIntBuffer(nbUniforms);
GL31.glGetUniformIndices(shaderProgramID, uniformNames, uniformIndices);
// Retrieve the offset of each uniform
IntBuffer uniformsOffsets = BufferUtils.createIntBuffer(nbUniforms);
GL31.glGetActiveUniformsiv(shaderProgramID, uniformIndices, GL31.GL_UNIFORM_OFFSET, uniformsOffsets);
// Retrieve the size of each uniform
IntBuffer uniformsSizes = BufferUtils.createIntBuffer(nbUniforms);
GL31.glGetActiveUniformsiv(shaderProgramID, uniformIndices, GL31.GL_UNIFORM_SIZE, uniformsSizes);
// Store offset and size in UniformBufferObjectInfos
uniformBufferObjectInfos.setUniformsOffsets(uniformsOffsets);
uniformBufferObjectInfos.setUniformsSizes(uniformsSizes);
}
But I always get 1 when I'm asking for the sizes... My shader code is like this (I need the offset even if i'm using std140 here) :
layout (std140, binding = 0) uniform BlobSettings {
// Base Offset // Base Alignment // Aligned Offset
vec4 innerColor; // 0 // 16 // 0 - 15
vec4 outerColor; // 16 // 16 // 16 - 31
float radiusInner; // 32 // 4 // 32 - 35
float radiusOuter; // 36 // 4 // 36 - 40
};
Am I doing wrong ?
And finally, why does the BufferUtils class prevent us from doing like :
ByteBuffer updatedData = BufferUtils.createByteBuffer(4));
// do some stuff
bytes[] array = updatedData.array();
Because at some point in my code I need to convert my ByteBuffer to an array of bytes so the only solution I found was not to use BufferUtils :
ByteBuffer byteBuffer = ByteBuffer.allocate(values.length * 4).order(ByteOrder.nativeOrder());
for(float value : values) {
byteBuffer.putFloat(value);
}
byte[] bytesValues = byteBuffer.array();
Thanks for your help :D
Read:
- http://www.lighthouse3d.com/tutorials/glsl-tutorial/uniform-blocks/
- https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetActiveUniformBlock.xhtml
You should really first google a few tutorials about Uniform Blocks. Just google "OpenGL Uniform Blocks" and read the first few results.
Thanks for your help KAIHH.
I already read this tutorials and this one : https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL , as well as the one in "OpenGL programming Guide (OpenGL version 4.5)" and the one in "OpenGL 4 shading Language CookBook" and I think I understood the basics of uniforms blocks in GLSL but still I can't get the size of each uniform in my uniform block... I'm missing something :-\
Then please read and follow that lighthouse3d tutorial again, and make sure you follow it exactly to the point. You are missing the GL call I mentioned in the other link. Please see the section "Setting and Updating the Buffer".
I'm going to read it again. Thank you :)
Ok so I read it again and still can't get it to work... My code is the same as before and is the same as in the tutorial :
Java code :
// Retrieve the uniform block index
int uniformBlockIndex = GL31.glGetUniformBlockIndex(shaderProgramID, uniformBlockName);
// Retrieve the binding point specified in the shader of the uniform block
int bindingPoint = GL31.glGetActiveUniformBlocki(shaderProgramID, uniformBlockIndex, GL31.GL_UNIFORM_BLOCK_BINDING);
// Retrieve the size of the uniform block
int sizeToAllocate = GL31.glGetActiveUniformBlocki(shaderProgramID, uniformBlockIndex, GL31.GL_UNIFORM_BLOCK_DATA_SIZE);
// Retrieve the number of active uniforms in the uniform block
int nbUniforms = GL31.glGetActiveUniformBlocki(shaderProgramID, uniformBlockIndex, GL31.GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS);
// Prepare a uniform buffer, allocating memory
int uboID = GL15.glGenBuffers();
GL15.glBindBuffer(GL31.GL_UNIFORM_BUFFER, uboID);
GL15.glBufferData(GL31.GL_UNIFORM_BUFFER, sizeToAllocate, GL15.GL_DYNAMIC_DRAW);
/*
* Finaly bind the uniform buffer object to the same binding point to acctualy link
* the uniform buffer to the uniform block (pointing each to the same binding point)
*/
GL30.glBindBufferBase(GL31.GL_UNIFORM_BUFFER, bindingPoint, uboID);
GL15.glBindBuffer(GL31.GL_UNIFORM_BUFFER, 0);
// Retrieve the index of each uniforms
IntBuffer uniformIndices = BufferUtils.createIntBuffer(nbUniforms);
GL31.glGetActiveUniformBlockiv(shaderProgramID, uniformBlockIndex, GL31.GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES , uniformIndices);
// Retrieve the offset of each uniforms
IntBuffer uniformsOffsets = BufferUtils.createIntBuffer(nbUniforms);
GL31.glGetActiveUniformsiv(shaderProgramID, uniformIndices, GL31.GL_UNIFORM_OFFSET, uniformsOffsets);
// Retrieve the size of each uniforms DOEST WORK fill the InteBuffer with Ones
IntBuffer uniformsSizes = BufferUtils.createIntBuffer(nbUniforms);
GL31.glGetActiveUniformsiv(shaderProgramID, uniformIndices, GL31.GL_UNIFORM_SIZE, uniformsSizes);
Shader code :
#version 460 core
in vec3 texCoords;
layout (location = 1) out vec4 fragColor;
layout (std140, binding = 0) uniform BlobSettings {
// Base Offset // Base Alignment // Aligned Offset
vec4 innerColor; // 0 // 16 // 0 - 15
vec4 outerColor; // 16 // 16 // 16 - 31
float radiusInner; // 32 // 4 // 32 - 35
float radiusOuter; // 36 // 4 // 36 - 40
};
void main(void) {
float dx = texCoords.x - 0.5;
float dy = texCoords.y - 0.5;
float dist = sqrt(dx * dx + dy * dy);
fragColor = mix(innerColor, outerColor, smoothstep(radiusInner, radiusOuter, dist));
}
Wich GL call am I missing ??? ?
Thanks for your help.