입방형 환경 맵 표면 만들기(Direct3D 9)
CreateCubeTexture 메서드를 호출하여 입방 환경 맵 텍스처를 만듭니다. 입방 환경 맵 텍스처는 2의 강력한 차원과 함께 정사각형이어야 합니다.
다음 코드 예제에서는 C++ 애플리케이션이 간단한 입방 환경 맵을 만드는 방법을 보여 있습니다.
// Init m_d3dDevice to point to an IDirect3DDevice9 interface
LPDIRECT3DCUBETEXTURE9 m_pCubeMap;
m_d3dDevice->CreateCubeTexture(256, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R8G8B8,
D3DPOOL_DEFAULT, &m_pCubeMap);
입방 환경 맵 얼굴에 액세스
GetCubeMapSurface 메서드를 사용하여 입방형 환경 맵의 얼굴 사이를 탐색할 수 있습니다.
다음 코드 예제에서는 GetCubeMapSurface 를 사용하여 양수 y-face(얼굴 2)에 사용되는 큐브 맵 표면을 검색합니다.
// Init m_pCubeMap to point to an IDirect3DCubeTexture9 interface
LPDIRECT3DSURFACE9 pFace2;
m_pCubeMap->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &pFace2);
GetCubeMapSurface에서 허용하는 첫 번째 매개 변수는 메서드가 검색해야 하는 연결된 표면을 설명하는 D3DCUBEMAP_FACES 열거형 값입니다. 두 번째 매개 변수는 검색할 mipmapped 큐브 텍스처의 수준을 Direct3D에 알려줍니다. 허용되는 세 번째 매개 변수는 반환된 큐브 텍스처 표면을 나타내는 IDirect3DSurface9 인터페이스의 주소입니다. 이 큐브 맵은 mipmapped가 아니므로 여기서는 0이 사용됩니다.
참고
이 메서드를 호출한 후 IDirect3DSurface9 인터페이스의 내부 참조 수가 증가합니다. 이 표면 사용을 마쳤으면 이 IDirect3DSurface9 인터페이스에서 IUnknown 메서드를 호출해야 합니다. 그렇지 않으면 메모리 누수가 발생합니다.
입방 환경 맵으로 렌더링
다른 텍스처 또는 표면 개체와 마찬가지로 큐브 맵의 개별 얼굴에 이미지를 복사할 수 있습니다. 얼굴로 렌더링하기 전에 해야 할 가장 중요한 작업은 카메라가 제대로 배치되고 해당 얼굴에 적절한 방향으로 가리키도록 변환 매트릭스를 설정하는 것입니다. 정방향(+z), 뒤로(-z), 왼쪽(-x), 오른쪽(+x), 위쪽(+y) 또는 아래쪽(-y).
다음 C++ 코드 예제에서는 렌더링되는 얼굴에 따라 뷰 행렬을 준비하고 설정합니다.
// Init pCubeMap to point to an IDirect3DCubeTexture9 interface
// Init d3dDevice to point to an IDirect3DDevice9 interface
void RenderFaces()
{
// Save transformation matrices of the device
D3DXMATRIX matProjSave, matViewSave;
d3dDevice->GetTransform(D3DTS_VIEW, &matViewSave ;
d3dDevice->GetTransform(D3DTS_PROJECTION, &matProjSave);
// Store the current back buffer and z-buffer
LPDIRECT3DSURFACE9 pBackBuffer, pZBuffer;
d3dDevice->GetRenderTarget(&pBackBuffer);
d3dDevice->GetDepthStencilSurface(&pZBuffer);
입방형 환경 맵의 각 면은 90도의 시야를 나타냅니다. 애플리케이션에 다른 보기 각도 필드(예: 특수 효과)가 필요하지 않은 경우 프로젝션 매트릭스를 적절하게 설정하는 데 주의해야 합니다.
이 코드 예제에서는 가장 일반적인 사례에 대한 프로젝션 행렬을 만들고 설정합니다.
// Use 90-degree field of view in the projection
D3DMATRIX matProj;
D3DXMatrixPerspectiveFovLH(matProj, D3DX_PI/2, 1.0f, 0.5f, 1000.0f);
d3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
// Loop through the six faces of the cube map
for(DWORD i=0; i<6; i++)
{
// Standard view that will be overridden below
D3DVECTOR vEnvEyePt = D3DVECTOR(0.0f, 0.0f, 0.0f);
D3DVECTOR vLookatPt, vUpVec;
switch(i)
{
case D3DCUBEMAP_FACE_POSITIVE_X:
vLookatPt = D3DVECTOR(1.0f, 0.0f, 0.0f);
vUpVec = D3DVECTOR(0.0f, 1.0f, 0.0f);
break;
case D3DCUBEMAP_FACE_NEGATIVE_X:
vLookatPt = D3DVECTOR(-1.0f, 0.0f, 0.0f);
vUpVec = D3DVECTOR( 0.0f, 1.0f, 0.0f);
break;
case D3DCUBEMAP_FACE_POSITIVE_Y:
vLookatPt = D3DVECTOR(0.0f, 1.0f, 0.0f);
vUpVec = D3DVECTOR(0.0f, 0.0f,-1.0f);
break;
case D3DCUBEMAP_FACE_NEGATIVE_Y:
vLookatPt = D3DVECTOR(0.0f,-1.0f, 0.0f);
vUpVec = D3DVECTOR(0.0f, 0.0f, 1.0f);
break;
case D3DCUBEMAP_FACE_POSITIVE_Z:
vLookatPt = D3DVECTOR( 0.0f, 0.0f, 1.0f);
vUpVec = D3DVECTOR( 0.0f, 1.0f, 0.0f);
break;
case D3DCUBEMAP_FACE_NEGATIVE_Z:
vLookatPt = D3DVECTOR(0.0f, 0.0f,-1.0f);
vUpVec = D3DVECTOR(0.0f, 1.0f, 0.0f);
break;
}
D3DMATRIX matView;
D3DXMatrixLookAtLH(matView, vEnvEyePt, vLookatPt, vUpVec);
d3dDevice->SetTransform(D3DTS_VIEW, &matView);
카메라가 위치에 있고 프로젝션 행렬이 설정된 경우 장면을 렌더링할 수 있습니다. 장면의 각 개체는 일반적으로 배치하는 것처럼 배치해야 합니다. 완전성을 위해 제공되는 다음 코드 예제에서는 이 작업을 간략하게 설명합니다.
// Get pointer to surface in order to render to it
LPDIRECT3DSURFACE9 pFace;
pCubeMap->GetCubeMapSurface((D3DCUBEMAP_FACES)i, 0, &pFace);
d3dDevice->SetRenderTarget (pFace , pZBuffer);
SAFE_RELEASE(pFace);
d3dDevice->BeginScene();
// Render scene here
...
d3dDevice->EndScene();
}
// Change the render target back to the main back buffer.
d3dDevice->SetRenderTarget(pBackBuffer, pZBuffer);
SAFE_RELEASE(pBackBuffer);
SAFE_RELEASE(pZBuffer);
// Restore the original transformation matrices
d3dDevice->SetTransform(D3DTS_VIEW, &matViewSave);
d3dDevice->SetTransform(D3DTS_PROJECTION, &matProjSave);
}
SetRenderTarget 메서드에 대한 호출을 확인합니다. 큐브 맵 얼굴에 렌더링할 때 얼굴을 현재 렌더링 대상 표면으로 할당해야 합니다. 깊이 버퍼를 사용하는 애플리케이션은 렌더링 대상에 대한 깊이 버퍼를 명시적으로 만들거나 기존 깊이 버퍼를 렌더링 대상 표면에 다시 할당할 수 있습니다. 위의 코드 샘플에서는 후자의 접근 방식을 사용합니다.
관련 항목