다음을 통해 공유


입방형 환경 맵 표면 만들기(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 메서드에 대한 호출을 확인합니다. 큐브 맵 얼굴에 렌더링할 때 얼굴을 현재 렌더링 대상 표면으로 할당해야 합니다. 깊이 버퍼를 사용하는 애플리케이션은 렌더링 대상에 대한 깊이 버퍼를 명시적으로 만들거나 기존 깊이 버퍼를 렌더링 대상 표면에 다시 할당할 수 있습니다. 위의 코드 샘플에서는 후자의 접근 방식을 사용합니다.

입방 환경 매핑