Texture 클래스
virtual const TEXINFO* Get_TexInfo(const wstring& wstrFilePath,
const wstring& wstrObjectKey,
const wstring& wstrStateKey = L"",
const int& iIndex = 0)PURE;
virtual HRESULT Insert_Texture(const wstring& wstrFilePath,
const wstring& wstrObjectKey,
const wstring& wstrStateKey = L"",
const int& iIndex = 0)PURE;
먼저 그림을 보관할때 방법은 오브젝트 키 안에 스테이트 키가 존재해야 한다.
단, 이건 멀티 텍스처 일 경우에만.
싱글텍스처는 그림이 한장 뿐이라서 오브젝트키는 필요하더라도 스테이트키는 필요가 없다.
그러므로 인자 값에 스테이트 키는 디폴트 값으로 정의한다.
SingleTexture 클래스 와 MultiTexture 클래스 모두 Texture 클래스를 상속 받는다.
SingleTexture 클래스
if (FAILED(D3DXGetImageInfoFromFile(wstrFilePath.c_str(), &m_tTexInfo.tImageInfo)))
{
ERR_MSG(L"Loading Image Info Failed");
return E_FAIL;
}
if (FAILED(D3DXCreateTextureFromFileEx(CGraphic_Device::Get_Instance()->Get_Device(),
wstrFilePath.c_str(),
m_tTexInfo.tImageInfo.Width,
m_tTexInfo.tImageInfo.Height,
m_tTexInfo.tImageInfo.MipLevels,
0,
m_tTexInfo.tImageInfo.Format,
D3DPOOL_MANAGED,
D3DX_DEFAULT,
D3DX_DEFAULT,
0,
nullptr,
nullptr,
&m_tTexInfo.pTexture)))
{
wstring wstrErr = wstrFilePath + L"Loading Failed";
ERR_MSG(wstrErr.c_str());
return E_FAIL;
}
return S_OK;
D3DXGetImageInfoFromFile()
-> 주어진 이미지 파일에 대한 정보를 검색하는 함수이다.
D3DXCreateTextureFromFileEx()
-> 파일에서 텍스처를 만드는 것.
-> D3DXCreateTextureFromFile 보다 고급 기능.
여기서 눈여겨봐야 될 것은 MipLevels 와 D3DPOOL_MANAGED 이다.
Miplevels
-> 동일한 그림을 다양한 사이즈로 만드는 것이다.
-> 예를 들어 다음과 같이 동일한 이미지를 다양한 사이즈로 만들어 둔다.
-> Miplevels는 사이즈 별로 단계가 존재한다.
1단계 : 512 * 512
2단계 : 256 * 256
3단계 : 128 * 128
4단계 : 64 * 64
5단계 : 32 * 32
6단계 : 16 * 16
-> 단계는 가장 가까운 곳 부터 순서대로 1단계부터 증가한다.
텍스처를 쓰기 위해 그림파일을 불러오는 함수
D3DXCreateTextureFromFile() 또는 D3DXCreateTextureFromFileEx()를 사용하는데,
위의 두 개의 함수는 서로 다르다.
D3DXCreateTextureFromFile()는 Mip Levels가 자동으로 여러 단계로 만들어지고,
D3DXCreateTextureFromFileEx()는 위의 함수의 확장형이며 Mip Levels의 단계를 입력한 만큼만 설정이 가능하다.
함수 인자 값 UNIT MipLevels에 2라고 쓰면 2단계까지만 Mip Levels를 만든다는 것이다.
이렇게 하면 기본형을 사용할 때보다 확장형을 사용할 때 로딩 속도를 더 빠르게 할 수 있게된다.
이 값이 0 또는 D3DX_DEFAULT 일 경우, 완전한 밉맵 체인이 생성 된다.
D3DPOOL
-> 리소스에 대한 버퍼를 보유하는 메모리 클래스를 뜻한다.
-> D3DPOOL에는 다음과 같은 열거형 값이 존재한다.
typedef enum D3DPOOL {
D3DPOOL_DEFAULT = 0,
D3DPOOL_MANAGED = 1,
D3DPOOL_SYSTEMMEM = 2,
D3DPOOL_SCRATCH = 3,
D3DPOOL_FORCE_DWORD = 0x7fffffff
} D3DPOOL, *LPD3DPOOL;
D3DPOOL_DEFAULT
-> 주어진 리소스에 대해 요청 된 사용 집합에 가장 적합한 메모리 풀에 배치된다.
-> 그래픽카드에 있는 메모리만 사용
-> 속도가 제일 빠름
-> 안전성 최악
D3DPOOL_MANAGED
-> 필요에 따라 장치에서 액세스 할 수있는 메모리에 자동으로 복사된다.
-> 그래픽카드에 있는 메모리를 사용하다가 부족하면 램의 메모리 사용
-> 속도와 안전성이 모두 보장되어 있음.
D3DPOOL_SYSTEMMEM
-> 일반적으로 Direct3D 장치에서 액세스 할 수없는 메모리에 배치된다.
-> 현재 사용하고 있는 램의 메모리 사용
-> 속도 최악
D3DPOOL_SCRATCH
-> 시스템 RAM에 배치되며 장치가 손실되었을 때 다시 만들 필요가 없다.
위에 네 가지 중에서 주로 MANAGED 타입을 많이 사용한다고 한다.
MultiTexture 클래스
auto& iter_Find = m_mapTexture.find(wstrStateKey);
if (iter_Find != m_mapTexture.end())
return E_FAIL;
TCHAR szBuf[MAX_PATH] = L"";
TEXINFO* pTexInfo = nullptr;
for (int i = 0 ; i < iIndex; ++i)
{
swprintf_s(szBuf, wstrFilePath.c_str(), i);
pTexInfo = new TEXINFO;
if (FAILED(D3DXGetImageInfoFromFile(szBuf, &pTexInfo->tImageInfo)))
{
ERR_MSG(L"Loading Image Info Failed");
return E_FAIL;
}
if (FAILED(D3DXCreateTextureFromFileEx(CGraphic_Device::Get_Instance()->Get_Device(),
szBuf,
pTexInfo->tImageInfo.Width,
pTexInfo->tImageInfo.Height,
pTexInfo->tImageInfo.MipLevels,
0,
pTexInfo->tImageInfo.Format,
D3DPOOL_MANAGED,
D3DX_DEFAULT,
D3DX_DEFAULT,
0,
nullptr,
nullptr,
&pTexInfo->pTexture)))
{
wstring wstrErr = wstrFilePath + L"Loading Failed";
ERR_MSG(wstrErr.c_str());
return E_FAIL;
}
m_mapTexture[wstrStateKey].emplace_back(pTexInfo);
}
return S_OK;
virtual const TEXINFO * Get_TexInfo(
const wstring & wstrStateKey,
const int & iIndex) override;
virtual HRESULT Insert_Texture(
const wstring & wstrFilePath,
const wstring & wstrStateKey,
const int & iIndex) override;
멀티 텍스처는 싱글 텍스처와는 반대로 스테이트 키를 따로 지정해주기 때문에 디폴트 값이 아닌 상태로 정의한다.
map<wstring, vector<TEXINFO*>> m_mapTexture;
멀티 텍스처는 여러 장의 이미지를 관리하기 때문에 map 과 vector를 함께 사용하여 관리한다.
폴더 내의 이미지를 몇장이 있는지 확인하거나 그 이미지 들을 불러오기 위해 인자 값에 Index를 추가한다.
MultiTexture 삭제
for (auto& rPair : m_mapTexture)
{
for (auto& rTexInfo : rPair.second)
{
Safe_Delete(rTexInfo);
}
rPair.second.clear();
//rPair.second.swap(vector<TEXINFO*>());
rPair.second.shrink_to_fit();
}
map 과 vector 둘 다 사용하였기 때문에 지울 때도 map 과 vector 따로 삭제해야 한다.
vector를 삭제 할 때는 스왑 함수를 사용하여 임시 객체와 교체를 통해서 삭제해도 되고,
shrink_to_fit()이라는 함수를 사용하여 삭제해도 된다.
shrink_to_fit() 함수는 C++11 부터 생긴 함수이다.