What is a good approach for handling uniforms in modern OpenGL?
Suballocating from a larger buffer is absolutely the way to go, with caveats. I'm coming more from a DirectX/Vulkan side of things, but this should apply equally to OpenGL (I just won't have direct API calls here in this answer). The things to consider are the following:


Do you need to index into the larger buffer, or are you OK with binding the resource to the offset each time?
Have you taken care of any/all alignment restrictions for your uniforms that are packed together (256 byte alignment is common)?


Newer graphics APIs have a "dynamic offset" you can specify with the draw command which is a pretty fast way to indirectly access a subregion of a buffer. However, assuming you are triple-buffering data that's mutable, there should be little to no contention in the driver for binding the data (just some fixed overhead).

In summary, yes, allocating larger regions of memory/buffers and subleasing those regions is considered best practice. This applies even to objects with different shaders (if your allocator can handle it).