Is using "Key" design pattern in shader class possible? - c++

First of all, i don't know if the "key" pattern is accepted as general patter, but some sorts of it have been appearing all over SO recently, so...
What I want to do?
Create shader manipulation class in C++. My issue here particularly focuses on setting uniform values (values sent from C++ to GLSL "directly").
What's the problem?
(Quick explanation, so that people not accustomed to OpenGL can contribute too) -
Uniform variables are set by using global glUniform* functions, taking as first parameter the location of the uniform in currently bound shader (int);
So the common usage is:
glBindProgram(myProgramNum);
int Location = glGetUniformLocation(myProgramNum, "myUniformParameterName");
float myValue = 42.f; // arbitrary data
glUniform1f (Location, myValue);
I've created some of the methods I need to encapsulate the above, such as
void SetUniform1f (std::string const& name, float a);
void SetUniformVector3 (std::string const& name, CVector3 const& vec);
void SetUniformMatrix4 (std::string const& name, CMatrix4 const& mat);
I've noticed, however, that all these use the glGetUniformLocation(int, const char*). As some of them will be used in realtime, this would cause unnecessary performance overhead.
The first idea
I've thought that I could create two versions of each function - one taking std::string and value, and second int and value, thus allowing faster access.
However, it would make them no better than the pure OpenGL access, since user would still be able to send malicious parameter to them.
The second idea
So, the proper way do to it would be to generate some sort of "Key" object from shader class, containing location of given uniform. It would however need to be linked to specific CShader class instance, because one could generate key in one object and pass it to another, causing unwanted behavior.
And my question is - is something like this possible in C++? Do I have to keep pointer to "parent" object in the key object and test if it's valid parameter every time, or are there any language/Boost features that will allow some sort of syntaxic sugar around it?
What I was able to deduce myself, the key class should be nested in CShader, and had CShader as friend. Also it should declare trivial constructor private, and overload copy-constructor so that copied objects will still be valid keys.

You need only an integer to set an uniform variable. Indeed, instead of calling a bunch of glGetUniformLocation, why don't you cache those values in a std::map<std::string, int>? Querying the map would be faster, isn't it?
Not everything is clear in you question (parent pointer?, malicious values?), but at the end an hypothetical user of a CShader class wants a shortcut for setting up uniform values. Indeed you can query uniforms after shader linkage (using glGetActiveUniform) or you can query uniform and cache uniform location when necessary.

Related

Design pattern to handle groups of objects

I have a class item. Each instance of this class is an object in 3D space, can be basic shapes like cylinder, sphere and cone. The class Item has a convenient API for geometry (radius, top radius, bot radius, length) and transformations (rotation, translation, scale).
enum ItemType {
Sphere = 1,
Cone
}
class Item
{
// ...
public:
ItemType type();
void setType(const ItemType &t);
float radius();
float length();
float topRadius();
float botRadious();
QMatrix4x4 transformations();
void setRadius(const float &r);
void setLength(const float &l);
void setTopRadius(const float &tr);
void setBotRadius(const float &br);
void setTransformations(const QMatrix4x4 &matrix);
// ...
}
Frequently, I want to glue multiple objects together to form a unified shape. For example, two spheres and a cone are connected below. The geometry and transformations of the unified object is dependent upon those of two spheres and one cone.
The problem is:
Convenient handling of the unified object is not possible
By handling, I mean, for example, transforming. Like changing the length of the unified object which requires, changing the length of the middle cone and location of the two spheres accordingly.
class Item has API for convenient handling of each individual object, but not the unified one
For handling of the unified object, I have to work with three different objects which is torturous
The question is:
Which design patterns are best suited to conveniently handle the unified objects?
Note: This question is about object oriented software design and software patterns, it has nothing to do specifically with C++. The only part that is C++ specific is the use of the virtual keyword, but even that, is just the C++-specific keyword that gives you polymorphism, which is again, an object-oriented principle, not something unique to C++.
So, what you first of all need to do, is to extract a true interface for what you call "API". I would call this Primitive3D, and it would be a class containing nothing but pure virtual methods. (In C++, that would be virtual function(parameters) = 0.)
Then, each one of your primitives would be implementing the interface by providing an implementation for each pure virtual method. If you have some basic functionality that all implementations will share, then in addition to implementing this interface you can also keep a common base class. However, the introduction of the interface will keep your options more open.
Then, introduce a new primitive, called perhaps Conglomerate. Again, that would be yet one more class implementing Primitive3D. That class would provide its own implementations for setting various attributes like length and transformation, and these implementations would work by setting some of the attributes of contained primitives.
The Conglomerate class would also provide a few functions which are specific to it and cannot be found in the Primitive3D interface. You would use these functions to configure the conglomerate, at the very least to populate the conglomerate with its contents.
The function which adds a new member primitive to the conglomerate may accept additional parameters to indicate precisely at which position of the conglomeration the new member should appear, what kind of transformation to perform when scaling the primitive, what kind of transformation to perform when translating the primitive, etc.
Internally, the conglomeration would probably make use of a vector containing instances of some internal member structure, which would contain a reference to a Primitive3D and any other information that is necessary so as to know how to handle that primitive. Do not make the mistake of adding this information to the Primitive3D itself, it does not belong there, because a primitive does not know, and should not know, that it is a member of a conglomeration. I would even go as far as to say that the location of a primitive is not a feature of the primitive itself; it is a feature of the space that contains the primitive, whether this space is the universe, or a conglomeration.
Looking at your structure, composite is the pattern you should consider. Also identifying concrete shape with 'type' attribute is against object oriented design. It kills polymorphism, a great unique tool available in OO. Composite pattern will allow you to address elements as well as their aggregation in one hiearchy.

Creating a unique ID for class types C++

My goal here is to create a unique ID (starting a 0) for each child of a specific class. I'm not sure if it is possible in the way i want, but i figured i'd ask here as a last resort.
Some context:
I'm creating my own 2D game engine and i want it to have an ECS as it's back bone (Before anyone says anything, i'm doing this as a learning experience, i know i could just use an already existing game engine). My idea is that each class that implements the 'EntityComponent' class should have a unique ID applied to it. This needs to be per child, not per object. I want to use this ID as the index for an array to find the component of an entity. The actual ID that each Component gets is unimportant and each component does not need to be assigned the ID every run time.
My hope is there is some way to create something similar to a static variable per class (That implements the Entity Component class). It needs to be quick to get this value so doing an unordered_map lookup is slower than i would like. One thing i do not want to do is setting the ID for every component myself. This could cause problems once many components are made and could cause problems if i forget to set it or set two components to the same ID.
One idea i had was to make a variable in EntityComponent called ID (And a getter to get it). When the entity is constructed it looks up an unordered map (which was made at run time, assigning an ID to each class) for what ID it should have. The price of looking up once at construction is fine. The only problem i see with this is there is a lot of redundant data (Though overall it seems it would account to a pretty small amount). With this, every single transform component would have to store that it its ID is x. This means potentially thousands upon thousands of transform components are storing this ID value, when only 1 really needs to.
Basically i am after an extremely quick way to find an ID for a class TYPE. This can be through a lookup, but it needs to be a quick lookup. I would like something faster than unordered_map if possible. If this can be done through compile time tricks (Maybe enums?) or maybe even templates i would love to hear your ideas. I know premature optimisation is the bad, but being able to get a component fast is a pretty big thing.
What i'm asking might very well be impossible. Just thought i'd ask here to make sure first. I should also note i'm trying to avoid implementation of this in the children classes. I'd like to not have to set up the same code for each child class to create an id.
Thank you.
In order to get something corresponding to the actual type of an object, it either needs to be in the object itself or accessed via a virtual function. Otherwise the type will be determined by the type of the variable it is associated with.
A common option when speed and size are both important is to have an integer identifier associated with each type (when the full type list is known at compile time) and use that integer value in a specific way when you want to do something based on the type.
The integer mechanism usually uses an enum for generating the corresponding value for each type and has that field in every object.
The virtual method variety, I've used boost::uuid and a static data member in each class and a virtual method get'er for it.
Declare a virtual function newId() in EntityComponent.
Implement this function to get and increment a static variable in each class, which children you want to have a unique Id.
Assign Id in the constructor:
mId = newId();
don't know this if this is what you meant and i know this is an old post however this is how im currently dealing with a similar issue, maybe it will help someone else.
(Im also doing this as a learning experience for uni :) )
in the controlling class or its own utility class:
enum class EntityType{ TYPE_ONE = 0, TYPE_TWO =1};
in class header:
#include "EntityType.h"
class Whatever{
public:
inline void getType(){return _type;}
OR
inline void getType(){return EntityType::TYPE_ONE;}
private:
EntityType _type = EntityType::TYPE_ONE;
};
Hope this is helpful to anyone :)

C++ Template Classes, Inheritance and Writing Generic Code for Graph Drawing

Background Info
I am writing a graph-drawing program. I have encountered a problem with templates and inheritance, and I do not know how to proceed. I do not know how I should design my code to enable me to do what I am trying to do. (Explanation below.)
Target
I have a template class, which represents "data". It looks something like the following:
template<typename T>
class GraphData
{
std::vector<T> data_x;
std::vector<T> data_y; // x and y should be held in separate vectors
}
This class is part of an inheritance hierarchy involving several classes.
The hierarchy looks something like this... (Sorry this is from my notes, awful diagram.)
Explanation
There is a base class. No real reason to have it right now, but I anticipate using it later.
Base_Legend adds functionality for legend drawing. New members added include a std::string, and Get/Set functions.
Base_Drawable adds a pure abstract = 0 member. void Draw(...). This is to force overloading in all inherited objects which are drawable.
GraphData_Generic adds functionality for adding/removing data points to a set of vectors. These are pure abstract methods, and must be overridden by any data classes which inherit.
GraphData and HistogramData are 2 data types which have implementations of the functions from GraphData_Generic. (No implementation of Draw().)
GraphData_GenericDrawable doesn't do anything. It is to be used as a base class pointer, so that a vector of these objects can be used as data (add/remove data points) and can be draw (using void Draw()). This class also can be used to call the Get()/Set() methods for the std::string to be used in the legend.
Finally, at the bottom are GraphData_Drawable and HistogramData_Drawable which overload the void Draw() function. This code specifies exactly how the data should be drawn, depending on whether we have a Histogram or general set of data points.
Problem
Currently, I am using template types. The type of data for the datapoints / histogram bin values is specified by using a template.
For example, one can have a HistogramData<double, HistogramData_Drawable<double>, HistogramData_Drawable<int>, etc... Similarly, one can have GraphData<double>, GraphData<float>, GraphData_Drawable`, etc...
So hopefully it should be fairly obvious what's going on here without me uploading my ~ 10000 lines of code...
Right, so, in addition I have some class Graph, which contains a std::vector<GraphData_Generic_Drawable*>, hence the use of the base class pointer, as suggested above.
BUT! One has to decide what type of data should be used as the underlying type. I MUST choose either std::vector<GraphData_Generic_Drawable<double>*> or std::vector<GraphData_Generic_Drawable<float>*>.
This isn't useful, for obvious reasons! (I could choose double and force the user to convert all values manually, but that's just an easy way out which creates more work later on.)
A (very) ugly solution would be to have a std::vector<> for each possible type... int long unsigned long long double float unsigned char... etc...
Obviously this is going to be hideous and essentially repeat loads of code..
So, I intend to implement an AddData method which adds data to that vector, and I also currently have the following method:
// In class Graph
void DrawAll()
{
for(std::vector<GraphData_Drawable*>::iterator it = m_data.begin(); it != m_data.end(); ++ it)
(*iterator)->Draw(arguments);
} // Draw function takes arguments including a canvas to draw to, but this isn't directly relevant to the question
Which iterates over the vector and calls Draw for each set of data in there.
How to fix it?
My current thoughts are something along the lines of; I need to implement some sort of interface for an underlying data class, which retrieves values independent of the underlying type. But this is only a very vague initial idea and I'm not really sure how I would go about implementing this, hence the question... I'm not sure this is even what I should be doing...
If this isn't clear ask me a question and I'll update this with more details.

Best practice to set single/multiple members of a (property-) class

I have a class that contains some members that may be modified from external sources:
class CNode
{
protected:
// these members might be changed by users
std::string m_sName;
CState m_CurrentState;
CColor m_DiffuseColor;
};
The sample is simplified, it has more members in my code.
Now what would be the best practice to change
single
multiple (at once)
all members (at once)
of this class?
My code needs to handle all cases, though internally case 1. will be the usual case.
Most of the time it is applied to a single CNode but it might also be applied to an array of nodes.
I know two possible solutions that both don't really satisfy me:
set&get for every variable:
Pro:
Every variable is modifiable independently from other members.
Easy to set the same value for multiple CNodes.
Contra:
A lot of set&gets;
If a new variable is added, a new set&get needs to be added as well.
This would work best if one Variable is changed in many CNodes
Create a CProperties class that contains all modifiable variables:
Pro:
One set&get in the parent class - properties may be added/removed without needing to modify set&get.
This also reduces the amount of methods in my API that processes user input.
Contra:
setting individual variables requires getting the current CProperties, so the other values won't be modified.
This would work best if multiple/all variables are updated at once in a single CNode.
Like so:
class CProperties
{
// these members might be changed by users
std::string m_sName;
CState m_CurrentState;
CColor m_DiffuseColor;
}
class CNode
{
public:
const CProperties* GetProperties();
void SetProperties(CProperties*);
protected:
CProperties m_Properties;
}
This would be the most lazy version (by code creation effort) but also the most obnoxious version for me, since setting single variables requires getting the current properties first, modifying a single variable and then setting the complete properties class back to the node.
Especially in the modify-a-single-variable-in-multiple-CNodes-case this seems to be an awful solution.
Time of execution and (size) overhead is mostly irrelevant in my case. (Which would really be my only good argument against the lazy version)
Instead I'm looking for clean, understandable, usable code.
I could think of a third possible solution with a dynamic approach:
One set method has an object as parameter that may contain one or more values that need to be modified. The API then only has one set method that won't need any modification if the CProperties change. Instead a parsing method would be needed in the CNode class.
This parsing method would still need to be updated for every change in the CProperties, though I'm confident this should also be solvable with the compiler through templates.
My question is:
Are there any other possible solutions for my use case?
Which approach is the most sensible one?
You can add the logic of how to update and what to update into the class and only provide it with a source of information.
Look at how you build the properties object and transfer the logic into an update function that will reside in CNode.
If CNode needs external sources of information in order to perform the update then transfer them to the update function.
Preferably the number of arguments passed to the update function will be smaller than the number of fields in CNode.(Ideally zero or one)
CNode will only update the fields that have actually been modified.
No need for a multiple set functions, uniform way of updating class, no information getting lost between the cracks.

Should I prefer a const function?

Assume I want to implement class A which must load its "configuration" from a file. And let's assume the "configuration" is a simple map<string, string>.
I can implement the A::LoadConfiguration in two different ways:
void A::LoadConfiguration(string filename)
map<string, string> A::LoadConfiguration(string filename) const
Should I prefer either of the two implementations, and why?
If you prefer the second version when the user wants to get info on a file they will base all their algorithms on the map. If you do the second version, meaning the implementation may be a map, but doesn't have to be, they can base their code around an API which does not have to change even if the internal implementation does.
Consider the situation where later you realize it is far more efficient to use an std array, for whatever reason, now every program using this code has to change many of it's algorithms. Using the first version the change to array can be handled internally and reflect no changes on the outside.
Now if you are planning to make multiple instances of the class you will definitely want to make it a static method because you don't want the file to load every time you call the constructor (especially if the file will not change).
Completely ignoring your suggestions, but this is probably how I would do it (not knowing all your constraints, so ignore me if it does not fit):
class A
{
public:
static A fromConfiguration( string fileName );
/* ... */
}
In most cases, the "configuration" of a class should be set at object creation, so forcing the user to provide it on construction is a good thing (instead of having to remember to do do the loading later).
namespace NeatStuff
{
map<string,string> loadSimpleConfiguration( string fileName );
}
If the configuration file format is really simple (and not specific to your class) you can move the actual loading out of the class.
Assuming other classes use the configuration later, I prefer option 1, and an additional GetConfigurationParameter public const method that gets the config value for a particular key. That lets me make other classes which can just ask for some parameter by name without ever caring that it's implemented as a map.
Another reason why I prefer option 1 is that loading a configuration should be distinct from returning it. If I see a name like LoadConfiguration, I assume that it loads the config from somewhere and sets the parameters in the class. I do not assume it returns some description of the configuration, which I'd instead expect from a method like GetConfiguration - but opinions on this will vary for different people of course.