PDA

View Full Version : How query the names of members of a uniform block?



Vexator
08-26-2010, 01:33 PM
How can I query the names of members of a uniform block?

Let's say I have the following uniform block in a shader:


layout(std140) uniform Colors
{
float red;
float green;
float blue;
};

I can query the index of the uniform block like so:


uint index = glGetUniformBlockIndex( shader->id, "Colors" );

But how can I query the names of the block members?

Vexator
08-26-2010, 04:37 PM
ok I got it, I think. At least this seems to work:


uint index = glGetUniformBlockIndex( shader->id, uniformbuffer->name );

if( index != GL_INVALID_INDEX )
{
glUniformBlockBinding( shader->id, index, uniformbuffer->slot );

int activeUniformsInBlock;
glGetActiveUniformBlockiv( shader->id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &activeUniformsInBlock );

int *indices = new int[activeUniformsInBlock];
glGetActiveUniformBlockiv( shader->id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices );

for( uint i = 0; i < activeUniformsInBlock; i++ )
{
const uint &amp;index = (uint)indices[i];

glGetActiveUniformName( shader->id, index, 256, 0, variable );

glGetActiveUniformsiv( shader->id, 1, &amp;index, GL_UNIFORM_TYPE, &amp;type );
glGetActiveUniformsiv( shader->id, 1, &amp;index, GL_UNIFORM_OFFSET, &amp;offset );

// now I can use name, type and offset!
}
}

One thing confuses me, though: The offset and size of a block element should always be the same for all programs the block is accessed from, right? So why do I have to query these things from a program?

Alfonse Reinheart
08-26-2010, 06:02 PM
The offset and size of a block element should always be the same for all programs the block is accessed from, right?

If it uses a shared to std140 layout type, yes. If it is packed, then no.

Vexator
08-27-2010, 04:56 AM
So that means that the same uniform buffer may have different offsets in different programs? When I call glBufferSubData with the element's offset and size obtained from one program, how can I be sure the element will be correctly updated in the other programs?


// 'index' is the index of the block element to be updated, 'data' holds the new data

glGetActiveUniformsiv( program->id, 1, &amp;index, GL_UNIFORM_TYPE, &amp;type );
glGetActiveUniformsiv( program->id, 1, &amp;index, GL_UNIFORM_OFFSET, &amp;offset );

glBufferSubData( GL_UNIFORM_BUFFER_EXT, offset, size, &amp;data );

Isn't the idea of uniform buffers that I can update the same uniforms in several programs at once?

Alfonse Reinheart
08-27-2010, 11:30 AM
So that means that the same uniform buffer may have different offsets in different programs? When I call glBufferSubData with the element's offset and size obtained from one program, how can I be sure the element will be correctly updated in the other programs?

Used shared or std140 layout. Like I said. That's what they're there for.


Isn't the idea of uniform buffers that I can update the same uniforms in several programs at once?

No, the idea is that uniforms can be stored in buffer objects. It's a tool; how you use that tool is up to you. You can use it to update uniforms in many programs at once, but that is not its only use.

Rob Barris
08-31-2010, 04:11 PM
A uniform buffer can also be used to transmit multiple sets of uniforms to be used by the same program on a series of draw calls.