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

📄 zfxd3d_skinman.cpp

📁 This is a book introduce some tech about Game Engine 3D
💻 CPP
📖 第 1 页 / 共 3 页
字号:
         return hr;
         }

      // add alpha values if needed
      if (bAlpha) {

         pZFXTex = &m_pTextures[m_nNumTextures];

         // remind information
         pZFXTex->dwNum = dwNumColorKeys;
         pZFXTex->pClrKeys = new ZFXCOLOR[dwNumColorKeys];
         memcpy(pZFXTex->pClrKeys, cColorKeys, 
                sizeof(ZFXCOLOR)*pZFXTex->dwNum);

         LPDIRECT3DTEXTURE9 pTex = (LPDIRECT3DTEXTURE9)pZFXTex->pData;

         // set alpha keys first
         for (DWORD dw=0; dw<dwNumColorKeys; dw++) {
            hr = SetAlphaKey(&pTex,
                             UCHAR(cColorKeys[dw].fR*255),
                             UCHAR(cColorKeys[dw].fG*255),
                             UCHAR(cColorKeys[dw].fB*255),
                             UCHAR(cColorKeys[dw].fA*255));
            if (FAILED(hr)) {
               Log("error: SetAlphaKey() failed");
               return hr;
               }
            }

         if (fAlpha < 1.0f) {
            // remind that value for info purpose
            pZFXTex->fAlpha = fAlpha;

            // now generell transparency
            hr = SetTransparency(&pTex, UCHAR(fAlpha*255));
            if (FAILED(hr)) {
               Log("error: SetTransparency() failed");
               return hr;
               }
            }
         }


      // save ID and add to count
      nTex = m_nNumTextures;
      m_nNumTextures++;
      }

   // put texture ID to skin ID
   for (int i=0; i<8; i++) {
      if (m_pSkins[nSkinID].nTexture[i] == MAX_ID) {
         m_pSkins[nSkinID].nTexture[i] = nTex;
         break;
         }
      }
   return ZFX_OK;
   } // AddTexture
/*----------------------------------------------------------------*/


/**
 * Add a texture to a given skin, but this is supposed to be a
 * heightmap that should be recalculated as normal map needed
 * to perform bump mapping. 
 */
HRESULT ZFXD3DSkinManager::AddTextureHeightmapAsBump(
                                      UINT      nSkinID, 
                                      const     char *chName) {
   ZFXTEXTURE *pZFXTex=NULL;
   HRESULT     hr;
   UINT        nTex, n;
   bool        bTex=false;

   // is skin ID valid at all
   if (nSkinID >= m_nNumSkins) return ZFX_INVALIDID;

   // all 8 stages for this skin already set?
   if (m_pSkins[nSkinID].nTexture[7] != MAX_ID) {
      Log("error: AddTexture() failed, all 8 stages set");
      return ZFX_BUFFERSIZE;
      }

   // do we already have this texture
   for (nTex=0; nTex<m_nNumTextures; nTex++) {
      if ( strcmp(chName, m_pTextures[nTex].chName) == 0 ) {
         bTex = true;
         break;
         }
      } // for [TEXTURES]

   // load new texture if not yet done
   if (!bTex) {
      // allocate 50 new memory slots for textures if necessary
      if ( (m_nNumTextures%50) == 0 ) {
         n = (m_nNumTextures+50)*sizeof(ZFXTEXTURE);
         m_pTextures = (ZFXTEXTURE*)realloc(m_pTextures, n);
         if (!m_pTextures) {
            Log("error: AddTexture() failed, realloc()");
            return ZFX_OUTOFMEMORY;
            }
         }

      // no alpha blending needed
      m_pTextures[m_nNumTextures].fAlpha = 1.0f;
      m_pTextures[m_nNumTextures].pClrKeys = NULL;

      // save texture name
      m_pTextures[m_nNumTextures].chName = new char[strlen(chName)+1];
      memcpy(m_pTextures[m_nNumTextures].chName, chName, strlen(chName)+1);

      // create d3d texture from that pointer
      hr = CreateTexture(&m_pTextures[m_nNumTextures], true);
      if (FAILED(hr)) {
         Log("error: CreateTexture() failed");
         return hr;
         }

      // build normals from heightvalues
      hr = ConvertToNormalmap( &m_pTextures[m_nNumTextures] );
      if (FAILED(hr)) {
         Log("error: ConvertToNormalmap() failed");
         return hr;
         }

      // save ID and add to count
      nTex = m_nNumTextures;
      m_nNumTextures++;
      } // load texture

   // put texture ID to skin ID
   for (int i=0; i<8; i++) {
      if (m_pSkins[nSkinID].nTexture[i] == MAX_ID) {
         m_pSkins[nSkinID].nTexture[i] = nTex;
         break;
         }
      }

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


/**
 * This method is used to exchange a texture in a given skin at the
 * given stage. 
 */
HRESULT ZFXD3DSkinManager::ExchangeTexture(UINT nSkinID, UINT nTexStage,
                                           const char *chName,
                                           bool bAlpha, float fAlpha,
                                           ZFXCOLOR *cColorKeys,
                                           DWORD dwNumColorKeys) {
   ZFXTEXTURE *pZFXTex=NULL;
   HRESULT     hr;
   UINT        nTex, n;
   bool        bTex=false;

   // is skin ID valid at all
   if (nSkinID >= m_nNumSkins) return ZFX_INVALIDID;

   // we can only take 7 textures for one skin
   if (nTexStage > 7) return ZFX_BUFFERSIZE;

   // clear out texture
   if (!chName) {
      m_pSkins[nSkinID].nTexture[nTexStage] = MAX_ID;
      return ZFX_OK;
      }

   // do we already have this texture
   for (nTex=0; nTex<m_nNumTextures; nTex++) {
      if ( strcmp(chName, m_pTextures[nTex].chName) == 0 ) {
         bTex = true;
         break;
         }
      } // for [TEXTURES]

   // load new texture if not yet done
   if (!bTex) {
      // allocate 50 new memory slots for textures if necessary
      if ( (m_nNumTextures%50) == 0 ) {
         n = (m_nNumTextures+50)*sizeof(ZFXTEXTURE);
         m_pTextures = (ZFXTEXTURE*)realloc(m_pTextures, n);
         if (!m_pTextures) return ZFX_OUTOFMEMORY;
         }

      // we use alphablending at least from now on
      if (bAlpha) m_pSkins[nSkinID].bAlpha = true;
      else m_pTextures[m_nNumTextures].fAlpha = 1.0f;

      m_pTextures[m_nNumTextures].pClrKeys = NULL;

      // save texture name
      m_pTextures[m_nNumTextures].chName = new char[strlen(chName)+1];
      memcpy(m_pTextures[m_nNumTextures].chName, chName, strlen(chName)+1);

      // create d3d texture from that pointer
      hr = CreateTexture(&m_pTextures[m_nNumTextures], bAlpha);
      if (FAILED(hr)) {
         Log("error: CreateTexture() failed");
         return hr;
         }

      // add alpha values if needed
      if (bAlpha) {

         pZFXTex = &m_pTextures[m_nNumTextures];

         // remind information
         pZFXTex->dwNum = dwNumColorKeys;
         pZFXTex->pClrKeys = new ZFXCOLOR[dwNumColorKeys];
         memcpy(pZFXTex->pClrKeys, cColorKeys, 
                sizeof(ZFXCOLOR)*pZFXTex->dwNum);

         LPDIRECT3DTEXTURE9 pTex = (LPDIRECT3DTEXTURE9)pZFXTex->pData;

         // set alpha keys first
         for (DWORD dw=0; dw<dwNumColorKeys; dw++) {
            hr = SetAlphaKey(&pTex,
                             UCHAR(cColorKeys[dw].fR*255),
                             UCHAR(cColorKeys[dw].fG*255),
                             UCHAR(cColorKeys[dw].fB*255),
                             UCHAR(cColorKeys[dw].fA*255));
            if (FAILED(hr)) {
               Log("error: SetAlphaKey() failed");
               return hr;
               }
            }

         if (fAlpha < 1.0f) {
            // remind that value for info purpose
            pZFXTex->fAlpha = fAlpha;

            // now generell transparency
            hr = SetTransparency(&pTex, UCHAR(fAlpha*255));
            if (FAILED(hr)) {
               Log("error: SetTransparency() failed");
               return hr;
               }
            }
         }


      // save ID and add to count
      nTex = m_nNumTextures;
      m_nNumTextures++;
      }

   // put texture ID to skin ID
   m_pSkins[nSkinID].nTexture[nTexStage] = nTex;
   return ZFX_OK;
   } // ExchangeTexture
/*----------------------------------------------------------------*/


/**
 * This method lets you exchange the material used in the given skin. 
 */
HRESULT ZFXD3DSkinManager::ExchangeMaterial(
                               UINT nSkinID,
                               const ZFXCOLOR *pcAmbient,
                               const ZFXCOLOR *pcDiffuse,
                               const ZFXCOLOR *pcEmissive,
                               const ZFXCOLOR *pcSpecular,
                               float fSpecPower) {
   UINT nMat=0, n=0;
   bool bMat=false;

   // is skin ID valid at all
   if (nSkinID >= m_nNumSkins) return ZFX_INVALIDID;

   ZFXMATERIAL mat;
   mat.cAmbient  = *pcAmbient;
   mat.cDiffuse  = *pcDiffuse;
   mat.cEmissive = *pcEmissive;
   mat.cSpecular = *pcSpecular;
   mat.fPower    = fSpecPower;

   // do we already have an equal material
   for (nMat=0; nMat<m_nNumMaterials; nMat++) {
      if ( MaterialEqual(&mat, &m_pMaterials[nMat]) ) {
         bMat = true;
         break;
         }
      } // for [MATERIALS]

   // if exists store its ID otherwise create it new
   if (bMat) m_pSkins[nSkinID].nMaterial = nMat;

   // else make a new material accordingly
   else {
      m_pSkins[nSkinID].nMaterial = m_nNumMaterials;

      // allocate 50 new memory slots for materials if necessary
      if ( (m_nNumMaterials%50) == 0 ) {
         n = (m_nNumMaterials+50)*sizeof(ZFXMATERIAL);
         m_pMaterials = (ZFXMATERIAL*)realloc(m_pMaterials, n);
         if (!m_pMaterials) return ZFX_OUTOFMEMORY;
         }
      memcpy(&m_pMaterials[m_nNumMaterials], &mat, sizeof(ZFXMATERIAL));
      m_nNumMaterials++;
      }

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


#define RGB16BIT(r,g,b) ((b%32) + ((g%64) << 5) + ((r%32) << 11))

/**
 * Creates a d3dtexture object and loads the image data from disc.
 * -> IN: ZFXTEXTURE - reference to texture object to store data
 */
HRESULT ZFXD3DSkinManager::CreateTexture(ZFXTEXTURE *pTexture, bool bAlpha) {
   D3DLOCKED_RECT     d3dRect;
   D3DFORMAT          fmt;
   DIBSECTION         dibS;
   HRESULT            hr;
   int                LineWidth;
   void              *pMemory=NULL;

   HBITMAP hBMP = (HBITMAP)LoadImage(NULL, pTexture->chName,
                                     IMAGE_BITMAP,0,0,
                                     LR_LOADFROMFILE |
                                     LR_CREATEDIBSECTION);
   if (!hBMP) {
      Log("error: cannot open texture \"%s\"", pTexture->chName);
      return ZFX_FILENOTFOUND;
      }

   GetObject(hBMP, sizeof(DIBSECTION), &dibS);

   // we support only 24 bit bitmaps
   if (dibS.dsBmih.biBitCount != 24) {
      DeleteObject(hBMP);
      Log("error: texture is not 24 bit \"%s\"", pTexture->chName);
      return ZFX_INVALIDFILE;

⌨️ 快捷键说明

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