Problems getting UniformBufferObject working

Hi,

I don’t manage to get UBOs to work. I think I set up everything properly as I don’t get any GL Errors. In my update code I can query the value(s) of the uniform buffer, but my Shader does not react to this value(s). I am trying this with just one float, one VertexArrayObject and one program for debugging purpose, but I also failed with float[4] uniform and vec4 respectively ( just in case I am not getting std140 right ).
What do I miss ?

Vertex Shader:


#version 330 core
// Uniforms
layout( std140 ) uniform Common {
	float	Time ;
} ;

// Input Attribs
in  vec3 inVertex ;

// Main
void main( void )  {
	vec3 pos = inVertex ;
	pos.x += sin( Time ) ;
	gl_Position = vec4( pos , 1.0 ) ;
}

Setup:


// Time is a class member
glGenBuffers( 1 , & uboName );
glBindBuffer( GL_UNIFORM_BUFFER , uboName ) ;
glBufferData( GL_UNIFORM_BUFFER , sizeof( Time ) , NULL , GL_DYNAMIC_DRAW ) ;

// programName is a class member storing the compiled program id
GLint uboBlockIndex = glGetUniformBlockIndex( programName , "Common" ) ;
glUniformBlockBinding( programName , uboBlockIndex , uboName ) ;
glBindBufferRange( GL_UNIFORM_BUFFER , uboBlockIndex , uboName , 0 , sizeof( Time )  ) ;
glBindBuffer( GL_UNIFORM_BUFFER , 0 ) ;

Update:


Time = updateTime() ;
glBindBuffer( GL_UNIFORM_BUFFER , uboName ) ;
glBufferSubData( GL_UNIFORM_BUFFER , 0 , sizeof( Time ) , & Time ) ;

// Testing the Buffer Data
GLfloat progTime ;
glGetBufferSubData( GL_UNIFORM_BUFFER , 0 , sizeof( progTime ) , & progTime ) ;
glBindBuffer( GL_UNIFORM_BUFFER , 0 ) ;
std::cout << "Time in Shader : " << progTime << std::endl ;	// Works

The easiest way to tell if something is working is to write it directly out to the screen.

That being said, your problem is right here:

glUniformBlockBinding( programName , uboBlockIndex , uboName ) ;
glBindBufferRange( GL_UNIFORM_BUFFER , uboBlockIndex , uboName , 0 , sizeof( Time )  ) ;

That’s not how it works. You don’t attach the buffer object to the program. Nor do you bind the buffer to the block index fetched from the program.

Here is an explanation of how this all works.

Hi,

thank you for your reply, but I fear I’m not getting you.
Funny thing is that I was following exactly this tutorial to build the uniform buffer in the first place, but I do not see the difference in code which you’re pointing out. Both the command are used in the tutorial the same way I use them, unless I’m to blind to see already ( possible after one day staring into this few lines of code ).
What do you mean exactly ? And what do you mean with “write it out to the screen” ? I checked the values of the variables used in the gl calls, they seem alright and no Errors thrown.

Sorry, I should have posted the original code her, maybe you ( anybody ) could explain me the proper usage:

Code from Tutorial:


glUniformBlockBinding(
  data.theProgram,
  data.globalUniformBlockIndex,
  g_iGlobalMatricesBindingIndex );

and


glBindBufferRange(
  GL_UNIFORM_BUFFER,
  g_iGlobalMatricesBindingIndex,
  g_GlobalMatricesUBO, 0, sizeof( glm::mat4 ) * 2 );

Both the command are used in the tutorial the same way I use them

Let’s compare:


glUniformBlockBinding( data.theProgram, data.globalUniformBlockIndex, g_iGlobalMatricesBindingIndex );

And


glUniformBlockBinding( programName , uboBlockIndex , uboName ) ;

data.theProgram and programName are both program objects. data.globalUniformBlockIndex and uboBlockIndex are uniform block indices queried from glGetUniformBlockIndex.

But g_iGlobalMatricesBindingIndex is just a global index, while uboName is an OpenGL uniform buffer object. These aren’t the same thing.

Perhaps you remember this statement from the tutorial:

Emphasis added.

The association between program uniform block and OpenGL uniform buffers is made by proxy, through an intermediary. These intermediaries are buffer object binding points. You tell the program which binding point to find its buffer in, and you bind the uniform buffer to that binding point so that it can find it.

And what do you mean with “write it out to the screen” ?

The screen. You know, the output from the fragment shader. You can write the value as the color, and then see if what you get on screen is what you expect from your shader. This is the most basic tool of shader debugging.

Hi,

Thank you very much, it works now :slight_smile:
Also the trick to debug with colors is very helpful.

Cheers, searching for the Pivot of my Soul, PP !