📄 zfxd3d_skinman.cpp
字号:
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 + -