#include "StdAfx.h" #include "Material.h" #include "Mesh.h" #include "../eterbase/Filename.h" #include "../eterlib/ResourceManager.h" #include "../eterlib/StateManager.h" #include "../eterlib/GrpScreen.h" CGraphicImageInstance CGrannyMaterial::ms_akSphereMapInstance[SPHEREMAP_NUM]; D3DXVECTOR3 CGrannyMaterial::ms_v3SpecularTrans(0.0f, 0.0f, 0.0f); D3DXMATRIX CGrannyMaterial::ms_matSpecular; D3DXCOLOR g_fSpecularColor = D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f); void CGrannyMaterial::TranslateSpecularMatrix(float fAddX, float fAddY, float fAddZ) { static float SPECULAR_TRANSLATE_MAX = 1000000.0f; ms_v3SpecularTrans.x+=fAddX; ms_v3SpecularTrans.y+=fAddY; ms_v3SpecularTrans.z+=fAddZ; if (ms_v3SpecularTrans.x>=SPECULAR_TRANSLATE_MAX) ms_v3SpecularTrans.x=0.0f; if (ms_v3SpecularTrans.y>=SPECULAR_TRANSLATE_MAX) ms_v3SpecularTrans.y=0.0f; if (ms_v3SpecularTrans.z>=SPECULAR_TRANSLATE_MAX) ms_v3SpecularTrans.z=0.0f; D3DXMatrixTranslation(&ms_matSpecular, ms_v3SpecularTrans.x, ms_v3SpecularTrans.y, ms_v3SpecularTrans.z ); } void CGrannyMaterial::ApplyRenderState() { assert(m_pfnApplyRenderState!=NULL && "CGrannyMaterial::SaveRenderState"); (this->*m_pfnApplyRenderState)(); } void CGrannyMaterial::RestoreRenderState() { assert(m_pfnRestoreRenderState!=NULL && "CGrannyMaterial::RestoreRenderState"); (this->*m_pfnRestoreRenderState)(); } void CGrannyMaterial::Copy(CGrannyMaterial& rkMtrl) { m_pgrnMaterial = rkMtrl.m_pgrnMaterial; m_roImage[0] = rkMtrl.m_roImage[0]; m_roImage[1] = rkMtrl.m_roImage[1]; m_eType = rkMtrl.m_eType; } CGrannyMaterial::CGrannyMaterial() { m_bTwoSideRender = false; m_dwLastCullRenderStateForTwoSideRendering = D3DCULL_CW; Initialize(); } CGrannyMaterial::~CGrannyMaterial() { } CGrannyMaterial::EType CGrannyMaterial::GetType() const { return m_eType; } void CGrannyMaterial::SetImagePointer(int iStage, CGraphicImage* pImage) { assert(iStage<2 && "CGrannyMaterial::SetImagePointer"); m_roImage[iStage]=pImage; } bool CGrannyMaterial::IsIn(const char* c_szImageName, int* piStage) { std::string strImageName = c_szImageName; CFileNameHelper::StringPath(strImageName); granny_texture * pgrnDiffuseTexture = GrannyGetMaterialTextureByType(m_pgrnMaterial, GrannyDiffuseColorTexture); if (pgrnDiffuseTexture) { std::string strDiffuseFileName = pgrnDiffuseTexture->FromFileName; CFileNameHelper::StringPath(strDiffuseFileName); if (strDiffuseFileName == strImageName) { *piStage=0; return true; } } granny_texture * pgrnOpacityTexture = GrannyGetMaterialTextureByType(m_pgrnMaterial, GrannyOpacityTexture); if (pgrnOpacityTexture) { std::string strOpacityFileName = pgrnOpacityTexture->FromFileName; CFileNameHelper::StringPath(strOpacityFileName); if (strOpacityFileName == strImageName) { *piStage=1; return true; } } return false; } void CGrannyMaterial::SetSpecularInfo(BOOL bFlag, float fPower, BYTE uSphereMapIndex) { m_fSpecularPower = fPower; m_bSphereMapIndex = uSphereMapIndex; m_bSpecularEnable = bFlag; if (bFlag) { m_pfnApplyRenderState = &CGrannyMaterial::__ApplySpecularRenderState; m_pfnRestoreRenderState = &CGrannyMaterial::__RestoreSpecularRenderState; } else { m_pfnApplyRenderState = &CGrannyMaterial::__ApplyDiffuseRenderState; m_pfnRestoreRenderState = &CGrannyMaterial::__RestoreDiffuseRenderState; } } bool CGrannyMaterial::IsEqual(granny_material* pgrnMaterial) const { if (m_pgrnMaterial==pgrnMaterial) return true; return false; } LPDIRECT3DTEXTURE8 CGrannyMaterial::GetD3DTexture(int iStage) const { const CGraphicImage::TRef & ratImage = m_roImage[iStage]; if (ratImage.IsNull()) return NULL; CGraphicImage * pImage = ratImage.GetPointer(); const CGraphicTexture * pTexture = pImage->GetTexturePointer(); return pTexture->GetD3DTexture(); } CGraphicImage * CGrannyMaterial::GetImagePointer(int iStage) const { const CGraphicImage::TRef & ratImage = m_roImage[iStage]; if (ratImage.IsNull()) return NULL; CGraphicImage * pImage = ratImage.GetPointer(); return pImage; } const CGraphicTexture* CGrannyMaterial::GetDiffuseTexture() const { if (m_roImage[0].IsNull()) return NULL; return m_roImage[0].GetPointer()->GetTexturePointer(); } const CGraphicTexture* CGrannyMaterial::GetOpacityTexture() const { if (m_roImage[1].IsNull()) return NULL; return m_roImage[1].GetPointer()->GetTexturePointer(); } BOOL CGrannyMaterial::__IsSpecularEnable() const { return m_bSpecularEnable; } float CGrannyMaterial::__GetSpecularPower() const { return m_fSpecularPower; } extern const std::string& GetModelLocalPath(); CGraphicImage* CGrannyMaterial::__GetImagePointer(const char* fileName) { assert(*fileName != '\0'); CResourceManager& rkResMgr = CResourceManager::Instance(); // SUPPORT_LOCAL_TEXTURE int fileName_len = strlen(fileName); if (fileName_len > 2 && fileName[1] != ':') { char localFileName[256]; const std::string& modelLocalPath = GetModelLocalPath(); int localFileName_len = modelLocalPath.length() + 1 + fileName_len; if (localFileName_len < sizeof(localFileName) - 1) { _snprintf(localFileName, sizeof(localFileName), "%s%s", GetModelLocalPath().c_str(), fileName); CResource* pResource = rkResMgr.GetResourcePointer(localFileName); return static_cast(pResource); } } // END_OF_SUPPORT_LOCAL_TEXTURE CResource* pResource = rkResMgr.GetResourcePointer(fileName); return static_cast(pResource); } bool CGrannyMaterial::CreateFromGrannyMaterialPointer(granny_material * pgrnMaterial) { m_pgrnMaterial = pgrnMaterial; granny_texture * pgrnDiffuseTexture = NULL; granny_texture * pgrnOpacityTexture = NULL; if (pgrnMaterial) { if (pgrnMaterial->MapCount > 1 && !strnicmp(pgrnMaterial->Name, "Blend", 5)) { pgrnDiffuseTexture = GrannyGetMaterialTextureByType(pgrnMaterial->Maps[0].Material, GrannyDiffuseColorTexture); pgrnOpacityTexture = GrannyGetMaterialTextureByType(pgrnMaterial->Maps[1].Material, GrannyDiffuseColorTexture); } else { pgrnDiffuseTexture = GrannyGetMaterialTextureByType(m_pgrnMaterial, GrannyDiffuseColorTexture); pgrnOpacityTexture = GrannyGetMaterialTextureByType(m_pgrnMaterial, GrannyOpacityTexture); } // Two-Side ·»´õ¸µÀÌ ÇÊ¿äÇÑ Áö °Ë»ç { granny_int32 twoSided = 0; granny_data_type_definition TwoSidedFieldType[] = { {GrannyInt32Member, "Two-sided"}, {GrannyEndMember}, }; granny_variant twoSideResult = GrannyFindMatchingMember(pgrnMaterial->ExtendedData.Type, pgrnMaterial->ExtendedData.Object, "Two-sided"); if (NULL != twoSideResult.Type) GrannyConvertSingleObject(twoSideResult.Type, twoSideResult.Object, TwoSidedFieldType, &twoSided); m_bTwoSideRender = 1 == twoSided; } } if (pgrnDiffuseTexture) m_roImage[0].SetPointer(__GetImagePointer(pgrnDiffuseTexture->FromFileName)); if (pgrnOpacityTexture) m_roImage[1].SetPointer(__GetImagePointer(pgrnOpacityTexture->FromFileName)); // ¿ÀÆÛ½ÃƼ°¡ ÀÖÀ¸¸é ºí·»µù ¸Þ½¬ if (!m_roImage[1].IsNull()) m_eType = TYPE_BLEND_PNT; else m_eType = TYPE_DIFFUSE_PNT; return true; } void CGrannyMaterial::Initialize() { m_roImage[0] = NULL; m_roImage[1] = NULL; SetSpecularInfo(FALSE, 0.0f, 0); } void CGrannyMaterial::__ApplyDiffuseRenderState() { STATEMANAGER.SetTexture(0, GetD3DTexture(0)); if (m_bTwoSideRender) { // -_-·»´õ¸µ ÇÁ·Î¼¼½º°¡ Á» ±¸·Á¼­... Save & Restore ÇÏ¸é ¼ø¼­¶§¹®¿¡ Á» ²¿ÀδÙ. ±ÍÂúÀ¸´Ï Save & Restore ´ë½Å µû·Î ÀúÀåÇØ µÒ. m_dwLastCullRenderStateForTwoSideRendering = STATEMANAGER.GetRenderState(D3DRS_CULLMODE); STATEMANAGER.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); } } void CGrannyMaterial::__RestoreDiffuseRenderState() { if (m_bTwoSideRender) { STATEMANAGER.SetRenderState(D3DRS_CULLMODE, m_dwLastCullRenderStateForTwoSideRendering); } } void CGrannyMaterial::__ApplySpecularRenderState() { if (TRUE == STATEMANAGER.GetRenderState(D3DRS_ALPHABLENDENABLE)) { __ApplyDiffuseRenderState(); return; } CGraphicTexture* pkTexture=ms_akSphereMapInstance[m_bSphereMapIndex].GetTexturePointer(); STATEMANAGER.SetTexture(0, GetD3DTexture(0)); if (pkTexture) STATEMANAGER.SetTexture(1, pkTexture->GetD3DTexture()); else STATEMANAGER.SetTexture(1, NULL); STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(g_fSpecularColor.r, g_fSpecularColor.g, g_fSpecularColor.b, __GetSpecularPower())); STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATEALPHA_ADDCOLOR); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &ms_matSpecular); STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); } void CGrannyMaterial::__RestoreSpecularRenderState() { if (TRUE == STATEMANAGER.GetRenderState(D3DRS_ALPHABLENDENABLE)) { __RestoreDiffuseRenderState(); return; } STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS); STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU); STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV); STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); } void CGrannyMaterial::CreateSphereMap(UINT uMapIndex, const char* c_szSphereMapImageFileName) { CResourceManager& rkResMgr = CResourceManager::Instance(); CGraphicImage * pImage = (CGraphicImage *)rkResMgr.GetResourcePointer(c_szSphereMapImageFileName); ms_akSphereMapInstance[uMapIndex].SetImagePointer(pImage); } void CGrannyMaterial::DestroySphereMap() { for (UINT uMapIndex=0; uMapIndexIsIn(c_szImageName, &iStage)) { CGrannyMaterial* pkNewMtrl=new CGrannyMaterial; pkNewMtrl->Copy(*roMtrl.GetPointer()); pkNewMtrl->SetImagePointer(iStage, pImage); roMtrl=pkNewMtrl; return; } } } void CGrannyMaterialPalette::SetMaterialData(const char* c_szMtrlName, const SMaterialData& c_rkMaterialData) { if (c_szMtrlName) { std::vector::iterator i; for (i=m_mtrlVector.begin(); i!=m_mtrlVector.end(); ++i) { CGrannyMaterial::TRef& roMtrl=*i; int iStage; if (roMtrl->IsIn(c_szMtrlName, &iStage)) { CGrannyMaterial* pkNewMtrl=new CGrannyMaterial; pkNewMtrl->Copy(*roMtrl.GetPointer()); pkNewMtrl->SetImagePointer(iStage, c_rkMaterialData.pImage); pkNewMtrl->SetSpecularInfo(c_rkMaterialData.isSpecularEnable, c_rkMaterialData.fSpecularPower, c_rkMaterialData.bSphereMapIndex); roMtrl=pkNewMtrl; return; } } } else { std::vector::iterator i; for (i=m_mtrlVector.begin(); i!=m_mtrlVector.end(); ++i) { CGrannyMaterial::TRef& roMtrl=*i; roMtrl->SetSpecularInfo(c_rkMaterialData.isSpecularEnable, c_rkMaterialData.fSpecularPower, c_rkMaterialData.bSphereMapIndex); } } } void CGrannyMaterialPalette::SetSpecularInfo(const char* c_szMtrlName, BOOL bEnable, float fPower) { DWORD size=m_mtrlVector.size(); DWORD i; if (c_szMtrlName) { for (i=0; iIsIn(c_szMtrlName, &iStage)) { roMtrl->SetSpecularInfo(bEnable, fPower, 0); return; } } } else { for (i=0; iSetSpecularInfo(bEnable, fPower, 0); } } } DWORD CGrannyMaterialPalette::RegisterMaterial(granny_material* pgrnMaterial) { DWORD size=m_mtrlVector.size(); DWORD i; for (i=0; iIsEqual(pgrnMaterial)) return i; } CGrannyMaterial* pkNewMtrl=new CGrannyMaterial; pkNewMtrl->CreateFromGrannyMaterialPointer(pgrnMaterial); m_mtrlVector.push_back(pkNewMtrl); return size; } DWORD CGrannyMaterialPalette::GetMaterialCount() const { return m_mtrlVector.size(); } /* void CActorInstance::BeginSpecularRender() { // NOTE - BlendingÇؼ­ Âï´Â ºÎºÐÀº Specular¸¦ Àû¿ë½ÃÅ°Áö ¾Ê´Â´Ù - [levites] STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE); STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(1.0f, 1.0f, 1.0f, m_AddColor.r)); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATEALPHA_ADDCOLOR); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); // STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); // STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); // STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); // STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); // // STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); // STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE); // STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATEALPHA_ADDCOLOR); // STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); // STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); // D3DXMATRIX texMatrix; // GetSphereMatrix(&texMatrix); // STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &texMatrix); // STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); // Type 1 // STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); // // Type 2 // STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL); } void CActorInstance::EndSpecularRender() { // STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); // STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); } */