實現原理:設置5個面,即前、后、左、右、上5個,每個面4個頂點,共20個頂點,然后對每個面貼圖,行走時,skybox與行走做相同的操作。下面一步步實現:
首先給出skybox的定義:
class CSkybox
{
//

//以下是基礎數據
private:
D3DXMATRIXA16 m_matWorld; //世界矩陣

LPDIRECT3DTEXTURE9 m_pSideTexture[6]; //skybox的6個面的紋理
D3DXVECTOR3 m_vSize; // z, x, y分別為長,寬,高
D3DXVECTOR3 m_vPos; // skybox的中心點
D3DXVECTOR3 m_vPosOrgin; //原始點
}
1、設置skybox的大小和位置,即設置盒子的長寬高。
//設置位置
void SetBoxPos(const D3DXVECTOR3& vPos)
{
m_vPos = vPos; //當前點
m_vPosOrgin = m_vPos; //原始點
}

void SetBoxSize(const D3DXVECTOR3& vSize)
{
m_vSize = vSize;
}
2、創建頂點緩沖,頂點的位置要根據第一步的盒子大小創建。
實際上我只用了兩張紋理,從CG模型網下載的古墓麗影的天空盒紋理,所以創建紋理坐標時是0.5。
BOOL CSkyBox::CreateVertexBuffer(LPDIRECT3DDEVICE9 p3DDevice9)
{
float fWidth = m_vSize.x;
float fLength = m_vSize.z;
float fHeight = m_vSize.y;

//確定8個點
//上面的左上角
D3DXVECTOR3 vTTopLeft(m_vPos.x - fWidth / 2, m_vPos.y + fHeight / 2, fLength / 2 - m_vPos.z);
D3DXVECTOR3 vTTopRight(fWidth / 2 - m_vPos.x, m_vPos.y + fHeight / 2, fLength / 2 - m_vPos.z);
D3DXVECTOR3 vTBottomLeft(m_vPos.x - fWidth / 2, m_vPos.y + fHeight / 2, m_vPos.z - fLength / 2);
D3DXVECTOR3 vTBottomRight(fWidth / 2 - m_vPos.x, m_vPos.y + fHeight / 2, m_vPos.z - fLength / 2);

//下面
D3DXVECTOR3 vBTopLeft(m_vPos.x - fWidth / 2, m_vPos.y - fHeight / 2, fLength / 2 - m_vPos.z);
D3DXVECTOR3 vBTopRight(fWidth / 2 - m_vPos.x, m_vPos.y - fHeight / 2, fLength / 2 - m_vPos.z);
D3DXVECTOR3 vBBottomLeft(m_vPos.x - fWidth / 2, m_vPos.y - fHeight / 2, m_vPos.z - fLength / 2);
D3DXVECTOR3 vBBottomRight(fWidth / 2 - m_vPos.x, m_vPos.y - fHeight / 2, m_vPos.z - fLength / 2);

CUSTOMVERTEX_TXT cvVertices[] =
{
//上面的點
{vTBottomLeft, D3DCOLOR_XRGB(255, 0, 0), 0.0f, 0.0f,}, //Vertex 2 - Red
{vTBottomRight, D3DCOLOR_XRGB(255, 255, 0), 1.0f, 0.0f,}, //Vertex 3 - Green
{vTTopLeft, D3DCOLOR_XRGB(255, 255, 255), 0.0f, 1.0f,}, //Vertex 1 - Red
{vTTopRight, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 1.0f,}, //Vertex 0 - Blue

//前面
{vTTopLeft, D3DCOLOR_XRGB(255, 255, 255), 0.0f, 0.0f,}, //Vertex 0 - Blue
{vTTopRight, D3DCOLOR_XRGB(255, 255, 255), 0.5f, 0.0f,}, //Vertex 1 - Red
{vBTopLeft, D3DCOLOR_XRGB(255, 255, 255), 0.0f, 1.0f,}, //Vertex 2 - Red
{vBTopRight, D3DCOLOR_XRGB(255, 255, 255), 0.5f, 1.0f,}, //Vertex 3 - Green

//右面
{vTTopRight, D3DCOLOR_XRGB(255, 255, 255), 0.5f, 0.0f,}, //Vertex 0 - Blue
{vTBottomRight, D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0.0f,}, //Vertex 3 - Green
{vBTopRight, D3DCOLOR_XRGB(255, 0, 0), 0.5f, 1.0f,}, //Vertex 2 - Red
{vBBottomRight, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 1.0f,}, //Vertex 1 - Red


//后面
{vTBottomRight, D3DCOLOR_XRGB(255, 255, 255), 0.0f, 0.0f,}, //Vertex 0 - Blue
{vTBottomLeft, D3DCOLOR_XRGB(255, 255, 255), 0.5f, 0.0f,}, //Vertex 0 - Blue
{vBBottomRight, D3DCOLOR_XRGB(255, 255, 255), 0.0f, 1.0f,}, //Vertex 1 - Red
{vBBottomLeft, D3DCOLOR_XRGB(255, 255, 255), 0.5f, 1.0f,}, //Vertex 1 - Red

//左面
{vTBottomLeft, D3DCOLOR_XRGB(255, 255, 255), 0.5f, 0.0f,}, //Vertex 0 - Blue
{vTTopLeft, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0.0f,}, //Vertex 0 - Blue
{vBBottomLeft, D3DCOLOR_XRGB(255, 255, 255), 0.5f, 1.0f,}, //Vertex 1 - Red
{vBTopLeft, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 1.0f,}, //Vertex 1 - Red


if(FAILED(p3DDevice9->CreateVertexBuffer(20 * sizeof(CUSTOMVERTEX_TXT),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &m_pVertexBuffer, NULL)))
{
return FALSE;
}

VOID* pVertices = NULL;

if(FAILED(m_pVertexBuffer->Lock(0, sizeof(cvVertices), (void**)&pVertices, 0)))
{
return FALSE;
}

//Copy our stored vertices values into the vertex buffer
memcpy(pVertices, cvVertices, sizeof(cvVertices));

//Unlock the vertex buffer
m_pVertexBuffer->Unlock();

return TRUE;
}
3、創建每個面的紋理。
4、更新世界矩陣。根據攝像頭位置的改變,改變skybox的世界矩陣就行了。
void CSkyBox::UpdatePos(const D3DXVECTOR3& vPos)
{
m_vPos = vPos;
D3DXVECTOR3 v = m_vPos - m_vPosOrgin; //計算出平移的向量
m_matWorld._41 = v.x;
m_matWorld._42 = v.y;
m_matWorld._43 = v.z;
}