UboRef not getting data

I’m trying to us the Unified Buffer Object gl::UboRef and to me, it looks incredibly simple, but I’ve been log jammed on this for hours.
I’m trying to setup a vector of a struct containing camera matrices… something like…

struct CameraParams {
	mat4 camMats;
 	mat4 camprogmat;
 	mat4 camviewmat;
} ;

I declare my UboRef and a vector of Parameters in a utility class.

class utility_class(){
    gl::UboRef			mCameraParamsUbo;
    std::vector<CameraParams > mCameraParams;
    void updateParams(ci::CameraStereo *stcam);

Then I set it up…

   blah blah blah
			mCameraParamsUbo = gl::Ubo::create(sizeof(CameraParams)*mCameraParams.size(), mCameraParams.data());

And update the Ubo with a function…

void utility_class::updateParams(ci::CameraStereo *stcam){

//update mCameraParams
mCameraParamsUbo->bufferSubData(0, sizeof(CameraParams) * mCameraParams.size(), mCameraParams.getData() );

in my shader in the geometry pass…

struct CameraParams{
	mat4 camMats;
 	mat4 camprogmat;
 	mat4 camviewmat;
layout (std140) uniform CameraParam {
	CameraParams uCameraParams[2];
//blah blah blah
gl_Position = uCameraParams[ gl_InvocationID ].camprogmat * uCameraParams[ gl_InvocationID ].camviewmat * gl_in[i].gl_Position;

and finally I have another class that builds a GlslProgRef and binds the Ubo bind location…

mGlslProgRef->uniformBlock("CameraParam", UBO_CAM);

I’m getting a proper read out when I print the Ubo info…

ub.getName() CameraParam
ub.getBlockBinding() 0
ub.getLocation() 0
ub.getDataSize() 384
ActiveUniforms size: 6
name: uCameraParams[0].camMats
name: uCameraParams[0].camprogmat
name: uCameraParams[0].camviewmat
name: uCameraParams[1].camMats
name: uCameraParams[1].camprogmat
name: uCameraParams[1].camviewmat

But I’m getting a blank screen… I know the mCameraParams are right because they were working as regular uniforms… but as a Ubo, I’m getting nothing. Something to do with bufferSubData maybe? Is there an order or scope that I’m missing?

I don’t have a heap of experience with UBOs but i’ve only ever written to them using mapWriteOnly as opposed to the buffer* functions. Can you whack a CI_CHECK_GL() after any interactions with the UBO and see if it’s bitching? Looks like you’re on windows so can you attach RenderDoc or NSight and see if your data is making its way to the GPU or if it’s failing elsewhere?

I wonder if there’s some potential struct layout / padding issues popping up too? (Unless the std140 precludes that?)

1 Like

good suggestion…
i did try mapWrite only, and I initially went from a structure of mat4 arrays to an array of the structure…with the same results…
CI_CHECK_GL() didn’t bring anything up so I launched Nsights. Upon quick inspection I saw that the ubo data wasn’t binding!

Turns out you have to bind the Ubo after each time a glslprog is created. For some reason I thought it would be like a global binding to the context that would hold. Since my app is loading and compiling glsl shaders at runtime, I had to add bindBufferBase(UBO_CAM) after each shader build. Cheers.