Direct9學習之-------------------------公告板技術

 

一. 公告板的應用:
     
      公告板可被用於場景中對細節要求不高的樹木花草,也可用於玩家頭頂的某些特效表現等。其好處自然是高效簡潔。

二. 公告板基本原理:

公告板最基本的原理就是,繪製一個帶貼圖的矩形區域,由阿爾法混合使貼圖看起來更逼真,並且保證每幀矩形都是正對攝像機,從而在效果上表現出貼圖中的對象。 由於只繪製了一個矩形因此其繪製的性能很高。

三. 公告板實現方式及相關代碼:

由公告板的基本原理可以將其實現歸納爲以下步驟:
        1. 初始化公告板矩形並將其放置到場景中
        2. 每幀根據當前相機位置在XZ平面旋轉矩陣保證其正對攝像機(當相機可繞UP方向移動旋轉時會導致公告板穿幫,此時需要其他手段來解決。)
        3. 繪製矩形並對其貼圖進行阿爾法混合。

                具體相關代碼如下:

        1. 初始化公告板矩形定點信息
        
          a. 定義公告板定點信息
          // 公告板定點信息  
          struct  CUSTOMVERTEX
         {
            float x, y, z;    //頂點位置
            float u,v ;    //頂點紋理座標
          };

          #define D3DFVF_CUSTOMVERTEX   (D3DFVF_XYZ|D3DFVF_TEX1)

          b. 創建定點緩衝區
          // 創建定點緩衝
          pDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX),0, D3DFVF_CUSTOMVERTEX,
          D3DPOOL_MANAGED, &m_pVertexBuf, NULL );


           // 初始化頂點數據 填充頂點緩衝區數據
          CUSTOMVERTEX Vertices[] =
         {
           { -m_fWidth / 2.0f, -m_fHeigh / 2.0f, 0.0f,  0.0f, 1.0f, },
           { -m_fWidth / 2.0f, m_fHeigh / 2.0f, 0.0f,  0.0f, 0.0f, },
           { m_fWidth / 2.0f, -m_fHeigh / 2.0f, 0.0f,  1.0f, 1.0f, },
           { m_fWidth / 2.0f, m_fHeigh / 2.0f, 0.0f,  1.0f, 0.0f, }
         };

        void* pVertices;
        if( FAILED( m_pVertexBuf->Lock( 0, sizeof(Vertices), (void**)&pVertices,0 ) ) )

memcpy( pVertices, Vertices, sizeof(Vertices) );
m_pVertexBuf->Unlock();


        c. 創建紋理貼圖
        D3DXCreateTextureFromFileA( pDevice, pTexPath, &m_pTexture );


       2. 每幀根據相機位置旋轉公告板

        a. 計算相機朝向
         VECTOR3 vPos;
         pCamera->GetPostion( &vPos );
         VECTOR3 vLookAt;
         pCamera->GetLookAt( &vLookAt );
         m_vCamera = vLookAt - vPos;


        b. 更新公告板方向(只計算在XZ平面的方向爲了避免失真)
         float fAngle = 0;
         if( m_vCamera.x > 0.0f )
            fAngle = -atanf(m_vCamera.z/m_vCamera.x)+D3DX_PI/2;
         else
            fAngle = -atanf(m_vCamera.z/m_vCamera.x)-D3DX_PI/2;


        c. 設置旋轉矩陣
          D3DXMatrixRotationY( &matRotation, fAngle + nIndex * m_nCount / D3DX_PI );


       3. 設置紋理貼圖繪製公告板

        a. 設置紋理阿爾法混合
          pDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
          pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );

          pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE,   true );
          pDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
          pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );


        b. 繪製公告板
          pDevice->SetTexture( 0, m_pTexture );
          pDevice->SetStreamSource( 0, m_pVertexBuf, 0, sizeof(CUSTOMVERTEX) );
          pDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
          pDevice->SetTransform( D3DTS_WORLD, &matBillboard );
          pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );




四. 效果展示:


             Direct9學習之------------------------------公告板技 ...
 
         Direct9學習之------------------------------公告板技 ...
 

                         公告板                   十字交叉公告板


   



五. 其他:

      1. 關於十字交叉公告板:
         所謂十字交叉公告板既是在公告板的基礎上再將矩形旋轉90度,使得兩個公告板交叉。十字交叉公告板比單純公告板表現效果更好。

      2. 關於在UP方向旋轉相機導致公告板穿幫的問題可以採用在XZ平面增加一個頂部公告板的方式解決。
發佈了25 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章