DragonNest/Common/EternityEngine/D3DDevice9/EtMaterial.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

1131 lines
30 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "EtType.h"
#include "EtCallBack.h"
#include "EtMaterial.h"
#include "EtSaveMat.h"
#include "EtResourceMng.h"
#include "EtStateManager.h"
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
LPD3DXEFFECTPOOL CEtMaterial::s_pEffectPool = NULL;
std::vector< SHADER_COMPILE_INFO > CEtMaterial::s_CompiledShaders;
int CEtMaterial::s_nShaderQuality = 0;
SGlobalParam g_GlobalParam[] =
{
{ "g_ProjMat", GetProjectionMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_ViewMat", GetViewMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_ViewRotProjMat", GetViewRotProjMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_PrevViewRotProjMat", GetPrevViewRotProjMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_ViewPosition", GetViewPosition, EPT_VECTOR, VariableCountOne, -1 },
{ "g_FogFactor", GetFogFactor, EPT_VECTOR, VariableCountOne, -1 },
{ "g_FogColor", GetFogColor, EPT_VECTOR, VariableCountOne, -1 },
{ "g_FogSkyBoxTex", GetFogSkyBoxTex, EPT_TEX, VariableCountOne, -1 },
{ "g_LightAmbient", GetLightAmbient, EPT_VECTOR, VariableCountOne, -1 },
{ "g_DirLightCount", GetDirLightCount, EPT_INT, VariableCountOne, -1 },
{ "g_DirLightDirection", GetDirLightDirection, EPT_VECTOR, VariableCountDirLight, -1 },
{ "g_ShadowMapTex", GetShadowMap, EPT_TEX, VariableCountOne, -1 },
{ "g_fShadowDensity", GetShadowDensity, EPT_VECTOR, VariableCountOne, -1 },
{ "g_FetchDist", GetShadowFetchDistance, EPT_FLOAT, VariableCountOne, -1 },
{ "g_fElapsedTime", GetElapsedTime, EPT_FLOAT, VariableCountOne, -1 },
{ "g_EnvTex", GetEnvTexture, EPT_TEX, VariableCountOne, -1 },
{ "g_BackBuffer", GetBackBuffer, EPT_TEX, VariableCountOne, -1 },
{ "g_ScreenSizeScale", GetScreenSizeScale, EPT_VECTOR, VariableCountOne, -1 },
{ "g_AlphaRef", GetDepthAlphaRef, EPT_FLOAT, VariableCountOne, -1 },/*
{ "g_DepthShadowBias", GetDepthShadowBias, EPT_FLOAT, VariableCountOne, -1 },
{ "g_DepthShadowBias2", GetDepthShadowBias2, EPT_FLOAT, VariableCountOne, -1 },*/
};
#define GLOBAL_PARAM_COUNT ( sizeof( g_GlobalParam ) / sizeof( SGlobalParam ) )
SGlobalParam g_WorldMatParam[] =
{
{ "g_WorldMat", GetWorldMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_InvViewMat", GetInvViewMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_WorldViewMat", GetWorldViewMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_ViewProjMat", GetViewProjMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_WorldViewProjMat", GetWorldViewProjMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_PrevWorldViewProjMat", GetPrevWorldViewProjMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_InvWorldViewPrevWVPMat", GetInvWorldViewPrevWorldViewProjMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_ModelViewMat", GetModelViewMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_InvViewModelViewMat", GetInvViewModelViewMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_WorldLightViewProjMat", GetWorldLightViewProjMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_InvViewLightViewProjMat", GetInvViewLightViewProjMat, EPT_MATRIX, VariableCountOne, -1 },
{ "g_WorldLightViewProjDepth", GetWorldLightViewProjDepth, EPT_VECTOR, VariableCountOne, -1 },
{ "g_InvViewLightViewProjDepth", GetInvViewLightViewProjDepth, EPT_VECTOR, VariableCountOne, -1 },
{ "g_DirLightDiffuse", GetDirLightDiffuse, EPT_VECTOR, VariableCountDirLight, -1 }, // Directional Light<68><74> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WorldMat Param<61><6D><EFBFBD><EFBFBD> <20>δ°<CEB4><C2B0><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>߱⶧<DFB1><E2B6A7><EFBFBD><EFBFBD>
{ "g_DirLightSpecular", GetDirLightSpecular, EPT_VECTOR, VariableCountDirLight, -1 }, // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>͸<EFBFBD><CDB8><EFBFBD> <20>̶<EFBFBD><CCB6><EFBFBD> GlobalParam<61><6D><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>dzʶٴ<CAB6><D9B4><EFBFBD><EFBFBD><EFBFBD> <20>̰͸<CCB0><CDB8><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ϱ<CFB1><E2B6A7><EFBFBD><EFBFBD> <20>׷<EFBFBD><D7B7><EFBFBD>
{ "g_PointLightCount", GetPointLightCount, EPT_INT, VariableCountOne, -1 },
{ "g_PointLightPosition", GetPointLightPosition, EPT_VECTOR, VariableCountPointLight, -1 },
{ "g_PointLightDiffuse", GetPointLightDiffuse, EPT_VECTOR, VariableCountPointLight, -1 },
{ "g_PointLightSpecular", GetPointLightSpecular, EPT_VECTOR, VariableCountPointLight, -1 },
{ "g_SpotLightCount", GetSpotLightCount, EPT_INT, VariableCountOne, -1 },
{ "g_SpotLightDirection", GetSpotLightDirection, EPT_VECTOR, VariableCountSpotLight, -1 },
{ "g_SpotLightPosition", GetSpotLightPosition, EPT_VECTOR, VariableCountSpotLight, -1 },
{ "g_SpotLightDiffuse", GetSpotLightDiffuse, EPT_VECTOR, VariableCountSpotLight, -1 },
{ "g_SpotLightSpecular", GetSpotLightSpecular, EPT_VECTOR, VariableCountSpotLight, -1 },
};
#define WORLDMAT_PARAM_COUNT ( sizeof( g_WorldMatParam ) / sizeof( SGlobalParam ) )
SGlobalParam g_PreComputeParam[] =
{
{ "g_EmissiveColor", ComputeEmissive, EPT_VECTOR, VariableCountEmissive, -1 },
{ "g_SkinCoeffA", GetCoefficientA, EPT_VECTOR, VariableCountOne, -1 },
{ "g_SkinCoeffB", GetCoefficientB, EPT_VECTOR, VariableCountOne, -1 },
{ "g_SkinCoeffC", GetCoefficientC, EPT_VECTOR, VariableCountOne, -1 },
{ "g_SkinCoeffD", GetCoefficientD, EPT_VECTOR, VariableCountOne, -1 },
{ "g_ComputeAniTime", GetAniTime, EPT_FLOAT, VariableCountOne, -1 },
};
#define PRECOMPUTE_PARAM_COUNT ( sizeof( g_PreComputeParam ) / sizeof( SGlobalParam ) )
CEtMaterial::CEtMaterial(void)
{
m_pEffect = NULL;
m_hWorldMatArray = NULL;
m_bUseTangentSpace = false;
m_bUseBackBuffer = false;
m_nCurrentTechnique = -1;
}
CEtMaterial::~CEtMaterial(void)
{
Clear();
}
void CEtMaterial::Clear()
{
SAFE_RELEASE( m_pEffect );
SAFE_DELETE_VEC( m_GlobalEffectParam );
SAFE_DELETE_VEC( m_WorldMatEffectParam );
SAFE_DELETE_VEC( m_PreComputeParam );
SAFE_DELETE_VEC( m_CustomEffectParam );
for( std::vector< void* >::iterator it = m_vecUserAllocMemList.begin(); it != m_vecUserAllocMemList.end(); ++it ) {
::free( *it );
}
m_vecUserAllocMemList.clear();
m_nCurrentTechnique = -1;
m_hWorldMatArray = NULL;
m_bUseTangentSpace = false;
m_bUseBackBuffer = false;
m_vecParamHandle.clear();
m_vecParamName.clear();
m_vecParamUsed.clear();
}
int CEtMaterial::LoadResource( CStream *pStream )
{
ASSERT( pStream && "Invalid Resource Stream( Texture )!!!" );
if( pStream == NULL )
{
return ETERR_INVALIDRESOURCESTREAM;
}
Clear();
CreateEffectPool();
if( !s_CompiledShaders.empty() && pStream->GetName() == NULL ) {
int i, nSize;
nSize = (int)s_CompiledShaders.size();
const char *pFileName = ((CResMngStream*)pStream)->GetFullName();
for( i = 0; i < nSize; i++)
{
if( stricmp(s_CompiledShaders[i].szFileName, pFileName) == 0 && s_CompiledShaders[i].nQualityLevel == s_nShaderQuality ) {
m_pEffect = GetEtDevice()->LoadEffectFromMemory( (char*)s_CompiledShaders[i].pCompiledBuffer, s_CompiledShaders[i].dwBufferSize, s_pEffectPool );
m_szFullName = pFileName;
m_szFileName = FindFileName( pFileName );
break;
}
}
}
else {
char *pBuffer;
int nFileSize;
nFileSize = pStream->Size();
pBuffer = new char[ nFileSize ];
pStream->Read( pBuffer, nFileSize );
CEtShaderInclude Include;
m_pEffect = GetEtDevice()->LoadEffectFromMemory( pBuffer, nFileSize, s_pEffectPool, &Include );
SAFE_DELETEA( pBuffer );
// m_pEffect = GetEtDevice()->LoadEffectFromFile( pStream->GetName(), s_pEffectPool );
}
if( m_pEffect == NULL ) {
ASSERT( 0 && "LoadEffectFromFile Failed" );
return ETERR_LOADEFFECTFAIL;
}
SaveParamHandle();
CreateAllVertexDecl();
CreateGlobalParam();
m_pEffect->SetStateManager( GetEtStateManager() );
return ET_OK;
}
DWORD CEtMaterial::GetParameterUsedFlag( EtHandle hHandle )
{
DWORD dwParamUsedFlag = 0;
for( int j = 0; j < GetTechniqueCount(); j++)
{
if( m_pEffect->IsParameterUsed( hHandle, m_pEffect->GetTechnique( j ) ) )
{
dwParamUsedFlag |= (1<<j);
}
}
return dwParamUsedFlag;
}
void CEtMaterial::SaveParamHandle()
{
if( !m_vecParamHandle.empty() )
{
int i, j, nParamCount;
memset( &m_vecParamHandle[ 0 ], 0, sizeof( EtHandle ) * m_vecParamHandle.size() );
nParamCount = GetParameterCount();
for( i = 0; i < nParamCount; i++ )
{
bool bFind;
EtHandle hHandle;
D3DXPARAMETER_DESC Desc;
bFind = false;
hHandle = m_pEffect->GetParameter( NULL, i );
m_pEffect->GetParameterDesc( hHandle, &Desc );
for( j = 0; j < ( int )m_vecParamName.size(); j++ )
{
if( stricmp( m_vecParamName[ j ].c_str(), Desc.Name ) == 0 )
{
m_vecParamHandle[ j ] = hHandle;
m_vecParamUsed[ j ] = GetParameterUsedFlag( hHandle );
bFind = true;
break;
}
}
if( !bFind )
{
m_vecParamHandle.push_back( hHandle );
m_vecParamName.push_back( Desc.Name );
m_vecParamUsed.push_back( GetParameterUsedFlag(hHandle) );
}
}
}
else
{
int i, nCount;
nCount = GetParameterCount();
m_vecParamHandle.resize( nCount );
for( i = 0; i < nCount; i++ )
{
D3DXPARAMETER_DESC Desc;
m_vecParamHandle[ i ] = m_pEffect->GetParameter( NULL, i );
m_pEffect->GetParameterDesc( m_vecParamHandle[ i ], &Desc );
m_vecParamName.push_back( Desc.Name );
m_vecParamUsed.push_back( GetParameterUsedFlag( m_vecParamHandle[ i ] ) );
}
}
}
void CEtMaterial::Reload()
{
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
Clear();
Load( GetFullName() );
Release();
}
void CEtMaterial::OnLostDevice()
{
if( m_pEffect )
{
m_pEffect->OnLostDevice();
}
}
void CEtMaterial::OnResetDevice()
{
if( m_pEffect )
{
m_pEffect->OnResetDevice();
}
}
int CEtMaterial::GetTechniqueCount()
{
D3DXEFFECT_DESC EffectDesc;
m_pEffect->GetDesc( &EffectDesc );
return EffectDesc.Techniques;
}
int CEtMaterial::GetPassCount( EtHandle hTechnique )
{
D3DXTECHNIQUE_DESC TechniqueDesc;
m_pEffect->GetTechniqueDesc( hTechnique, &TechniqueDesc );
return TechniqueDesc.Passes;
}
int CEtMaterial::GetParameterCount()
{
D3DXEFFECT_DESC EffectDesc;
m_pEffect->GetDesc( &EffectDesc );
return EffectDesc.Parameters;
}
EtParameterHandle CEtMaterial::GetParameterByName( const char *pName )
{
EtHandle hFindHandle;
int i;
if( !m_pEffect ) {
return -1;
}
hFindHandle = m_pEffect->GetParameterByName( NULL, pName );
for( i = 0; i < ( int )m_vecParamHandle.size(); i++ )
{
if( m_vecParamHandle[ i ] == hFindHandle )
{
return i;
}
}
return -1;
}
const char *CEtMaterial::GetParameterName( EtParameterHandle hParam )
{
D3DXPARAMETER_DESC ParamDesc;
m_pEffect->GetParameterDesc( m_vecParamHandle[ hParam ], &ParamDesc );
return ParamDesc.Name;
}
D3DXPARAMETER_TYPE CEtMaterial::GetParameterType( EtParameterHandle hParam )
{
D3DXPARAMETER_DESC ParamDesc;
m_pEffect->GetParameterDesc( m_vecParamHandle[ hParam ], &ParamDesc );
return ParamDesc.Type;
}
EtTextureType CEtMaterial::GetTextureType( EtParameterHandle hHandle )
{
if( hHandle < 0 || hHandle >= (int) m_vecParamHandle.size() ) {
return ETTEXTURE_NORMAL;
}
D3DXPARAMETER_DESC Desc;
EtTextureType TextureType;
m_pEffect->GetParameterDesc( m_vecParamHandle[ hHandle ], &Desc );
switch( Desc.Type )
{
case D3DXPT_TEXTURE3D:
TextureType = ETTEXTURE_VOLUME;
break;
case D3DXPT_TEXTURECUBE:
TextureType = ETTEXTURE_CUBE;
break;
default:
TextureType = ETTEXTURE_NORMAL;
break;
}
return TextureType;
}
const char *CEtMaterial::GetSemantic( EtParameterHandle hHandle )
{
D3DXPARAMETER_DESC Desc;
m_pEffect->GetParameterDesc( m_vecParamHandle[ hHandle ], &Desc );
return Desc.Semantic;
}
int CEtMaterial::SetTechnique( int nIndex )
{
EtHandle hTechnique;
hTechnique = m_pEffect->GetTechnique( nIndex );
if( hTechnique == NULL )
{
ASSERT( 0 && "Invalid Technique Handle" );
return ETERR_INVALIDTECHNIQUEHANDLE;
}
m_pEffect->SetTechnique( hTechnique );
m_nCurrentTechnique = nIndex;
return ET_OK;
}
int CEtMaterial::CreateVertexDecl( EtHandle hTechnique, EtHandle hPass, bool bMergeType )
{
int i, nOffset;
UINT nSemanticCount;
D3DXPASS_DESC PassDesc;
D3DXSEMANTIC Semantic[ 20 ]; // 20<32><30> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
D3DVERTEXELEMENT9 VertexElement[ 20 ];
m_pEffect->GetPassDesc( hPass, &PassDesc );
D3DXGetShaderInputSemantics( PassDesc.pVertexShaderFunction, Semantic, &nSemanticCount );
nOffset = 0;
for( i = 0; i < ( int )nSemanticCount; i++ )
{
if( bMergeType )
{
VertexElement[ i ].Stream = 0;
}
else
{
VertexElement[ i ].Stream = i;
}
if( bMergeType )
{
VertexElement[ i ].Offset = nOffset;
}
else
{
VertexElement[ i ].Offset = 0;
}
VertexElement[ i ].Method = D3DDECLMETHOD_DEFAULT;
VertexElement[ i ].Usage = Semantic[ i ].Usage;
VertexElement[ i ].UsageIndex = Semantic[ i ].UsageIndex;
switch( Semantic[ i ].Usage ) // <20><><EFBFBD>ؽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>°<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ȵ<EFBFBD> <20>ִ<EFBFBD>. by mapping
{
case D3DDECLUSAGE_POSITION:
case D3DDECLUSAGE_NORMAL:
VertexElement[ i ].Type = D3DDECLTYPE_FLOAT3;
nOffset += sizeof( float ) * 3;
break;
case D3DDECLUSAGE_TANGENT:
case D3DDECLUSAGE_BINORMAL:
m_bUseTangentSpace = true;
VertexElement[ i ].Type = D3DDECLTYPE_FLOAT3;
nOffset += sizeof( float ) * 3;
break;
case D3DDECLUSAGE_BLENDWEIGHT:
VertexElement[ i ].Type = D3DDECLTYPE_FLOAT4;
nOffset += sizeof( float ) * 4;
break;
case D3DDECLUSAGE_BLENDINDICES:
VertexElement[ i ].Type = D3DDECLTYPE_SHORT4;
nOffset += sizeof( short ) * 4;
break;
case D3DDECLUSAGE_TEXCOORD:
VertexElement[ i ].Type = D3DDECLTYPE_FLOAT2;
nOffset += sizeof( float ) * 2;
break;
case D3DDECLUSAGE_COLOR:
VertexElement[ i ].Type = D3DDECLTYPE_D3DCOLOR;
nOffset += sizeof( DWORD );
break;
case D3DDECLUSAGE_DEPTH:
VertexElement[ i ].Type = D3DDECLTYPE_FLOAT1;
nOffset += sizeof( float );
break;
case D3DDECLUSAGE_PSIZE:
VertexElement[ i ].Type = D3DDECLTYPE_FLOAT1;
nOffset += sizeof( float );
break;
default:
ASSERT( 0 && "Invalid Semantic!!!" );
VertexElement[ i ].Type = D3DDECLTYPE_UNUSED;
break;
}
}
VertexElement[ nSemanticCount ].Stream = 0xff;
VertexElement[ nSemanticCount ].Offset = 0;
VertexElement[ nSemanticCount ].Type = D3DDECLTYPE_UNUSED;
VertexElement[ nSemanticCount ].Method = 0;
VertexElement[ nSemanticCount ].Usage = 0;
VertexElement[ nSemanticCount ].UsageIndex = 0;
return GetEtDevice()->CreateVertexDeclaration( VertexElement );
}
void CEtMaterial::CreateAllVertexDecl()
{
UINT i, j, nTechniqueCount, nPassCount;
D3DXHANDLE hTechnique, hPass;
nTechniqueCount = GetTechniqueCount();
m_vecVertexDecl.resize( nTechniqueCount );
m_vecMergedVertexDecl.resize( nTechniqueCount );
for( i = 0; i < nTechniqueCount; i++ )
{
hTechnique = m_pEffect->GetTechnique( i );
nPassCount = GetPassCount( hTechnique );
m_vecVertexDecl[ i ].resize( nPassCount );
m_vecMergedVertexDecl[ i ].resize( nPassCount );
for( j = 0; j < nPassCount; j++ )
{
hPass = m_pEffect->GetPass( hTechnique, j );
m_vecVertexDecl[ i ][ j ] = CreateVertexDecl( hTechnique, hPass );
m_vecMergedVertexDecl[ i ][ j ] = -1;
}
}
}
int CEtMaterial::GetVertexDeclIndex( int nTechniqueIndex, int nPassIndex, bool bMergeType )
{
if( bMergeType )
{
if( nTechniqueIndex >= ( int )m_vecMergedVertexDecl.size() ) {
return -1;
}
if( nPassIndex >= ( int )m_vecMergedVertexDecl[ nTechniqueIndex ].size() ) {
return -1;
}
if( m_vecMergedVertexDecl[ nTechniqueIndex ][ nPassIndex ] == -1 )
{
D3DXHANDLE hTechnique, hPass;
hTechnique = m_pEffect->GetTechnique( nTechniqueIndex );
hPass = m_pEffect->GetPass( hTechnique, nPassIndex );
m_vecMergedVertexDecl[ nTechniqueIndex ][ nPassIndex ] = CreateVertexDecl( hTechnique, hPass, true );
}
return m_vecMergedVertexDecl[ nTechniqueIndex ][ nPassIndex ];
}
else
{
if( nTechniqueIndex >= ( int )m_vecVertexDecl.size() ) {
return -1;
}
if( nPassIndex >= ( int )m_vecVertexDecl[ nTechniqueIndex ].size() ) {
return -1;
}
return m_vecVertexDecl[ nTechniqueIndex ][ nPassIndex ];
}
}
void CEtMaterial::CreateEffectPool()
{
if( !s_pEffectPool )
{
D3DXCreateEffectPool( &s_pEffectPool );
ADD_D3D_RES( s_pEffectPool );
}
}
void CEtMaterial::LoadCompiledShaders()
{
if( s_CompiledShaders.empty() )
{
CResMngStream Stream("DnShaders.dat");
if( !Stream.IsValid() ) return;
int nCount;
DWORD dwHeader;
Stream.Read(&dwHeader, sizeof(DWORD));
Stream.Read(&nCount, sizeof(DWORD));
for( int i = 0; i < nCount; i++)
{
SHADER_COMPILE_INFO scInfo;
Stream.Read(scInfo.szFileName, 64);
Stream.Read(&scInfo.nQualityLevel, 4);
Stream.Read(&scInfo.dwBufferSize, 4);
scInfo.pCompiledBuffer = new BYTE[ scInfo.dwBufferSize ];
Stream.Read(scInfo.pCompiledBuffer, scInfo.dwBufferSize);
s_CompiledShaders.push_back( scInfo );
}
}
}
void CEtMaterial::DeleteCompiledShaders()
{
int i, nSize;
nSize = (int)s_CompiledShaders.size();
for( i = 0; i < nSize; i++) {
delete [] s_CompiledShaders[i].pCompiledBuffer;
}
s_CompiledShaders.clear();
}
void CEtMaterial::CreateGlobalParam()
{
int i, nParamCount;
nParamCount = ( int )m_vecParamHandle.size();
for( i = 0; i < nParamCount; i++ )
{
D3DXPARAMETER_DESC ParamDesc;
if( m_vecParamHandle[ i ] == NULL )
{
continue;
}
m_pEffect->GetParameterDesc( m_vecParamHandle[ i ], &ParamDesc );
if( stricmp( ParamDesc.Name, "g_BackBuffer") == 0 )
{
m_bUseBackBuffer = true;
}
if( stricmp( ParamDesc.Name, "g_WorldViewMatArray" ) == 0 )
{
m_hWorldMatArray = m_vecParamHandle[ i ];
}
else
{
if( !AddGlobalParam( i, ParamDesc.Name ) )
{
if( !AddWorldMatParam( i, ParamDesc.Name ) )
{
if( !AddPreComputeParam( i, ParamDesc.Name ) )
{
AddCustomParam( i, ParamDesc );
}
}
}
}
}
}
bool CEtMaterial::AddGlobalParam( EtParameterHandle hParam, const char *pParamName )
{
int i;
SCustomParam GlobalParam;
for( i = 0; i < GLOBAL_PARAM_COUNT; i++ )
{
if( stricmp( pParamName, g_GlobalParam[ i ].szParamName ) == 0 )
{
GlobalParam.hParamHandle = hParam;
GlobalParam.pCallBack = g_GlobalParam[ i ].pCallBack;
GlobalParam.Type = EPT_VARIABLE;
GlobalParam.VariableType = g_GlobalParam[ i ].VariableType;
GlobalParam.pCountCallBack = g_GlobalParam[ i ].pCountCallBack;
m_GlobalEffectParam.push_back( GlobalParam );
return true;
}
}
return false;
}
bool CEtMaterial::AddWorldMatParam( EtParameterHandle hParam, const char *pParamName )
{
int i;
SCustomParam WorldMatParam;
for( i = 0; i < WORLDMAT_PARAM_COUNT; i++ )
{
if( stricmp( pParamName, g_WorldMatParam[ i ].szParamName ) == 0 )
{
WorldMatParam.hParamHandle = hParam;
WorldMatParam.pCallBack = g_WorldMatParam[ i ].pCallBack;
WorldMatParam.Type = EPT_VARIABLE;
WorldMatParam.VariableType = g_WorldMatParam[ i ].VariableType;
WorldMatParam.pCountCallBack = g_WorldMatParam[ i ].pCountCallBack;
m_WorldMatEffectParam.push_back( WorldMatParam );
return true;
}
}
return false;
}
bool CEtMaterial::AddPreComputeParam( EtParameterHandle hParam, const char *pParamName )
{
int i;
SCustomParam PreComputeParam;
for( i = 0; i < PRECOMPUTE_PARAM_COUNT; i++ )
{
if( stricmp( pParamName, g_PreComputeParam[ i ].szParamName ) == 0 )
{
PreComputeParam.hParamHandle = hParam;
PreComputeParam.pCallBack = g_PreComputeParam[ i ].pCallBack;
PreComputeParam.Type = EPT_VARIABLE;
PreComputeParam.VariableType = g_PreComputeParam[ i ].VariableType;
PreComputeParam.pCountCallBack = g_PreComputeParam[ i ].pCountCallBack;
m_PreComputeParam.push_back( PreComputeParam );
return true;
}
}
return false;
}
void CEtMaterial::AddCustomParam( EtParameterHandle hParam, D3DXPARAMETER_DESC &Desc )
{
SCustomParam CustomParam;
CustomParam.hParamHandle = hParam;
switch( Desc.Type )
{
case D3DXPT_INT:
CustomParam.Type = EPT_INT;
break;
case D3DXPT_FLOAT:
switch( Desc.Bytes ) {
case 4: CustomParam.Type = EPT_FLOAT; break;
case 16: CustomParam.Type = EPT_VECTOR; break;
case 64: CustomParam.Type = EPT_MATRIX; break;
default: return;
}
/*
if( Desc.Rows > 1 )
{
CustomParam.Type = EPT_VECTOR;
}
else if( Desc.Columns > 1 )
{
CustomParam.Type = EPT_MATRIX;
}
else
{
CustomParam.Type = EPT_FLOAT;
}
*/
break;
case D3DXPT_TEXTURE:
case D3DXPT_TEXTURE1D:
case D3DXPT_TEXTURE2D:
case D3DXPT_TEXTURE3D:
case D3DXPT_TEXTURECUBE:
CustomParam.Type = EPT_TEX;
break;
default:
return;
}
m_CustomEffectParam.push_back( CustomParam );
}
void CEtMaterial::SetCustomParamList( std::vector< SCustomParam > &vecCustomParam )
{
SetPreComputeParams( vecCustomParam );
int i, j, nSize, nPreSize;
nSize = ( int )vecCustomParam.size();
nPreSize = ( int )m_PreComputeParam.size();
for( i = 0; i < nSize; i++ )
{
for( j = 0; j < nPreSize; j++) {
if( m_PreComputeParam[j].hParamHandle == vecCustomParam[ i ].hParamHandle ) {
break;
}
}
if( j == nPreSize ) {
SetCustomParam( &vecCustomParam[ i ] );
}
}
}
void CEtMaterial::SetCustomParam( SCustomParam *pParam, void *pAddParam, void *pAddParam2 )
{
if( ( pParam == NULL ) || ( pParam->hParamHandle < 0 ) || ( pParam->hParamHandle >= (int)m_vecParamHandle.size() ) )
{
//ASSERT( 0 && "Invalid Custom Param!!!" );
return;
}
EtHandle hParamHandle;
hParamHandle = m_vecParamHandle[ pParam->hParamHandle ];
if( hParamHandle == NULL )
{
return;
}
// SetTechnique() <20>Լ<EFBFBD><D4BC><EFBFBD> SetCustomParam() <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ҷ<EFBFBD><D2B7><EFBFBD><EFBFBD><EFBFBD> <20>մϴ<D5B4>.
BOOL bUsed = ( m_vecParamUsed[ pParam->hParamHandle ] & (1<<m_nCurrentTechnique) ) != 0 ;
if( !bUsed ) {
return;
}
#if defined(_DEBUG) || defined(_RDEBUG)
const std::string &paramName = m_vecParamName[ pParam->hParamHandle ];
#endif
#if 0
D3DXPARAMETER_DESC Desc;
m_pEffect->GetParameterDesc( hParamHandle, &Desc );
#endif
switch( pParam->Type )
{
case EPT_INT:
if( pParam->nVariableCount == 1 )
{
m_pEffect->SetInt( hParamHandle, pParam->nInt );
}
else
{
if( pParam->nVariableCount > 0 )
m_pEffect->SetIntArray( hParamHandle, ( int * )pParam->pPointer, pParam->nVariableCount );
}
break;
case EPT_FLOAT:
if( pParam->nVariableCount == 1 )
{
m_pEffect->SetFloat( hParamHandle, pParam->fFloat );
}
else
{
if( pParam->nVariableCount ) {
m_pEffect->SetFloatArray( hParamHandle, ( float * )pParam->pPointer, pParam->nVariableCount );
}
}
break;
case EPT_VECTOR:
if( pParam->nVariableCount == 1 )
{
m_pEffect->SetVector( hParamHandle, ( EtVector4 * )pParam->fFloat4 );
}
else
{
if( pParam->nVariableCount > 0 ) {
m_pEffect->SetVectorArray( hParamHandle, ( EtVector4 * )pParam->pPointer, pParam->nVariableCount );
}
}
break;
case EPT_MATRIX:
assert( false && "Use EPT_MATRIX_PTR !!");
break;
case EPT_INT_PTR:
if( pParam->pPointer )
{
m_pEffect->SetInt( hParamHandle, *( int * )pParam->pPointer );
}
break;
case EPT_FLOAT_PTR:
if( pParam->pPointer )
{
m_pEffect->SetFloat( hParamHandle, *( float * )pParam->pPointer );
}
break;
case EPT_VECTOR_PTR:
if( pParam->pPointer )
{
if( pParam->nVariableCount > 1 )
{
m_pEffect->SetVectorArray( hParamHandle, ( EtVector4 * )pParam->pPointer, pParam->nVariableCount );
}
else
{
m_pEffect->SetVector( hParamHandle, ( EtVector4 * )pParam->pPointer );
}
}
break;
case EPT_MATRIX_PTR:
if( pParam->pPointer )
{
if( pParam->nVariableCount > 1 )
{
m_pEffect->SetMatrixArray( hParamHandle, ( EtMatrix * )pParam->pPointer, pParam->nVariableCount );
}
else
{
m_pEffect->SetMatrix( hParamHandle, ( EtMatrix * )pParam->pPointer );
}
}
break;
case EPT_TEX:
{
EtTextureHandle hTexture;
if( pParam->nTextureIndex == -1 )
{
m_pEffect->SetTexture( hParamHandle, NULL );
break;
}
hTexture = CEtResource::GetResource( pParam->nTextureIndex );
if( ( hTexture ) && ( hTexture->GetResourceType() == RT_TEXTURE ) )
{
m_pEffect->SetTexture( hParamHandle, hTexture->GetTexturePtr() );
}
break;
}
case EPT_VARIABLE:
int nVariableCount = pParam->pCountCallBack( pAddParam, pAddParam2 );
switch( pParam->VariableType )
{
case EPT_INT:
if( nVariableCount & 0x80000000 )
{
m_pEffect->SetIntArray( hParamHandle, ( int * )pParam->pCallBack( pAddParam, pAddParam2 ), nVariableCount & 0x7fffffff );
}
else
{
m_pEffect->SetInt( hParamHandle, *( int * )pParam->pCallBack( pAddParam, pAddParam2 ) );
}
break;
case EPT_FLOAT:
if( nVariableCount & 0x80000000 )
{
m_pEffect->SetFloatArray( hParamHandle, ( float * )pParam->pCallBack( pAddParam, pAddParam2 ), nVariableCount & 0x7fffffff );
}
else
{
m_pEffect->SetFloat( hParamHandle, *( float * )pParam->pCallBack( pAddParam, pAddParam2 ) );
}
break;
case EPT_VECTOR:
if( nVariableCount & 0x80000000 )
{
m_pEffect->SetVectorArray( hParamHandle, ( EtVector4 *)pParam->pCallBack( pAddParam, pAddParam2 ), nVariableCount & 0x7fffffff );
}
else
{
m_pEffect->SetVector( hParamHandle, ( EtVector4 *)pParam->pCallBack( pAddParam, pAddParam2 ) );
}
break;
case EPT_MATRIX:
if( nVariableCount & 0x80000000 )
{
m_pEffect->SetMatrixArray( hParamHandle, ( EtMatrix * )pParam->pCallBack( pAddParam, pAddParam2 ), nVariableCount & 0x7fffffff );
}
else
{
m_pEffect->SetMatrix( hParamHandle, ( EtMatrix * )pParam->pCallBack( pAddParam, pAddParam2 ) );
}
break;
case EPT_TEX:
m_pEffect->SetTexture( hParamHandle, ( EtBaseTexture * )pParam->pCallBack( pAddParam, pAddParam2 ) );
break;
}
break;
}
}
void CEtMaterial::SetGlobalParams()
{
int i, nSize;
nSize = ( int )m_GlobalEffectParam.size();
for( i = 0; i < nSize; i++ )
{
SetCustomParam( &m_GlobalEffectParam[ i ] );
}
}
void CEtMaterial::SetWorldMatParams( EtMatrix *pWorldMat, EtMatrix *pPrevWorldMat, int nSaveMatIndex )
{
EtMatrix *pSaveMat, WorldMat, PrevWorldMat;
pSaveMat = GetEtSaveMat()->GetMatrix( nSaveMatIndex );
EtMatrixMultiply( &WorldMat, pSaveMat, pWorldMat );
if( pPrevWorldMat )
{
EtMatrixMultiply( &PrevWorldMat, pSaveMat, pPrevWorldMat );
}
SetWorldMatParams( &WorldMat, &PrevWorldMat );
}
void CEtMaterial::SetWorldMatParams( EtMatrix *pWorldMat, EtMatrix *pPrevWorldMat )
{
int i, nSize;
nSize = ( int )m_WorldMatEffectParam.size();
for( i = 0; i < nSize; i++ )
{
SetCustomParam( &m_WorldMatEffectParam[ i ], pWorldMat, pPrevWorldMat );
}
}
void CEtMaterial::SetPreComputeParams( std::vector< SCustomParam > &vecCustomParam )
{
int i, nSize;
nSize = ( int )m_PreComputeParam.size();
for( i = 0; i < nSize; i++ )
{
SetCustomParam( &m_PreComputeParam[ i ] ,this , &vecCustomParam);
}
}
void CEtMaterial::SetWorldMatArray( EtMatrix *pWorldMat, int nSaveMatIndex, int nBoneCount, const int *pBoneIndex )
{
if( !GetEtSaveMat()->IsValidIndex( nSaveMatIndex ) )
{
return;
}
if( !m_hWorldMatArray )
{
return;
}
EtMatrix WorldViewMat = *(EtMatrix*)GetWorldViewMat( pWorldMat, NULL );
GetEtSaveMat()->Transform( nSaveMatIndex, WorldViewMat );
EtMatrix WorldViewMatArray[ 50 ]; // <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.. <20>ƽ<EFBFBD><C6BD><EFBFBD> 50<35><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>
EtMatrix *pWorldMatArray;
pWorldMatArray = GetEtSaveMat()->GetTransMatrix( nSaveMatIndex );
ASSERT( nBoneCount <= 50);
for( int i = 0; i < nBoneCount; i++ )
{
WorldViewMatArray[ i ] = (pBoneIndex[ i ] == -1) ? WorldViewMat : pWorldMatArray[ pBoneIndex[ i ] ];
}
m_pEffect->SetMatrixArray( m_hWorldMatArray, WorldViewMatArray, nBoneCount );
}
void CEtMaterial::ReloadMaterial()
{
CEtResource::FlushWaitDelete(); // RefCount 0 <20><> Material <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
int i;
int nCount = GetItemCount();
EtMaterialHandle hMaterial;
for( i = 0; i < nCount; i++ )
{
hMaterial = GetItem( i );
if( ( hMaterial ) && ( hMaterial->GetResourceType() == RT_SHADER ) )
{
hMaterial->Reload();
}
}
}
void CEtMaterial::BeginEffect( int &nPasses )
{
if( GetEtStateManager()->IsEnable() ) {
GetEtStateManager()->FlushDeferedStates();
m_pEffect->Begin( ( UINT * )&nPasses, D3DXFX_DONOTSAVESTATE | D3DXFX_DONOTSAVESAMPLERSTATE);
}
else {
m_pEffect->Begin( ( UINT * )&nPasses, 0 );
}
}
void CEtMaterial::BeginEffect()
{
if( GetEtStateManager()->IsEnable() ) {
GetEtStateManager()->FlushDeferedStates();
m_pEffect->Begin( NULL, D3DXFX_DONOTSAVESTATE | D3DXFX_DONOTSAVESAMPLERSTATE );
}
else {
m_pEffect->Begin( NULL, 0 );
}
}
void CEtMaterial::EndEffect()
{
m_pEffect->End();
if( GetEtStateManager()->IsEnable() ) {
for( int i = 0; i < CEtStateBlockManager::STAGE_MAX; i++) {
GetEtStateManager()->SetSamplerStateDefered( i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
GetEtStateManager()->SetSamplerStateDefered( i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
GetEtStateManager()->SetSamplerStateDefered( i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
GetEtStateManager()->SetSamplerStateDefered( i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
GetEtStateManager()->SetSamplerStateDefered( i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
}
}
}
int FindCustomParam( std::vector< SCustomParam > &ParamList, EtParameterHandle hHandle )
{
int i;
for( i = 0; i < ( int )ParamList.size(); i++ )
{
if( ParamList[ i ].hParamHandle == hHandle )
{
return i;
}
}
return -1;
}
int AddCustomParam( std::vector< SCustomParam > &ParamList, EffectParamType Type, EtMaterialHandle hMaterial,
const char *pParamName, void *pValue, int nParamCount )
{
int nParamIndex;
SCustomParam CustomParam;
CustomParam.Type = Type;
CustomParam.hParamHandle = hMaterial->GetParameterByName( pParamName );
ASSERT( CustomParam.hParamHandle != -1 );
CustomParam.nVariableCount = nParamCount;
nParamIndex = FindCustomParam( ParamList, CustomParam.hParamHandle );
if( nParamCount > 1 )
{
CustomParam.pPointer = pValue;
}
else
{
switch( Type )
{
case EPT_INT:
memcpy( &CustomParam.nInt, pValue, sizeof( int ) );
break;
case EPT_FLOAT:
memcpy( &CustomParam.fFloat, pValue, sizeof( float ) );
break;
case EPT_VECTOR:
memcpy( &CustomParam.fFloat4, pValue, sizeof( float ) * 4 );
break;
case EPT_TEX:
memcpy( &CustomParam.nTextureIndex, pValue, sizeof( int ) );
break;
case EPT_INT_PTR:
case EPT_FLOAT_PTR:
case EPT_VECTOR_PTR:
case EPT_MATRIX_PTR:
CustomParam.pPointer = pValue;
break;
}
}
if( nParamIndex == -1 )
{
ParamList.push_back( CustomParam );
nParamIndex = ( int )ParamList.size() - 1;
}
else
{
ParamList[ nParamIndex ] = CustomParam;
}
return nParamIndex;
}
CEtShaderInclude::CEtShaderInclude()
{
}
HRESULT CEtShaderInclude::Open( D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes )
{
CResMngStream Stream( pFileName );
if( !Stream.IsValid() ) return E_FAIL;
char *pBuffer = new char[Stream.Size()];
Stream.Read( pBuffer, Stream.Size() );
*ppData = pBuffer;
*pBytes = Stream.Size();
return S_OK;
}
HRESULT CEtShaderInclude::Close( LPCVOID pData )
{
char *pBuffer = (char*)pData;
SAFE_DELETEA( pBuffer );
return S_OK;
}