Proper way to create a generic container of uniforms?
In my program I'm trying to store a map of "global uniforms" where drawn meshes can optionally override these with their own internal maps of uniforms. I am really struggling to get it to compile though, what with needing a generic container. I am struggling to understand if the container should be of type unordered_map<string, AbstractUniform> or
unordered_map<string, ref_ptr<AbstractUniform>>.
As I understand it, I need to use the AbstractUniform abstract class in order to have containers of uniforms of arbitrary types. I would update these values by doing something like
container["modelview"]->as<glm::mat4>()->set(glm::mat4(1.0f));
However, I cannot figure out the necessary type signatures of functions to be able to pass around uniforms. I need to pass uniforms into my individual meshes, and I can't pass around a raw ref_ptr<AbstractUniform> because it can't be instantiated.
Alright, so I got my project to compile again. My solution is to use a container of ref_ptr<AbstractUniform>. The problem I was having is I was using code like this:
auto uni = make_ref<Uniform<glm::mat4>>("projection");
container["projection"] = uni;
where the type of container was: unordered_map<string, ref_ptr<AbstractUniform>>
I can't figure out what exactly was the problem with this, but instead of using make_ref and auto, I now use:
ref_ptr<AbstractUniform> uni = new Uniform<glm::mat4>("projection");
container["projection"] = uni;
Seems like a pecularity in C++ or a design flaw within our ref_ptr :wink:
In your first example using make_ref you create a typed uniform and this type is bound to auto. Later on, this reference pointer of a typed uniform should get assigned to a reference pointer of an abstract uniform which isn't defined in our interface (but I see no reason against such functionality besides our current approach of explicit ownership and thus, a discontinued ref_ptr).
In your second example, you declare a reference pointer on an abstract uniform whose constructor expects a pointer of AbstractUniform and, fortunately, your typed uniform pointer is convertible.