일반적으로 텍스처 자료는 디스크에 저장된 이미지 파일에서 읽어서 ID3D11Texture2D 객체에 적재한다. 텍스처는 알다시피 자원 뷰를 따로 만들어서 파이프라인에 묶어야 한다. 그 과정은 다음과 같다.
첫 두 단계를 한꺼번에 해주는 함수가 D3DX에 있다.
HRESULT D3DX11CreateShaderResourceViewFromFile(
ID3D11Device *pDevice,
LPCTSTR pSrcFile,
D3DX11_IMAGE_LOAD_INFO *pLoadInfo,
ID3DXllThreadPump *pPump,
ID3DllShaderResourceView **ppShaderResourceView,
HRESULT *pHResult
);
이 함수는 BMP, JPG, PNG, DDS, TIFF, GIF, WMP 텍스처 파일 형식을 지원한다. 다음은 tree.png라는 이미지 파일로 텍스처를 생성하는 예이다.
ID3D11ShaderResourceView* mDiffuseMapSRV;
HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice,
L"./Tree.png", nullptr, nullptr, &srv, nullptr));
텍스처를 만들었다면, 이를 파이프라인에 묶어줘야 한다. 묶는 함수는 다음과 같이 PSSetShaderResources 함수를 이용한다.
m_immediateContext->PSSetShaderResources(0, 1, &srv);
이 함수의 제1 매개변수는 시작 슬롯이다. 자원을 배열 형식으로 넘겨주는데 그 배열의 시작 슬롯을 말한다. 보통 0부터 시작한다. 제2 매개변수는 넘겨주는 개수이다. 우리는 1개만 넘기므로 1로 한다. 제3 매개변수는 배열 포인터를 반환해준다.
이러면 이제 픽셀 셰이더 안에서 받을 준비가 된 것이다. 셰이더의 텍스트 출력 부분 코드는 다음과 같다.
Texture2D sourceTex : register(t0);
SamplerState samp : register(s0);
float4 PS(PixelInput input) : SV_Target
{
return sourceTex.Sample(samp,input.uv);
}
Texture2D sourceTex : register(t0); 이 문구가 텍스처 자원을 받는 문구다. 텍스처 객체를 나타내는 형식은 Texture2D이다.
여기서 상수 버퍼 때처럼 변수 뒤에 : register(t0)을 붙여줘야 한다. 달라진 건 뒤의 t0이다. 무슨 의미인가? t는 텍스처 자원을 받겠다는 뜻이고, 0은 텍스처 자원 배열의 인덱스이다. CPU에서 보내줄 때 배열 0번부터 시작해 1개 넣었으므로, 그 자원은 배열의 0에 있을 것이다. 그래서 저렇게 썼다. 만약 PSSetShaderResources(2, 1, &srv) 이런식으로 2번에서 시작해 1개 넣었으면 뭘로 받아야 할까? 당연히 2로 받으면 된다. Texture2D는 0 ~ 127까지 128개를 전달 받을 수 있다.
밑에 SamplerState samp : register(s0)은 무엇인가? CPU에서 넘길 수 있는 또 다른 자원 '샘플러'라는 건데, 굳이 안 받아도 출력할 수 있다. 그럼 왜 필요하냐? PS함수에 Sample 함수의 제1 매개변수로 필요하기 때문이다. Sample 함수는 '제1 매개변수에서 설정한 조건으로 샘플링해서, 호출 객체를, 제2 매개변수인 uv좌표 따라서 출력해주세요'라는 의미이다.
이렇게 하고 실행 하면 텍스처가 나온다.
