How query the names of members of a uniform block?

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?

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 &index = (uint)indices[i];
				
		glGetActiveUniformName(	shader->id, index, 256, 0, variable );

		glGetActiveUniformsiv( shader->id, 1, &index, GL_UNIFORM_TYPE, &type );
		glGetActiveUniformsiv( shader->id, 1, &index, GL_UNIFORM_OFFSET, &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?

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.

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, &index, GL_UNIFORM_TYPE, &type );
glGetActiveUniformsiv( program->id, 1, &index, GL_UNIFORM_OFFSET, &offset );

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

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

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.

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.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.