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

📄 zfxd3d_skinman.cpp

📁 This is a book introduce some tech about Game Engine 3D
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************
 * ZFXEngine!                                                      *
 * (c)2003 by Stefan Zerbst | www.zfx.info                         *
 *-----------------------------------------------------------------*
 * File: ZFXD3D_skinman.cpp                                        *
 * part of render dll implementing direct3d rendering              *
 *******************************************************************/


// I N C L U D E S /////////////////////////////////////////////////

#include "ZFXD3D_skinman.h"   // class definition
#include "ZFX.h"              // return values and stuff

#include "d3dx9.h"         // shader compiler

extern bool g_bLF;


// F U N C T I O N S ///////////////////////////////////////////////

/**
 * Constructor: Initializes vertex cache arrays
 */
ZFXD3DSkinManager::ZFXD3DSkinManager(LPDIRECT3DDEVICE9 pDevice,
                                     FILE *pLog) {
   m_nNumMaterials = 0;
   m_nNumTextures  = 0;
   m_nNumSkins     = 0;
   m_pMaterials    = NULL;
   m_pTextures     = NULL;
   m_pSkins        = NULL;
   m_pLog          = pLog;
   m_pDevice       = pDevice;
   Log("online");
   } // constructor
/*----------------------------------------------------------------*/


/**
 * Destructor: Release vertex cache arrays
 */
ZFXD3DSkinManager::~ZFXD3DSkinManager(void) {

   // release direct3d texture objects
   if (m_pTextures) {
      for (UINT i=0; i<m_nNumTextures; i++) {
         if (m_pTextures[i].pData) {
            ((LPDIRECT3DTEXTURE9)(m_pTextures[i].pData))->Release();
            m_pTextures[i].pData = NULL;
            }
         if (m_pTextures[i].pClrKeys) {
            delete [] m_pTextures[i].pClrKeys;
            m_pTextures[i].pClrKeys = NULL;
            }
         if (m_pTextures[i].chName) {
            delete [] m_pTextures[i].chName;
            m_pTextures[i].chName = NULL;
            }
         }
      free(m_pTextures);
      m_pTextures = NULL;
      }
   
   // release allocated memory
   if (m_pMaterials) {
      free(m_pMaterials);
      m_pMaterials = NULL;
      }

   if (m_pSkins) {
      free(m_pSkins);
      m_pSkins = NULL;
      }
   Log("offline (ok)");
   } // destructor
/*----------------------------------------------------------------*/


/**
 *
 */
void ZFXD3DSkinManager::Reset(void) {
   // release direct3d texture objects
   for (UINT i=0; i<m_nNumTextures; i++) {
      if (m_pTextures[i].pData) {
         ((LPDIRECT3DTEXTURE9)(m_pTextures[i].pData))->Release();
         m_pTextures[i].pData = NULL;
         }
      if (m_pTextures[i].pClrKeys) {
         delete [] m_pTextures[i].pClrKeys;
         m_pTextures[i].pClrKeys = NULL;
         }
      if (m_pTextures[i].chName) {
         delete [] m_pTextures[i].chName;
         m_pTextures[i].chName = NULL;
         }
      }
   
   // release allocated memory
   if (m_pMaterials) {
      free(m_pMaterials);
      m_pMaterials = NULL;
      }
   if (m_pTextures) {
      free(m_pTextures);
      m_pTextures = NULL;
      }
   if (m_pSkins) {
      free(m_pSkins);
      m_pSkins = NULL;
      }

   m_nNumMaterials = 0;
   m_nNumTextures  = 0;
   m_nNumSkins     = 0;
   m_pMaterials    = NULL;
   m_pTextures     = NULL;
   m_pSkins        = NULL;
   } // Reset
/*----------------------------------------------------------------*/


/**
 * Compares if two color values are equal.
 */
inline bool ZFXD3DSkinManager::ColorEqual(const ZFXCOLOR *pCol0, 
                                          const ZFXCOLOR *pCol1) {
   if ( (pCol0->fA != pCol1->fA) ||
        (pCol0->fR != pCol1->fR) ||     
        (pCol0->fG != pCol1->fG) ||
        (pCol0->fB != pCol1->fB) )
      return false;
   return true;
   } // ColorEqual
/*----------------------------------------------------------------*/


/**
 * Returns a copy of the requested skin object if it exists.
 */
ZFXSKIN ZFXD3DSkinManager::GetSkin(UINT nSkinID) {
   if (nSkinID < m_nNumSkins) return m_pSkins[nSkinID];
   else 
      {
      ZFXSKIN EmptySkin;
      return EmptySkin;
      }
   } // GetSkin
/*----------------------------------------------------------------*/


/**
 * Returns a copy of the requested material object if it exists.
 */
ZFXMATERIAL ZFXD3DSkinManager::GetMaterial(UINT nMatID) {
   if (nMatID < m_nNumMaterials)
      return m_pMaterials[nMatID];
   else
      {
      ZFXMATERIAL EmptyMaterial;
      return EmptyMaterial;
      }
   } // GetMaterial
/*----------------------------------------------------------------*/


/**
 * Returns a copy of the requested data about the texture object.
 */
const char* ZFXD3DSkinManager::GetTextureName(UINT nID, float *pfAlpha,
                                              ZFXCOLOR *pAK, UCHAR *pNum) {
   if (nID >= m_nNumTextures) return NULL;

   if (pfAlpha) *pfAlpha = m_pTextures[nID].fAlpha;

   if (pNum) *pNum = m_pTextures[nID].dwNum;

   if (m_pTextures[nID].pClrKeys && pAK) {
      memcpy(pAK, m_pTextures[nID].pClrKeys, 
             sizeof(ZFXCOLOR) * m_pTextures[nID].dwNum);
      }
   
   return m_pTextures[nID].chName;
   } // GetTextureName
/*----------------------------------------------------------------*/


/**
 * Compares if two materials are identical.
 */
bool ZFXD3DSkinManager::MaterialEqual(const ZFXMATERIAL *pMat0, 
                                      const ZFXMATERIAL *pMat1) {
   if ( !ColorEqual(&pMat0->cAmbient,  &pMat1->cAmbient)  || 
        !ColorEqual(&pMat0->cDiffuse,  &pMat1->cDiffuse)  || 
        !ColorEqual(&pMat0->cEmissive, &pMat1->cEmissive) ||
        !ColorEqual(&pMat0->cSpecular, &pMat1->cSpecular) || 
        (pMat0->fPower != pMat1->fPower) )
      return false;
   return true;
   } // MaterialEqual
/*----------------------------------------------------------------*/


/**
 * Creates a new skin object using the given material. texture is
 * set to NULL till a texture is added to that skin.
 * -> IN:  ZFXCOLOR - ambient material  color 
 *         ZFXCOLOR - diffuse material color 
 *         ZFXCOLOR - emissive material color 
 *         ZFXCOLOR - specular material color 
 *         float    - power for specular reflection
 * -> OUT: UINT     - ID to reference new skin
 */
HRESULT ZFXD3DSkinManager::AddSkin(const ZFXCOLOR *pcAmbient,
                                   const ZFXCOLOR *pcDiffuse,
                                   const ZFXCOLOR *pcEmissive,
                                   const ZFXCOLOR *pcSpecular,
                                   float fSpecPower,
                                   UINT  *nSkinID) {
   UINT    nMat, n;
   bool    bMat=false;

   // allocate 50 new memory slots for skins if necessary
   if ( (m_nNumSkins%50) == 0 ) {
      n = (m_nNumSkins+50)*sizeof(ZFXSKIN);
      m_pSkins = (ZFXSKIN*)realloc(m_pSkins, n);
      if (!m_pSkins) return ZFX_OUTOFMEMORY;
      }

   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[m_nNumSkins].nMaterial = nMat;
   else {
      m_pSkins[m_nNumSkins].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++;
      }

   m_pSkins[m_nNumSkins].bAlpha = false;
   for (int i=0; i<8; i++) m_pSkins[m_nNumSkins].nTexture[i] = MAX_ID;

   // save ID and add to count
   (*nSkinID) = m_nNumSkins;
   m_nNumSkins++;

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


/**
 * Add a texture to a given skin. BMP is only loaded if not used yet.
 * Can also be used to set alpha channels on textures for alpha keys
 * and/or overall transparency. Set bool to true in both cases.
 * -> IN: UINT      - ID of skin to receive texture
 *        char*     - name of 24 bit BMP file used as texture
 *        bool      - use alphablending?
 *        float     - value for overall transparency
 *        ZFXCOLOR* - array of RGB values to receive their A value
 *        DWORD     - number of colors in array
 */
HRESULT ZFXD3DSkinManager::AddTexture(UINT      nSkinID, 
                                      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;

   // 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;
            }
         }

      // 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");

⌨️ 快捷键说明

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