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

📄 zfxd3d_misc.cpp

📁 This is a book introduce some tech about Game Engine 3D
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*----------------------------------------------------------------*/


// enable / disable use of color buffer
void ZFXD3D::UseColorBuffer(bool b) {
   // clear out buffers prior to state changes
   m_pVertexMan->ForcedFlushAll();
   m_pVertexMan->InvalidateStates();

   m_bColorBuffer = b;

   if (!b) {
      m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
      m_pDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ZERO);
      m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
      }
   else {
      m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
      m_pDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ONE);
      m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
      }
   } // UseColorBuffer
/*----------------------------------------------------------------*/


// SET VARIOUS RENDERSTATES AND STUFF LIKE THAT
void ZFXD3D::SetBackfaceCulling(ZFXRENDERSTATE rs) {
   // clear out buffers prior to state changes
   m_pVertexMan->ForcedFlushAll();

   if (rs == RS_CULL_CW) 
      m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);

   else if (rs == RS_CULL_CCW) 
      m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

   else if (rs == RS_CULL_NONE) 
      m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
   } // SetBackfaceCulling
/*----------------------------------------------------------------*/

void ZFXD3D::SetStencilBufferMode(ZFXRENDERSTATE rs, DWORD dw) {
   // clear out buffers prior to state changes
   m_pVertexMan->ForcedFlushAll();

   switch (rs) {
      // switch on and off
      case RS_STENCIL_DISABLE:
         m_pDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
         break;
      case RS_STENCIL_ENABLE:
         m_pDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
         break;
      case RS_DEPTHBIAS:
         m_pDevice->SetRenderState(D3DRS_DEPTHBIAS, dw);

      // function modes and values
      case RS_STENCIL_FUNC_ALWAYS:
         m_pDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
         break;
      case RS_STENCIL_FUNC_LESSEQUAL:
         m_pDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL);
         break;
      case RS_STENCIL_MASK:
         m_pDevice->SetRenderState(D3DRS_STENCILMASK, dw);
         break;
      case RS_STENCIL_WRITEMASK:
         m_pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, dw);
         break;
      case RS_STENCIL_REF:
         m_pDevice->SetRenderState(D3DRS_STENCILREF, dw);
         break;

      // stencil test fails modes
      case RS_STENCIL_FAIL_DECR:
         m_pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_DECR);
         break;
      case RS_STENCIL_FAIL_INCR:
         m_pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
         break;
      case RS_STENCIL_FAIL_KEEP:
         m_pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
         break;

      // stencil test passes but z test fails modes
      case RS_STENCIL_ZFAIL_DECR:
         m_pDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
         break;
      case RS_STENCIL_ZFAIL_INCR:
         m_pDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR);
         break;
      case RS_STENCIL_ZFAIL_KEEP:
         m_pDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
         break;

      // stencil test passes modes
      case RS_STENCIL_PASS_DECR:
         m_pDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR);
         break;
      case RS_STENCIL_PASS_INCR:
         m_pDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR);
         break;
      case RS_STENCIL_PASS_KEEP:
         m_pDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
         break;
      } // switch
   } // SetStencilBufferMode
/*----------------------------------------------------------------*/


void ZFXD3D::UseStencilShadowSettings(bool b) {
   ZFXMatrix matProj;

   m_pVertexMan->InvalidateStates();

   if (b) {
      m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE,  FALSE);
      m_pDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
      m_pDevice->SetRenderState(D3DRS_SHADEMODE,     D3DSHADE_FLAT);
      m_pDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
      m_pDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
      m_pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
      m_pDevice->SetRenderState(D3DRS_STENCILREF,       0x1);
      m_pDevice->SetRenderState(D3DRS_STENCILMASK,      0xffffffff);
      m_pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
      m_pDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR);
      UseColorBuffer(false);
      }
   else {
      m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
      m_pDevice->SetRenderState(D3DRS_CULLMODE,  D3DCULL_CCW);
      m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE,     TRUE);
      m_pDevice->SetRenderState(D3DRS_STENCILENABLE,    FALSE);
      m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
      UseColorBuffer(true);
      SetMode(m_Mode, m_nStage);
      }
   } // UseStencilShadowSettings
/*----------------------------------------------------------------*/


void ZFXD3D::SetDepthBufferMode(ZFXRENDERSTATE rs) {
   // clear out buffers prior to state changes
   m_pVertexMan->ForcedFlushAll();

   if (rs == RS_DEPTH_READWRITE) {
      m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
      m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
      }

   else if (rs == RS_DEPTH_READONLY) {
      m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
      m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
      }

   else if (rs == RS_DEPTH_NONE){
      m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
      m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
      }
   } // SetDepthBufferMode
/*----------------------------------------------------------------*/

inline DWORD FtoDW( FLOAT f ) { return *((DWORD*)&f); }

void ZFXD3D::SetShadeMode(ZFXRENDERSTATE smd, float f, const ZFXCOLOR *pClr) {

   // copy color if it was given
   if ( pClr  && !m_pSkinMan->ColorEqual( pClr, &m_clrWire) ) { 
      m_pVertexMan->ForcedFlushAll();
      m_pVertexMan->InvalidateStates();
      memcpy(&m_clrWire, pClr, sizeof(ZFXCOLOR));
      }
   
   // no change in current mode
   if (smd == m_ShadeMode) {
      // but maybe change in size
      if (smd==RS_SHADE_POINTS) {
         m_pVertexMan->ForcedFlushAll();
         m_pDevice->SetRenderState(D3DRS_POINTSIZE, FtoDW(f));
         }
      return;
      }
   else {
      m_pVertexMan->ForcedFlushAll();
      }

   if (smd == RS_SHADE_TRIWIRE) {
      // only triangle wireframe ist set via d3d shade mode
      m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
      m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
      m_ShadeMode = smd;
      }
   else {
      if (smd != RS_SHADE_SOLID) {
         m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
         }
      m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
      m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
      m_ShadeMode = smd;
      }

   if (smd == RS_SHADE_POINTS) {
      if (f > 0.0f) {
         m_pDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
         m_pDevice->SetRenderState(D3DRS_POINTSCALEENABLE,  TRUE);
         m_pDevice->SetRenderState(D3DRS_POINTSIZE,     FtoDW( f ));
         m_pDevice->SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(0.00f));
         m_pDevice->SetRenderState(D3DRS_POINTSCALE_A,  FtoDW(0.00f));
         m_pDevice->SetRenderState(D3DRS_POINTSCALE_B,  FtoDW(0.00f));
         m_pDevice->SetRenderState(D3DRS_POINTSCALE_C,  FtoDW(1.00f));
         }
      else {
         m_pDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
         m_pDevice->SetRenderState(D3DRS_POINTSCALEENABLE,  FALSE);
         }
      }
   else {
      m_pDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
      m_pDevice->SetRenderState(D3DRS_POINTSCALEENABLE,  FALSE);
      }

   // update depending states
   m_pVertexMan->InvalidateStates();
   } // SetShadeMode
/*----------------------------------------------------------------*/



HRESULT ZFXD3D::SetTextureStage(UCHAR n, ZFXRENDERSTATE rs) {
   D3DCAPS9 caps;

   m_pDevice->GetDeviceCaps(&caps);
   if (caps.MaxSimultaneousTextures < (n+1)) 
      return ZFX_FAIL;

   switch (rs) {
      case RS_NONE:
         m_TOP[n] = D3DTOP_DISABLE;
         break;
      case RS_TEX_ADDSIGNED:
         m_TOP[n] = D3DTOP_ADDSIGNED;
         break;
      case RS_TEX_MODULATE:
         m_TOP[n] = D3DTOP_MODULATE;
         break;

      default: break;
      } // switch


   return ZFX_OK;
   } // SetTextureStage
/*----------------------------------------------------------------*/


HRESULT ZFXD3D::SetLight(const ZFXLIGHT *pLight, UCHAR nStage) {
   D3DLIGHT9 d3dLight;

   // switch it off
   if (!pLight) {
      m_pDevice->LightEnable(nStage, FALSE);
      return ZFX_OK;
      }

   memset(&d3dLight, 0, sizeof(D3DLIGHT9));

   switch (pLight->Type) {
      case LGT_DIRECTIONAL:
         // set light values
         d3dLight.Type = D3DLIGHT_DIRECTIONAL;

         // copy light direction
         memcpy(&d3dLight.Direction, 
                &pLight->vcDirection,
                sizeof(float)*3);
         break;

      case LGT_POINT:
         // set light values
         d3dLight.Type  = D3DLIGHT_POINT;
         d3dLight.Range = pLight->fRange;

         d3dLight.Attenuation1 = 1.0f;

         // copy light position
         memcpy(&d3dLight.Position, 
                &pLight->vcPosition,
                sizeof(float)*3);
         break;

      case LGT_SPOT:
         // set light values
         d3dLight.Type     = D3DLIGHT_SPOT;
         d3dLight.Range    = pLight->fRange;
         d3dLight.Falloff  = 1.0f;
         d3dLight.Theta    = pLight->fTheta;
         d3dLight.Phi      = pLight->fPhi;

         d3dLight.Attenuation0 = pLight->fAttenuation0;
         d3dLight.Attenuation1 = pLight->fAttenuation1;
         d3dLight.Attenuation2 = 1.0f;

         // copy light position
         memcpy(&d3dLight.Position, 
                &pLight->vcPosition,
                sizeof(float)*3);

         // copy light direction
         memcpy(&d3dLight.Direction, 
                &pLight->vcDirection,
                sizeof(float)*3);
         break;
      } 

   memcpy(&d3dLight.Ambient, &pLight->cAmbient,
          sizeof(float)*4);

   memcpy(&d3dLight.Diffuse, &pLight->cDiffuse,
          sizeof(float)*4);

   memcpy(&d3dLight.Specular, &pLight->cSpecular,
          sizeof(float)*4);


   m_pDevice->SetLight(nStage, &d3dLight);
   m_pDevice->LightEnable(nStage, TRUE);

   return ZFX_OK;
   } // SetLight
/*----------------------------------------------------------------*/


// the user wants to render additive
void ZFXD3D::UseAdditiveBlending(bool b) {
   if (m_bAdditive == b) return;

   // clear all vertex caches
   m_pVertexMan->ForcedFlushAll();
   m_pVertexMan->InvalidateStates();

   m_bAdditive = b;

   if (!m_bAdditive) {
      m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
      m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
      m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
      }
   } // UseAdditiveBlending
/*----------------------------------------------------------------*/


// the user wants to render without textures
void ZFXD3D::UseTextures(bool b) {
   if (m_bTextures == b) return;

   // clear all vertex caches
   m_pVertexMan->ForcedFlushAll();
   m_pVertexMan->InvalidateStates();

   m_bTextures = b;
   } // UseAdditiveBlending
/*----------------------------------------------------------------*/

⌨️ 快捷键说明

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