Managing Various D3D10 Components

Started by
1 comment, last by Geiger 12 years, 5 months ago
Hello all, I have a question regarding the organization and management of certain Direct3D10 features for a somewhat larger scale project.

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
Advertisement
I am using similar system as you and there is easy (probably not best, but fast) solution to holding one copy of particular entity at a time: You can store physical path to the resource with that resource and then each time when you want to add texture to the texture manager you check if that particular texture exists in system, if it does you can release the new one (or don't even create it, depends on implementation) and return the pointer to the old texture (if the new one was same) or return pointer to new one.


LPTEXTURE TextureManager::AddTexture(std::string FileName)


{
for (unsigned int i = 0; i < Textures.size(); ++i)
{
if ( Textures->_FileName == FileName)
{
return Textures;
}
}

Textures.push_back(new T::Texture(FileName, _d3dd));
return Textures[Textures.size()-1];
}


[color="blue"]LPTEXTURE is [color="blue"]IDirect3DTexture9 with physical path under [color="navy"]_FileName



I am happy to provide you with my source code, just pm me
Thanks Daniel but my question was regarding the performance of these management systems rather than the implementations. My texture manager class works fine and is similar to the system you've described, however I just wanted to ask if these are acceptable implementations because (for them to be visible to all other objects) most of them are globals or contain global/static variables.

This topic is closed to new replies.

Advertisement