今DirextXでゲームを作っているのですが、困ったことがあります。
メッシュをロードする際に、同じリソースを多重ロード防止する方法を
教えて頂だきたいです。
Aメッシュ Bメッシュ 2つともCというテクスチャをロードする際に
同じテクスチャをロードしないようにしたいのですが、
最適な方法はないでしょうか?
C++ DirectX リソース二重ロード防止
Re: C++ DirectX リソース二重ロード防止
例えば下記の様な事でしょうか。
01.あらかじめ用意されたテクスチャのみを指定できるようにする
02.使用するすべてのテクスチャを別にリストアップしておき、その中からメッシュに使うテクスチャを選び出す
03.すべてのテクスチャを納めた1枚の大きなテクスチャの必要な部分だけを切り出してくる
04.テクスチャを一括して管理するクラスにロードを任せる。このクラスは同じテクスチャを重複してロードするように指示されても、既に読み込まれているテクスチャを返す。
[04の件として]
(テクスチャデータへのポインタの型を仮に LPTEXTURE とします。なので、そのままでは動きません。適当に書き換えてください。テクスチャ以外のデータに使う場合もちょっと変えるだけです)[コード例は古いですよ]
01.あらかじめ用意されたテクスチャのみを指定できるようにする
02.使用するすべてのテクスチャを別にリストアップしておき、その中からメッシュに使うテクスチャを選び出す
03.すべてのテクスチャを納めた1枚の大きなテクスチャの必要な部分だけを切り出してくる
04.テクスチャを一括して管理するクラスにロードを任せる。このクラスは同じテクスチャを重複してロードするように指示されても、既に読み込まれているテクスチャを返す。
[04の件として]
(テクスチャデータへのポインタの型を仮に LPTEXTURE とします。なので、そのままでは動きません。適当に書き換えてください。テクスチャ以外のデータに使う場合もちょっと変えるだけです)[コード例は古いですよ]
#include <windows.h>
#include <stdlib.h> //_fullpath()
#include <limits.h> //CHAR_BIT,UCHAR_MAX
#include <map>
#include 他にも必要なヘッダファイル
class CTextureManager{
protected:
//ファイルパスの32bitCRCをキーにテクスチャを管理する
std::map<unsigned int,LPTEXTURE> TextureManagerMap;
public:
CTextureManager();
virtual ~CTextureManager();
virtual void Clear(); //管理しているすべてのテクスチャを放棄
virtual bool Load(LPTEXTURE&,const char*); //テクスチャのロード
};
//*******************
//* CRC計算部 *
//*******************
#define CRCPOLY 0x04C11DB7UL
/* x^{32}+x^{26}+x^{23}+x^{22}+x^{16}+x^{12}+x^{11]+
x^{10}+x^8+x^7+x^5+x^4+x^2+x^1+1 */
//CRCテーブル
static unsigned long crctable[UCHAR_MAX + 1];
//CRCテーブルの初期化;一度だけ呼べばよい
void MakeCRCTable()
{
unsigned int i, j;
unsigned long r;
for(i = 0; i <= UCHAR_MAX; i++) {
r = (unsigned long)i << (32 - CHAR_BIT);
for(j = 0; j < CHAR_BIT; j++)
if(r & 0x80000000UL) r = (r << 1) ^ CRCPOLY;
else r <<= 1;
crctable[i] = r & 0xFFFFFFFFUL;
}
}
unsigned long CalcCRC32(int n, const BYTE c[])
{
unsigned long r;
r = 0xFFFFFFFFUL;
while (--n >= 0)
r = (r << CHAR_BIT) ^ crctable[(byte)(r >> (32 - CHAR_BIT)) ^ *c++];
return ~r & 0xFFFFFFFFUL;
}
CTextureManager::CTextureManager()
{
MakeCRCTable();
}
CTextureManager::~CTextureManager()
{
Clear();
}
//テクスチャをロードする。
//テクスチャの読み込みに失敗した場合のみfalseを返す
//trueが返れば必ず有効なテクスチャが与えられると考えて良い
bool CTextureManager::Load(LPTEXTURE &Texture,const char *filename){
//*********************
//* 絶対パス取得 *
//*********************
//ファイル名が指定されていなければロードは失敗
if(NULL==filename[0]){
return false;
}
char Full[_MAX_PATH]; //絶対パス取得用バッファ
if(NULL==_fullpath( Full, filename, _MAX_PATH)){
//絶対パス取得失敗
return false;
}
//*********************
//* 重複チェック *
//*********************
unsigned int key_crc=CalcCRC32(strlen(Full)*sizeof(char),(BYTE*)Full);
std::pair<std::map<unsigned int,LPTEXTURE>::iterator,bool> p;
p=TextureManagerMap.insert(std::pair<unsigned int,LPTEXTURE>(key_crc,NULL));
//mapに挿入してみる。
//失敗すれば、既に同じキーが登録されているということ。
if(!p.second){
//既に登録されているテクスチャのポインタを引数に設定して終了
Texture=(*p.first).second;
return true;
}
//挿入に成功すれば、新しくデータを読み込む必要がある
//ここではLoadTextureが第一引数にファイル名、
//第二引数にLPTEXTUREへのポインタをとり、ロードに失敗すればfalseを返す関数であるとする
if(!LoadTexture(Full,&(*p.first).second)){
//ファイルロードに失敗
return false;
}
Texture=(*p.first).second;
return true;
}
void CTextureManager::Clear()
{
//アンロード
std::map<unsigned int,LPTEXTURE>::iterator ite=TextureManagerMap.begin();
std::map<unsigned int,LPTEXTURE>::iterator end=TextureManagerMap.end();
for(;ite!=end;ite++){
//ここではUnloadTextureは引数にLPTEXTUREをとり、
//テクスチャをメモリからアンロードする関数であるとする
UnloadTexture((*ite).second);
}
//クリア
TextureManagerMap.clear();
}