⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zfxd3d_vcache.cpp

📁 This is a book introduce some tech about Game Engine 3D
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                  }
               else break;
               } 
            // deactivate unused stages at all costs
            m_pDevice->SetTextureStageState(iT, D3DTSS_COLOROP, D3DTOP_DISABLE);
            }
         else {
            m_pDevice->SetTexture(0, NULL);
            m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
            }
         }
      else {
         ZFXCOLOR clrWire = m_pZFXD3D->GetWireColor();
         // set material
         D3DMATERIAL9 matW = { 
            clrWire.fR, clrWire.fG, clrWire.fB, clrWire.fA,
            clrWire.fR, clrWire.fG, clrWire.fB, clrWire.fA,
            0.0f,             0.0f,       0.0f,       1.0f,
            0.0f,             0.0f,       0.0f,       1.0f,
            1.0f };
         m_pDevice->SetMaterial(&matW);

         // set no texture for device
         m_pDevice->SetTexture(0, NULL);
         m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
         }
      
      // set alpha states for device
      if (pSkin->bAlpha) {
         m_pDevice->SetRenderState(D3DRS_ALPHAREF, 50);
         m_pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
         m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
         m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
         m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
         m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
         }
      else {
         m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
         m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
         }
      // skin will change now
      m_pZFXD3D->SetActiveSkinID(SkinID);
      } // [device->skin]

   // if using shaders they should be activated by the
   // ActivateVShader methods. Else set FVF
   if (!m_pZFXD3D->UsesShaders())
      m_pDevice->SetFVF(m_pSB[nID].dwFVF);

   // this method is for indexed primitives only
   if (!m_pSB[nID].bIndis) return ZFX_FAIL;

   //  should we use additive rendering?
   if (m_pZFXD3D->UsesAdditiveBlending()) {
      m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
      m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
      m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
      }

   //  should we use rendering to color buffer at all?
   if (!m_pZFXD3D->UsesColorBuffer()) {
      m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
      m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
      m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
      }

   // render content

// STATES OTHER THAT FINAL ELSE NOT EVALUATED /////////////

   if ( sm == RS_SHADE_POINTS ) {
      hr = m_pDevice->DrawPrimitive(
                        D3DPT_POINTLIST, 0,
                        NumVerts);
      }
   else if ( sm == RS_SHADE_LINES ) {
      hr = m_pDevice->DrawIndexedPrimitive(
                     D3DPT_LINELIST, 0,
                     0, NumVerts,
                     StartIndex, NumTris);
      }
   else if ( sm == RS_SHADE_HULLWIRE ) {
      hr = m_pDevice->DrawIndexedPrimitive(
                        D3DPT_LINESTRIP, 0,
                        0, NumVerts,
                        StartIndex, NumTris);
      }
   else { // RS_SHADE_SOLID || RS_SHADE_TRIWIRE
      hr = m_pDevice->DrawIndexedPrimitive(
                        D3DPT_TRIANGLELIST, 0,
                        0, NumVerts,
                        StartIndex, NumTris);
      }

   return hr;
   } // Render
/*----------------------------------------------------------------*/


/**
 * Takes the vertex and index lists and sorts them into one fitting
 * vertex cache that features the same vertexID. If none of those
 * caches is free one will be flushed out. Note that output of pixel
 * to any buffers is not immediately. Call ForcedFlush() if needed.
 * -> IN: ZFXVERTEXID - vertex type to be processed
 *        UINT        - number of vertices in this call
 *        UINT        - number of indices in this call
 *        void        - array of vertices
 *        WORD        - array of indices
 *        ZFXSKIN     - pointer to the skin used for those vertices
 */
HRESULT ZFXD3DVCManager::Render(ZFXVERTEXID VertexID,
                                UINT  nVerts, 
                                UINT  nIndis, 
                                const void *pVerts,
                                const WORD *pIndis,
                                UINT  SkinID) {
   ZFXD3DVCache **pCache=NULL,
                 *pCacheEmpty=NULL,
                 *pCacheFullest=NULL;
   int nEmptyVC   = -1;
   int nFullestVC = 0;

   bool bShaders = m_pZFXD3D->UsesShaders();
   
   // which vertex type is to be processed?
   switch (VertexID) {
      case VID_PS: { pCache = m_CachePS; } break;
      case VID_UU: { pCache = m_CacheUU; } break;
      case VID_UL: { pCache = m_CacheUL; } break;
      case VID_CA: { pCache = m_CacheCA; } break;
      case VID_3T: { pCache = m_Cache3T; } break;
      case VID_TV: { pCache = m_CacheTV; } break;
      default: return ZFX_INVALIDID;
      } // switch

   pCacheFullest = pCache[0];

   // active buffer might change now
   m_dwActiveSB = MAX_ID;

/*   
   // for wireframe sorting is not needed
   if ( GetShadeMode() != RS_SHADE_SOLID) {
      return pCache[0]->Add(nVerts, nIndis, pVerts, 
                            pIndis, bShaders);
      }
*/
   // SEARCH BEST FITTING CACHE FOR THE VERTICES

   // first check if any cache uses same skin. that is the
   // easiest option cause we can just add the verts then.
   for (int i=0; i<NUM_CACHES; i++) {
      if (pCache[i]->UsesSkin(SkinID))
         return pCache[i]->Add(nVerts, nIndis, pVerts, 
                               pIndis, bShaders);
     
      if (pCache[i]->IsEmpty())
         pCacheEmpty = pCache[i];

      if (pCache[i]->NumVerts() > pCacheFullest->NumVerts())
         pCacheFullest = pCache[i];
      }

   // no luck though. second option is to add vertices to
   // a flushed empty cache if any one is available.
   if (pCacheEmpty) {
      pCacheEmpty->SetSkin(SkinID, bShaders);
      return pCacheEmpty->Add(nVerts, nIndis, pVerts, 
                              pIndis, bShaders);
      }

   // still no luck with that one. final option is to force
   // one cache to flush itself so we get an empty cache. We
   // simply choose the fullest cache here to avoid render 
   // calls with just a few verts.
   pCacheFullest->Flush(bShaders);
   pCacheFullest->SetSkin(SkinID, bShaders);
   return pCacheFullest->Add(nVerts, nIndis, pVerts, 
                             pIndis, bShaders);
   } // Render
/*----------------------------------------------------------------*/


/**
 * Render without texture using VID_UU and no shaders
 */
HRESULT ZFXD3DVCManager::RenderNaked(UINT nNumV, const void *pVerts, bool b) {
   HRESULT hr=ZFX_OK;
   InvalidateStates();
   m_pZFXD3D->UseShaders(false);
   m_pDevice->SetTexture(0, NULL);

   if (b)
      m_pDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)
                 m_pSkinMan->m_pTextures[2].pData);
   else
      m_pDevice->SetTexture(0, NULL);


   m_pDevice->SetFVF(FVF_PVERTEX);
   hr = m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 
                                   nNumV/3,
                                   pVerts,
                                   sizeof(PVERTEX));
   return hr;
   } // Render
/*----------------------------------------------------------------*/


/**
 * Set all states to invalid to force reset at next rendering.
 */
void ZFXD3DVCManager::InvalidateStates(void) {
   m_pZFXD3D->SetActiveSkinID(MAX_ID);
   m_dwActiveSB    = MAX_ID;
   m_dwActiveCache = MAX_ID;
   } // InvalidateStates
/*----------------------------------------------------------------*/


/**
 * Use normal Vertex Type here. Render a list of points.
 */
HRESULT ZFXD3DVCManager::RenderPoints(ZFXVERTEXID VID,
                                      UINT nVerts, 
                                      const void *pVerts,
                                      const ZFXCOLOR *pClr) {
   D3DMATERIAL9 mtrl;
   DWORD        dwFVF;
   int          nStride;

   // active skin and static buffer gets invalid
   InvalidateStates();

   if (pClr) {
      memset(&mtrl, 0, sizeof(D3DMATERIAL9));
	   mtrl.Diffuse.r = mtrl.Ambient.r = pClr->fR;
      mtrl.Diffuse.g = mtrl.Ambient.g = pClr->fG;
      mtrl.Diffuse.b = mtrl.Ambient.b = pClr->fB;
      mtrl.Diffuse.a = mtrl.Ambient.a = pClr->fA;
      m_pDevice->SetMaterial(&mtrl);
      }

   m_pDevice->SetTexture(0,NULL);

   // which vertex type is to be processed?
   switch (VID) {
      case VID_PS: { 
         nStride = sizeof(PVERTEX); 
         m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
         dwFVF   = FVF_PVERTEX;
         } break;
      case VID_UU: { 
         nStride = sizeof(VERTEX); 
         m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
         dwFVF   = FVF_VERTEX;
         } break;
      case VID_3T: { 
         nStride = sizeof(VERTEX3T); 
         m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
         dwFVF   = FVF_T3VERTEX;
         } break;
      case VID_TV: { 
         nStride = sizeof(TVERTEX); 
         m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
         dwFVF   = FVF_TVERTEX;
         } break;
      case VID_CA: { 
         nStride = sizeof(CVERTEX); 
         m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
         dwFVF   = FVF_CVERTEX;
         } break;
      case VID_UL: { 
         nStride = sizeof(LVERTEX);
         m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
         dwFVF   = FVF_LVERTEX;
         } break;
      default: return ZFX_INVALIDID;
      } // switch

   // shaders or FVF
   if ( m_pZFXD3D->UsesShaders() ) {
      m_pZFXD3D->ActivateVShader(0, VID);
      m_pZFXD3D->ActivatePShader(0);
      }
   else m_pDevice->SetFVF(dwFVF);

   // render list of points
   if (FAILED(m_pDevice->DrawPrimitiveUP(D3DPT_POINTLIST, nVerts, 
                                         pVerts, nStride))) {
      m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
      return ZFX_FAIL;
      }

   m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
   return ZFX_OK;
   } // RenderPoints
/*----------------------------------------------------------------*/


/**
 * Use normal Vertex Type here. Render a list of lines. 
 */
HRESULT ZFXD3DVCManager::RenderLines(ZFXVERTEXID VID,
                                     UINT nVerts, 
                                     const void *pVerts,
                                     const ZFXCOLOR *pClr,
                                     bool	bStrip) {
   D3DMATERIAL9 mtrl;
   DWORD        dwFVF;
   int          nStride;

   // we will change states
   ForcedFlushAll();

   // active skin and static buffer gets invalid
   InvalidateStates();

   if (pClr) {
      memset(&mtrl, 0, sizeof(D3DMATERIAL9));
	   mtrl.Diffuse.r = mtrl.Ambient.r = pClr->fR;
      mtrl.Diffuse.g = mtrl.Ambient.g = pClr->fG;
      mtrl.Diffuse.b = mtrl.Ambient.b = pClr->fB;
      mtrl.Diffuse.a = mtrl.Ambient.a = pClr->fA;
      m_pDevice->SetMaterial(&mtrl);
      }

   m_pDevice->SetTexture(0, NULL);
   m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
   m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
   m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

   // which vertex type is to be processed?
   switch (VID) {
      case VID_PS: { 
         nStride = sizeof(PVERTEX); 
         m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
         dwFVF   = FVF_PVERTEX;
         } break;
      case VID_UU: { 
         nStride = sizeof(VERTEX); 
         m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
         dwFVF   = FVF_VERTEX;
         } break;
      case VID_3T: { 
         nStride = sizeof(VERTEX3T); 
         m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
         dwFVF   = FVF_T3VERTEX;
         } break;
      case VID_TV: { 
         nStride = sizeof(TVERTEX); 
         m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
         dwFVF   = FVF_TVERTEX;
         } break;
      case VID_CA: { 
         nStride = sizeof(CVERTEX); 
         m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
         dwFVF   = FVF_CVERTEX;
         } break;
      case VID_UL: { 
         nStride = sizeof(LVERTEX);
         m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
         dwFVF   = FVF_LVERTEX;
         } break;
      default: return ZFX_INVALIDID;
      } // switch

   // shaders or FVF
   if ( m_pZFXD3D->UsesShaders() ) {
      m_pZFXD3D->ActivateVShader(0, VID);
      m_pZFXD3D->ActivatePShader(0);
      }
   else m_pDevice->SetFVF(dwFVF);

   // render list of lines
   if (!bStrip) {
      if (FAILED(m_pDevice->DrawPrimitiveUP(D3DPT_LINELIST, nVerts/2, 
                                            pVerts, nStride))) {
         m_pDevice->SetRenderState(D3DRS_LIGHTING , TRUE);
         return ZFX_FAIL;
         }
      }
   else {
      if (FAILED(m_pDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, nVerts-1, 
                                            pVerts, nStride))) {
         m_pDevice->SetRenderState(D3DRS_LIGHTING , TRUE);
         return ZFX_FAIL;
         }
      }
   m_pDevice->SetRenderState(D3DRS_LIGHTING , TRUE);
   return ZFX_OK;
   } // RenderLines
/*----------------------------------------------------------------*/


/**
 * Use normal Vertex Type here. Render one line. 
 */
HRESULT ZFXD3DVCManager::RenderLine(const float *fStart,
                                    const float *fEnd, 
                                    const ZFXCOLOR *pClr) {
   D3DMATERIAL9 mtrl;
   LVERTEX      pVerts[2];

   if (!pClr) return ZFX_INVALIDPARAM;

   // we will change states
   ForcedFlushAll();

   // active skin and static buffer gets invalid
   InvalidateStates();
   
   // make sure state is switched off
   GetZFXD3D()->UseShaders(false);

   // set coordinates
   pVerts[0].x = fStart[0];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -