テクスチャ管理
テクスチャを管理するクラスを作ってみた。
キャッシュに残っていれば使う。
参照カウンターが0になったらキャッシュを消す。
#ifndef __cTextureManager_h__ #define __cTextureManager_h__ #include <d3d11.h> #include <d3dx11.h> #include <string> #include <map> class cTextureManager { private: struct sCache { int m_RefCount; ID3D11ShaderResourceView* m_Resource; }; typedef std::map<std::string, sCache*> TextureCache; public: static cTextureManager& GetInstance() { static cTextureManager s_Instance; return s_Instance; } private: cTextureManager() { } cTextureManager(const cTextureManager& rhs); cTextureManager& operator=(const cTextureManager& rhs); public: ID3D11ShaderResourceView* getTextureResourceView(ID3D11Device* device,const std::string& filename); HRESULT removeTextureResourceView(ID3D11ShaderResourceView* resource); void exit(); void dump(); protected: TextureCache m_TextureCache; }; #define g_texture_manager cTextureManager::GetInstance() #endif // __cTextureManager_h__
#include "cTextureManager.h" #include "ShaderUtility.h" ID3D11ShaderResourceView* cTextureManager::getTextureResourceView(ID3D11Device* device, const std::string& filename) { TextureCache::iterator it; it = m_TextureCache.find(filename); // キャッシュにヒット if(it != m_TextureCache.end()) { std::string key = it->first; sCache* value = it->second; int refCnt = ++value->m_RefCount; // 参照カウントを増やす ID3D11ShaderResourceView* pRV = value->m_Resource; printf("cTextureManager already regist %s : %p, refCnt = %d\n", key.c_str(), pRV, refCnt); return pRV; } ID3D11ShaderResourceView* pRV = NULL; // キャッシュにないのでロード HRESULT hr = D3DX11CreateShaderResourceViewFromFileA( device, filename.c_str(), NULL, NULL, &pRV, NULL ); if(FAILED(hr)) { printf("cant load %s\n", filename.c_str()); return NULL; } sCache* pCache = new sCache; pCache->m_RefCount = 1; pCache->m_Resource = pRV; m_TextureCache.insert(std::pair<std::string, sCache*>(filename, pCache)); printf("cTextureManager regist %s : %p\n", filename.c_str(), pRV); return pRV; } HRESULT cTextureManager::removeTextureResourceView(ID3D11ShaderResourceView* resource) { TextureCache::iterator it = m_TextureCache.begin(); TextureCache::iterator end = m_TextureCache.end(); sCache* pCache = NULL; ID3D11ShaderResourceView* pRV = NULL; while(it != end) { pCache = it->second; pRV = pCache->m_Resource; if(resource == pRV) { if(--pCache->m_RefCount <= 0) { printf("cTextureManager remove %s, %p\n", it->first.c_str(), pRV); pRV->Release(); delete pCache; m_TextureCache.erase(it); return S_OK; } printf("cTextureManager descrease RefCount %d\n", pCache->m_RefCount); } ++it; } return E_FAIL; } void cTextureManager::exit() { TextureCache::iterator it = m_TextureCache.begin(); TextureCache::iterator end = m_TextureCache.end(); sCache* pCache = NULL; ID3D11ShaderResourceView* pRV = NULL; while(it != end) { pCache = it->second; if(pCache) { printf("cTextureManager::exit %s : %p, %d\n", it->first.c_str(), pCache->m_Resource, pCache->m_RefCount); pRV = pCache->m_Resource; if(pRV) { pRV->Release(); } delete pCache; } ++it; } } void cTextureManager::dump() { TextureCache::iterator it = m_TextureCache.begin(); TextureCache::iterator end = m_TextureCache.end(); sCache* pCache = NULL; printf("cTextureManager cache dump ------------------\n"); while(it != end) { pCache = it->second; printf("%s : %p, %d\n", it->first.c_str(), pCache->m_Resource, pCache->m_RefCount); ++it; } printf("---------------------------------------------\n"); }