用DirectX写的Skybox

用DirectX写的Skybox

        实现原理:设置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;
}

你可能感兴趣的:(用DirectX写的Skybox)