TextureManagerクラスと、Texture2Dクラスがあります。
クラス設計の授業で「friend指定はまだ早い」と言われていましたが、使いました。
自分的には問題ないと思うのですが、とりあえずはソースを。
[Texture2D.h]
#pragma once
#include
class CTextureManager;
class CTexture2D
{
private:
friend CTextureManager;
LPDIRECT3DTEXTURE9 m_pTexture2D; // テクスチャデータ格納変数
bool m_isUse; // 使用中フラグ(フラグが立っていると、描画される)
private:
CTexture2D(void);
virtual ~CTexture2D(void);
void Load(LPDIRECT3DDEVICE9 pd3dDevice, LPSTR fileName); // テクスチャロード関数
bool CheckIsUse(void)const;
LPDIRECT3DTEXTURE9 GetTexture(void)const; // テクスチャ取得関数
bool Delete(void);
public:
void Use(void);
void UnUse(void);
};
#include "Texture2D.h"
CTexture2D::CTexture2D(void)
{
m_pTexture2D = NULL;
m_isUse = false;
}
CTexture2D::~CTexture2D(void)
{
// テクスチャ開放
if(m_pTexture2D != NULL)
{
m_pTexture2D->Release();
m_pTexture2D = NULL;
}
m_isUse = false;
}
// 2Dテクスチャをロード
void CTexture2D::Load(LPDIRECT3DDEVICE9 pd3dDevice, LPSTR fileName)
{
if(FAILED( D3DXCreateTextureFromFile( pd3dDevice, fileName, &m_pTexture2D)))
{ // テクスチャが読み込めなかったらエラー
MessageBox(NULL, "Failed Texture Load...", "Warning!!", MB_ICONWARNING);
exit(1);
}
}
// テクスチャの取得
LPDIRECT3DTEXTURE9 CTexture2D::GetTexture(void)const
{
return m_pTexture2D;
}
// テクスチャ使用開始
void CTexture2D::Use(void)
{
if(m_pTexture2D != NULL)
m_isUse = true;
}
// テクスチャの使用終わり(削除はしない)
void CTexture2D::UnUse(void)
{
m_isUse = false;
}
bool CTexture2D::CheckIsUse(void)const
{
return m_isUse;
}
// テクスチャの削除
bool CTexture2D::Delete(void)
{
if(m_isUse)
return false;
m_pTexture2D->Release();
m_pTexture2D = NULL;
return true;
}
#pragma once
#include
#include "Game.h"
#include "Texture2D.h"
class CTextureManager
{
private:
LPDIRECT3DDEVICE9 m_pd3dDev;
CTexture2D m_texAry[GAME_RESOURCE_NUM];
CTexture2D* m_pFrontTex;
int m_lastResIndex; // 配列の中で、リソースが入っている最後の要素
int m_accessTexID; // ID_NONEのときは、アクセスしていないことを意味する
public:
CTextureManager(LPDIRECT3DDEVICE9 pd3dDev);
~CTextureManager(void);
int Load(LPTSTR fileName);
void Delete(int id);
CTexture2D& Access(int id); // 指定したIDのテクスチャにアクセスする
};
#include "TextureManager.h"
#include
CTextureManager::CTextureManager(LPDIRECT3DDEVICE9 pd3dDev)
{
m_pd3dDev = pd3dDev;
memset(m_texAry, 0, sizeof(m_texAry));
m_pFrontTex = m_texAry;
m_accessTexID = ID_NONE;
}
CTextureManager::~CTextureManager(void)
{
}
// テクスチャをロード
int CTextureManager::Load(LPSTR fileName)
{
m_lastResIndex++;
// これ以上配列に入らなかったら
if(m_lastResIndex > GAME_RESOURCE_NUM)
{
m_lastResIndex--;
return ID_NONE;
}
// ロード
m_texAry[m_lastResIndex].Load(m_pd3dDev, fileName);
return m_lastResIndex;
}
// テクスチャ削除
void CTextureManager::Delete(int id)
{
assert(id >= 0 || id = 0 || id < GAME_RESOURCE_NUM); // 無効なIDチェック
assert(m_texAry[id].GetTexture() != NULL); // テクスチャが存在するかチェック
return m_texAry[id];
}
GAME_RESOURCE_NUMは、ゲーム内で同時に読み込めるテクスチャの最大数です。
ID_NONEはdefineで-1を定義しています。
CTexture2Dは、ユーザがインスタンス化できないようにしておきます。
また、DeleteやLoadも行えないようにします。
あくまで、テクスチャをいじれるのはTextureManagerからのみです。
使い方としては、TextureManagerクラスをインスタンス化して、Loadメソッドを呼び出します。
IDが返ってくるので、それをどこかに保存しておき、そのIDをAccessメソッドの引数にすることで、テクスチャにアクセスできるようになっています。
void Hoge(void)
{
CTextureManager(g_pd3dDev) texMng;
CTexture2D tex; // エラー。
int id = texMng.Load("resource/foo.png");
texMng.Access(id).Use();
texMng.Access(id).Delete(); // エラー。
}
後はTextureManagerクラスに描画を追加する予定で、そのためには頂点情報をどこで処理するのがいいかなと考えています。
この設計はいかがでしょうか・・・?
追記:
私も馬鹿なもんで、テクスチャとTexture2Dクラスは一対一である必要はないと考えていませんでした。
テクスチャ削除したらクラスごと削除する、ってやってました。