In my current personal project, my application has a few different "manager" objects such as:
- Texture Manager (ensure a particular texture is only loaded once into memory, and deleted when no longer in use)
- Shader Manager (encapsulates an ID3D10Effect, along with all of its Techniques and Variables)
- Pipeline States Manager ( Contains all unique rasterizer, blend, depth/stencil states )
- Input Layout Manager
The problem is I am quite positive I have implemented these objects in an inefficient and unpractical way for a large scale project. I'm still fairly new to Direct3D programming and my implementations are loosely based off of practices in the book I recently read, "Introduction to 3D Game Programming With DirectX10".
Here's an example of the implementation of my texture manager. Notice the GetTextures() function that creates a static instance of the object and returns it. This is so that I can obtain a reference to the object from anywhere that needs it in the application. Is this a no-no?
class Textures
{
public:
Textures();
~Textures();
void init(ID3D10Device* device);
// Does contain other member functions but that's not relevant
private:
ID3D10Device* md3dDevice;
// Array of textures currently in use within the application
std::vector<Texture> mTextures;
};
// Singleton class
Textures& GetTextures()
{
static Textures textures;
return textures;
};
And here is an example of how I am currently handling a shader and it's corresponding techniques/variables. This example shows one shader, my application has about 5 in total at the moment. Again, this allows me to get the pointers to the shader's variables anywhere in the application that needs them (terrain, mesh, or water rendering for example)
namespace genericfx
{
extern ID3D10Effect* mGenericFX;
extern ID3D10EffectTechnique* mTech;
extern ID3D10EffectTechnique* mTech_DepthOnly;
// Effect Variables
extern ID3D10EffectMatrixVariable* mfxViewProjVar;
extern ID3D10EffectMatrixVariable* mfxWorldMatrixVar;
extern ID3D10EffectMatrixVariable* mfxTexMatrixVar;
extern ID3D10EffectShaderResourceVariable* mfxDiffuseMapVar;
extern ID3D10EffectShaderResourceVariable* mfxSpecularMapVar;
extern ID3D10EffectShaderResourceVariable* mfxNormalMapVar;
extern ID3D10EffectShaderResourceVariable* mfxShadowMapVar;
extern ID3D10EffectScalarVariable* mfxFogEnabledVar;
extern ID3D10EffectScalarVariable* mfxFogBeginVar;
extern ID3D10EffectScalarVariable* mfxFogEndVar;
extern ID3D10EffectScalarVariable* mfxFogTypeVar;
// There is a few more variables but wont waste space
void init(std::wstring filename, ID3D10Device* md3dDevice);
void selfDestruct();
};
// ------------ Somewhere else in the application ---------------- //
genericfx::mfxDiffuseMapVar->SetResource( mSomeShaderResource );
// ----------------------------------------------------------------------------- //
I'm hoping someone can tell me whether or not I'm making a horrible choice here because as my project grows I think these managers are causing a fairly large performance hit. I'm just having trouble thinking of a different way to ensure only one copy of a particular entity (texture, shader, shader variables) is loaded at a time, and having it available to multiple objects all throughout the application