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 부터 생긴 함수이다.

'Programming > MFC' 카테고리의 다른 글

MFC - 기본 이론 , 계층 구조  (0) 2020.11.29
MFC - 타일 픽킹(내적)  (0) 2020.11.29
MFC - 타일 픽킹(직선의 방정식)  (0) 2020.11.25
MFC - 타일 배치  (0) 2020.11.25
MFC - 디바이스 초기화  (0) 2020.11.22

+ Recent posts