Поделиться через


Создание поверхностей схемы кубических сред (Direct3D 9)

Текстура схемы кубических сред создается путем вызова метода CreateCubeTexture . Текстуры кубической карты среды должны быть квадратными, с размерами, которые имеют два значения.

В следующем примере кода показано, как приложение 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 (лицо 2).

// Init m_pCubeMap to point to an IDirect3DCubeTexture9 interface

LPDIRECT3DSURFACE9 pFace2;
m_pCubeMap->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &pFace2);

Первый параметр, который принимает GetCubeMapSurface , — это D3DCUBEMAP_FACES перечисленное значение, описывающее присоединенную поверхность, которую должен получить метод. Второй параметр указывает Direct3D, какой уровень текстуры куба mipmapped следует извлечь. Третий допустимый параметр — адрес интерфейса IDirect3DSurface9 , представляющий возвращенную поверхность текстуры куба. Так как эта куб-карта не является mipmapped, здесь используется значение 0.

Примечание

После вызова этого метода количество внутренних ссылок в интерфейсе IDirect3DSurface9 увеличивается. Завершив работу с этой поверхностью, обязательно вызовите метод IUnknown в этом интерфейсе IDirect3DSurface9 , иначе произойдет утечка памяти.

 

Отрисовка в кубических картах среды

Вы можете копировать изображения на отдельные грани карты куба так же, как и любую другую текстуру или объект поверхности. Самое важное, что необходимо сделать перед отрисовкой на лицо, — задать матрицы преобразования таким образом, чтобы камера правильно располагалась и указывалась в правильном направлении для этого лица: вперед (+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 . При отрисовке лиц на карте куба необходимо назначить лицо в качестве текущей целевой поверхности отрисовки. Приложения, использующие буферы глубины, могут явно создать буфер глубины для целевого объекта отрисовки или переназначить существующий буфер глубины поверхности целевого объекта отрисовки. В приведенном выше примере кода используется последний подход.

Сопоставление кубических сред