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