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

📄 zfxd3d_misc.cpp

📁 This is a book introduce some tech about Game Engine 3D
💻 CPP
📖 第 1 页 / 共 4 页
字号:
   float X = m_fNear/(m_fNear-m_fFar);
   m_mProjO[0]._33 = m_mProjO[1]._33 = Q;
   m_mProjO[2]._33 = m_mProjO[3]._33 = Q;
   m_mProjO[0]._43 = m_mProjO[1]._43 = X;
   m_mProjO[2]._43 = m_mProjO[3]._43 = X;

   // change perspective projection
   Q *= m_fFar;
   X = -Q * m_fNear;
   m_mProjP[0]._33 = m_mProjP[1]._33 = Q;
   m_mProjP[2]._33 = m_mProjP[3]._33 = Q;
   m_mProjP[0]._43 = m_mProjP[1]._43 = X;
   m_mProjP[2]._43 = m_mProjP[3]._43 = X;
   } // SetClippingPlanes
/*----------------------------------------------------------------*/


/**
 * Call this prior to but not instead of SetMode(ORTHO,n)
 */
void ZFXD3D::SetOrthoScale(float fScale, int n) {
   float fW = ((float)m_dwWidth)/m_dwHeight * fScale;
   float fH = fScale;
   memset(&m_mProjO[n], 0, sizeof(D3DMATRIX));
   m_mProjO[n]._11 = 2.0f / fW;
   m_mProjO[n]._22 = 2.0f / fH;
   m_mProjO[n]._33 = 1.0f / (m_fFar-m_fNear);
   m_mProjO[n]._43 = m_fNear / (m_fNear-m_fFar);
   m_mProjO[n]._44 = 1.0f;
   } // SetOrthoScale
/*----------------------------------------------------------------*/


/**
 * Calculate orthogonal projection and view matrix to render
 * vertices who's world-coordinates are given in screen space.
 */
void ZFXD3D::Prepare2D(void) {
   // set matrices to identity
   memset(&m_mProj2D, 0, sizeof(float)*16); 
   memset(&m_mView2D, 0, sizeof(float)*16); 
   m_mView2D._11 = m_mView2D._33 = m_mView2D._44 = 1.0f;

   // orthogonal projection matrix
   m_mProj2D._11 =  2.0f/(float)m_dwWidth;
   m_mProj2D._22 =  2.0f/(float)m_dwHeight;
   m_mProj2D._33 =  1.0f/(m_fFar-m_fNear);
   m_mProj2D._43 = -m_fNear*(1.0f/(m_fFar-m_fNear));
   m_mProj2D._44 =  1.0f;

   // 2D view matrix
   float tx, ty, tz;
   tx = -((int)m_dwWidth) + m_dwWidth * 0.5f;
   ty =  m_dwHeight - m_dwHeight  * 0.5f;
   tz =  m_fNear + 0.1f;

   m_mView2D._22 = -1.0f;
   m_mView2D._41 = tx; 
   m_mView2D._42 = ty; 
   m_mView2D._43 = tz;
   }// Prepare2D
/*----------------------------------------------------------------*/


/**
 * Retrieve active frustrum planes, normals pointing outwards.
 * -> IN: ZFXPlane* - address to store 6 planes
 */
HRESULT ZFXD3D::GetFrustrum(ZFXPlane *p) {
   // left plane
   p[0].m_vcN.x = -(m_mViewProj._14 + m_mViewProj._11);
   p[0].m_vcN.y = -(m_mViewProj._24 + m_mViewProj._21);
   p[0].m_vcN.z = -(m_mViewProj._34 + m_mViewProj._31);
   p[0].m_fD    = -(m_mViewProj._44 + m_mViewProj._41);

   // right plane
   p[1].m_vcN.x = -(m_mViewProj._14 - m_mViewProj._11);
   p[1].m_vcN.y = -(m_mViewProj._24 - m_mViewProj._21);
   p[1].m_vcN.z = -(m_mViewProj._34 - m_mViewProj._31);
   p[1].m_fD    = -(m_mViewProj._44 - m_mViewProj._41);

   // top plane
   p[2].m_vcN.x = -(m_mViewProj._14 - m_mViewProj._12);
   p[2].m_vcN.y = -(m_mViewProj._24 - m_mViewProj._22);
   p[2].m_vcN.z = -(m_mViewProj._34 - m_mViewProj._32);
   p[2].m_fD    = -(m_mViewProj._44 - m_mViewProj._42);
   
   // bottom plane
   p[3].m_vcN.x = -(m_mViewProj._14 + m_mViewProj._12);
   p[3].m_vcN.y = -(m_mViewProj._24 + m_mViewProj._22);
   p[3].m_vcN.z = -(m_mViewProj._34 + m_mViewProj._32);
   p[3].m_fD    = -(m_mViewProj._44 + m_mViewProj._42);

   // near plane
   p[4].m_vcN.x = -m_mViewProj._13;
   p[4].m_vcN.y = -m_mViewProj._23;
   p[4].m_vcN.z = -m_mViewProj._33;
   p[4].m_fD    = -m_mViewProj._43;

   // far plane
   p[5].m_vcN.x = -(m_mViewProj._14 - m_mViewProj._13);
   p[5].m_vcN.y = -(m_mViewProj._24 - m_mViewProj._23);
   p[5].m_vcN.z = -(m_mViewProj._34 - m_mViewProj._33);
   p[5].m_fD    = -(m_mViewProj._44 - m_mViewProj._43);

   // normalize frustrum normals
   for (int i=0;i<6;i++) {
      float fL = p[i].m_vcN.GetLength();
      p[i].m_vcN /= fL;
      p[i].m_fD  /= fL;
      }

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

/**
 * Cast a world ray from a given position on screen.
 * -> IN:  POINT      - point in screen coordinates
 * -> OUT: ZFXVector* - to fill with 4 floats for origin vextor
 *         ZFXVector* - to fill with 4 floats for ray direction
 */
void  ZFXD3D::Transform2Dto3D(const POINT &pt, 
                              ZFXVector *vcOrig, 
                              ZFXVector *vcDir) {
   D3DMATRIX *pView=NULL, *pProj=NULL;
   ZFXMatrix mInvView;
   ZFXVector vcS;
   DWORD     dwWidth,
             dwHeight;
 
   // if 2D mode
   if (m_Mode == EMD_TWOD) {
      dwWidth  = m_dwWidth;
      dwHeight = m_dwHeight;

      pView = &m_mView2D;
      }
   // else ortho or perspective projection
   else {
      dwWidth  = m_VP[m_nStage].Width,
      dwHeight = m_VP[m_nStage].Height;

      pView = &m_mView3D;

      if (m_Mode == EMD_PERSPECTIVE)
         pProj = &m_mProjP[m_nStage];
      else
         pProj = &m_mProjO[m_nStage];
      }

   // resize to viewportspace [-1,1] -> projection
   vcS.x =  ( ((pt.x*2.0f) / dwWidth) -1.0f) / m_mProjP[m_nStage]._11;
   vcS.y = -( ((pt.y*2.0f) / dwHeight)-1.0f) / m_mProjP[m_nStage]._22;
   vcS.z = 1.0f;

   // invert view matrix
   mInvView.InverseOf(*((ZFXMatrix*)&m_mView3D._11));

   // ray from screen to worldspace
   (*vcDir).x = (vcS.x * mInvView._11)
              + (vcS.y * mInvView._21)
              + (vcS.z * mInvView._31);
   (*vcDir).y = (vcS.x * mInvView._12)
              + (vcS.y * mInvView._22)
              + (vcS.z * mInvView._32);
   (*vcDir).z = (vcS.x * mInvView._13)
              + (vcS.y * mInvView._23)
              + (vcS.z * mInvView._33);
   
   // inverse translation.
   (*vcOrig).x = mInvView._41;
   (*vcOrig).y = mInvView._42;
   (*vcOrig).z = mInvView._43;

   // normalize
   (*vcOrig).Normalize();
   }
/*----------------------------------------------------------------*/

/**
 * Cast given point from world space to screen space.
 * -> IN:     ZFXVector - vector to position in 3d space
 * -> RETURN: POINT     - corresponding point in 2d screen space
 */
POINT ZFXD3D::Transform3Dto2D(const ZFXVector &vcPoint) {
   POINT pt;
   float fClip_x, fClip_y;
   float fXp, fYp, fWp;
   DWORD dwWidth, dwHeight;

   // if 2D mode use whole screen
   if (m_Mode == EMD_TWOD) {
      dwWidth  = m_dwWidth;
      dwHeight = m_dwHeight;
      }
   // else take viewport dimensions
   else {
      dwWidth  = m_VP[m_nStage].Width,
      dwHeight = m_VP[m_nStage].Height;
      }

   fClip_x = (float)(dwWidth  >> 1);
   fClip_y = (float)(dwHeight >> 1);

   fXp = (m_mViewProj._11*vcPoint.x) + (m_mViewProj._21*vcPoint.y) 
       + (m_mViewProj._31*vcPoint.z) + m_mViewProj._41;
   fYp = (m_mViewProj._12*vcPoint.x) + (m_mViewProj._22*vcPoint.y) 
       + (m_mViewProj._32*vcPoint.z) + m_mViewProj._42;
   fWp = (m_mViewProj._14*vcPoint.x) + (m_mViewProj._24*vcPoint.y) 
       + (m_mViewProj._34*vcPoint.z) + m_mViewProj._44;

   float fWpInv = 1.0f / fWp;

   // transform from [-1,1] to actual viewport dimensions
   pt.x = (LONG)( (1.0f + (fXp * fWpInv)) * fClip_x );
   pt.y = (LONG)( (1.0f + (fYp * fWpInv)) * fClip_y );

   return pt;
   }
/*----------------------------------------------------------------*/


/**
 * Cast the current cursor position to world coordinates in ortho
 * views. User has to take care of third coordinate. 
 */
ZFXVector ZFXD3D::Transform2Dto2D(UINT nHwnd, float fScale, 
                                  const POINT *pPt, ZFXAXIS axis) {
   ZFXVector vcResult(0,0,0);
   POINT ptC = { -1, -1 };
   RECT  rect;

   if (!m_d3dpp.Windowed) return vcResult;
   else if (m_pChain[nHwnd]==NULL) return vcResult;

   GetClientRect(m_hWnd[nHwnd], &rect);

   if (!pPt) {
      GetCursorPos(&ptC);
      ScreenToClient(m_hWnd[nHwnd], &ptC);
      }
   else memcpy(&ptC, pPt, sizeof(POINT));

   ptC.x -= long( ((float)rect.right) /2.0f );
   ptC.y -= long( ((float)rect.bottom)/2.0f );

   // use buttom for both as horizontal view angle is not known
   if (axis == Z_AXIS) {
      vcResult.x = ((float)ptC.x)/rect.bottom * fScale;
      vcResult.y = -((float)ptC.y)/rect.bottom * fScale;
      vcResult.z = 0.0f;
      }
   else if (axis == X_AXIS) {
      vcResult.x = 0.0f;
      vcResult.y = -((float)ptC.y)/rect.bottom * fScale;
      vcResult.z = ((float)ptC.x)/rect.bottom * fScale;
      }
   else if (axis == Y_AXIS) {
      vcResult.x = ((float)ptC.x)/rect.bottom * fScale;
      vcResult.y = 0.0f;
      vcResult.z = -((float)ptC.y)/rect.bottom * fScale;
      }
   return vcResult;
   } // Transform2Dto2D
/*----------------------------------------------------------------*/


/**
 * This functions evaluates shader support and initializes everything
 * we need to use shaders if they are available.
 */
void ZFXD3D::PrepareShaderStuff(void) {
   D3DCAPS9 d3dCaps;

   if (FAILED(m_pDevice->GetDeviceCaps(&d3dCaps))) {
      Log("error: GetDeviceCaps() in PrepareShaderStuff failed");
      m_bCanDoShaders = false;
      return;
      }

   if (d3dCaps.VertexShaderVersion < D3DVS_VERSION(1,1) ) {
      Log("warning: Vertex Shader Version < 1.1 => no support");
      m_bCanDoShaders = false;
      return;
      }

   if (d3dCaps.PixelShaderVersion < D3DPS_VERSION(1,1) ) {
      Log("warning: Pixel Shader Version < 1.1 => no support");
      m_bCanDoShaders = false;
      return;
      }

   // vertex declarations needed for shaders
   D3DVERTEXELEMENT9 declPVertex[] =
      {
         { 0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_POSITION, 0}, 
         D3DDECL_END()
      };

   D3DVERTEXELEMENT9 declVertex[] =
      {
         { 0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_POSITION, 0}, 
         { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_NORMAL,   0}, 
         { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_TEXCOORD, 0}, 
         D3DDECL_END()
      };

   D3DVERTEXELEMENT9 declLVertex[] =
      {
         { 0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_POSITION, 0}, 
         { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_COLOR,    0}, 
         { 0, 16, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_TEXCOORD, 0}, 
         D3DDECL_END()
      };

   D3DVERTEXELEMENT9 declCVertex[] =
      {
         { 0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_POSITION, 0}, 
         { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_NORMAL,   0}, 
         { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_TEXCOORD, 0}, 
         { 0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_TEXCOORD, 1}, 
         D3DDECL_END()
      };

   D3DVERTEXELEMENT9 decl3TVertex[] =
      {
         { 0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_POSITION, 0}, 
         { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_NORMAL,   0}, 
         { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_TEXCOORD, 0}, 
         { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_TEXCOORD, 1}, 
         { 0, 40, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_TEXCOORD, 2}, 
         D3DDECL_END()
      };

   D3DVERTEXELEMENT9 declTVertex[] = 
      {
         { 0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_POSITION, 0}, 
         { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_NORMAL,   0}, 
         { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_TEXCOORD, 0}, 
         { 0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,  D3DDECLUSAGE_TANGENT,  0}, 
         D3DDECL_END() 
      };

   // create the declarations
   m_pDevice->CreateVertexDeclaration(declVertex,   &m_pDeclVertex);
   m_pDevice->CreateVertexDeclaration(declPVertex,  &m_pDeclPVertex);
   m_pDevice->CreateVertexDeclaration(declLVertex,  &m_pDeclLVertex);
   m_pDevice->CreateVertexDeclaration(declCVertex,  &m_pDeclCVertex);
   m_pDevice->CreateVertexDeclaration(decl3TVertex, &m_pDecl3TVertex);
   m_pDevice->CreateVertexDeclaration(declTVertex,  &m_pDeclTVertex);
   m_pDevice->SetFVF(NULL);

   m_bCanDoShaders  = true;
   Log("use of shaders activated (VS 1.1, PS 1.1)");
   } // PrepareShaderStuff
/*----------------------------------------------------------------*/


/**
 * Switch use of shaders on and off if shaders are possible.
 */

⌨️ 快捷键说明

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