The title explains my two biggest logical problems with developing a game. It's something I sit up at night thinking about, and that is "What is the most effective way to manage shaders" and "What is the most effective way to manage objects (I call them entities in my game)"
Before I actually began to create I game, I made a bunch of simple projects, and my shader and object management systems have always felt flimsy to me. The methods I usually used for shaders were:
- Preload all the shaders when the game loads
- All the shaders are based off of "ShaderBase"
- Each class holds a pointer to a class derived from "ShaderBase"
- When the object is rendered, the app calls the MapData and Render functions of the ShaderBase derived class that the objects pointer contains
This had some problems, however. First of all, is I usually created a different shader when the entities that use it needed special information (Perhaps it was a water shader, and it would be tessellated, so it needed that information). I would need to map different data types to the shader. That means I'd need different versions of ShaderBase's MapData function, for example a regular entity would use:
void ShaderBase::MapData(TransformBuffer transBuf, LightingBuffer lightBuf);
but the water would use:
void ShaderBase::MapData(TransformBuffer transBuf, LightingBuffer lightBuf, WaterDataBuffer waterBuff);
Having to do this seemingly ruins the point of inheritance, because my base class would soon be loaded with different functions for different shaders.
Now the methods for object/entity management. I didn't really have any problems, I just felt like maybe there was a better way to do it. Here's this process:
- Create all the objects (Maybe from a world file)
- Sort all the objects by purpose and/or shader, to cut down on state changes
- A class called EntityList would have an array of all the entities, and each frame would run through that array, and call each ones Render() function, and if it is time, a Think() function (Because some entities may think in steps). It also places the object in its rightful location in the world.
I can see how things like instancing can also be applied here to cut down on resource usage. However, I just have a feeling theres a better way to do this. Each entity is derived from EntityBase, so theres no real problems with inheritance. I might be wrong, but I don't want to continue and have to redo this later.
I didn't mention this above, but I have a sort of bonus question that came to mind while I was writing this:
With the new DirectX 11 features in shaders, what method is better to use: Using techniques, passes, etc. and effect (.fx) files, or the seemingly newer method (I actually don't know when it came about) with each shader in an individual file (.PS, .VS, etc.). Maybe there isn't a difference, I don't know, but I've seen both used in DirectX 11 applications, and I thought maybe people who were more keen to DirectX 10 would use the effect file method, because when I learned a little DirectX 10 before I moved to DirectX 11, I used that method.
For examples of where I've seen these two methods, I learned most of what I know from these two sites: