Files
Client/GameTools/Zallad3D SceneClass/2방향 - Z3DMultipartSkin.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

2250 lines
65 KiB
C++

// Z3DMultipartSkin.cpp: implementation of the CZ3DMultipartSkin class.
//
//////////////////////////////////////////////////////////////////////
//#include "FunctionPerformanceCheck.h"
#include "Z3DMultipartSkin.h"
#include "Vertex.h"
//#include "BaseDataDefine.h"
#include "RenderOption.h"
#include "ShaderConstants.h"
#include "SceneManager.h"
#include "Texture.h"
#include "Shader_IndexHeader.h"
#include "ShaderScene.h"
// Rain 관련 VertexBuffer Setting
#include "Shader_Rain.h"
#include <sys/types.h>
#include <sys/timeb.h>
#include "SceneStateMgr.h"
#include "Shader_ClassicBumpSpec.h"
#include "Shader_ClassicBumpSpecV.h"
#include "Shader_ClassicBumpSpecP.h"
#include "TextureUtils.h"
//////////////////////////////////////////////////////////////////////
// LOD 레벨당 몇 프레임에 한번씩 blending 계산을 할 것인지 결정할때 쓰이는 테이블
long CZ3DMultipartSkin::ms_alAniLODFrameTable[Z3D_LOD_LEVEL] = { 1, 3, 5, 10 };
bool CZ3DMultipartSkin::SetMesh( const char* szMeshName )
{
int id;
int nPartId;
H3DMeshTag tagMesh;
g_ContLODMesh.GetObject( tagMesh, szMeshName );
nPartId = tagMesh.GetObject()->GetId();
id = GetPortionIndex( nPartId );
if( -1 == id ) // 잘못된 id
{
tagMesh.Release();
return false;
}
if( m_apPortion[id]->SetMesh( nPartId, tagMesh ) )
{
if( !m_bIsBatchMode )
{
m_lAniLODCounter = 0; // 메쉬가 바뀌었을 경우 blending 재계산이 필요하므로
m_apPortion[id]->BuildMesh( GetDevice() );
}
return true;
}
return false;
}
bool CZ3DMultipartSkin::SetTex( const char* szTexName, const char* szTex2Name )
{
int id;
int nPartId;
H3DTexPieceTag tagTexPiece;
g_ContTexture.SetFilePath( WORLDCHRDIFF);
g_ContTexturePiece.GetObject( tagTexPiece, szTexName );
nPartId = tagTexPiece.GetObject()->GetId();
id = GetPortionIndex( nPartId );
if( -1 == id ) // 잘못된 id
{
tagTexPiece.Release();
return false;
}
if( !m_bIsBatchMode )
{
// 텍스처가 비어 있을때 null 텍스처 생성
if( true == m_apPortion[id]->m_pTexture->IsEmpty() )
{
if( 0 == id )
{
if( false == m_apPortion[id]->m_pTexture->Load( "NULL_512x512.dds" ) )
{
_ASSERT(false); // error reading default texture!
return false;
}
}
else
{
if( false == m_apPortion[id]->m_pTexture->Load( "NULL_256x512.dds" ) )
{
_ASSERT(false); // error reading default texture!
return false;
}
}
}
}
if( m_apPortion[id]->SetTexPiece( nPartId, tagTexPiece ) )
{
if( !m_bIsBatchMode )
{
tagTexPiece.GetObject()->Blt2Texture( *(m_apPortion[id]->m_pTexture) );
}
}
// secondary texture 처리
if( NULL == szTex2Name )
{
return true;
}
g_ContTexture.SetFilePath( WORLDCHRBUM);
g_ContTexturePiece.GetObject( tagTexPiece, szTex2Name );
nPartId = tagTexPiece.GetObject()->GetId();
id = GetPortionIndex( nPartId );
if( -1 == id ) // 잘못된 id
{
tagTexPiece.Release();
return false;
}
if( !m_bIsBatchMode )
{
// 텍스처가 비어 있을때 null 텍스처 생성
if( true == m_apPortion[id]->m_pTexture2->IsEmpty() )
{
if( 0 == id )
{
if( false == m_apPortion[id]->m_pTexture2->Load( "BUMP_512x512.dds" ) )
{
_ASSERT(false); // error reading default texture!
return false;
}
}
else
{
if( false == m_apPortion[id]->m_pTexture2->Load( "BUMP_256x512.dds" ) )
{
_ASSERT(false); // error reading default texture!
return false;
}
}
}
}
if( m_apPortion[id]->SetTexPiece2( nPartId, tagTexPiece ) )
{
if( !m_bIsBatchMode )
{
tagTexPiece.GetObject()->Blt2Texture( *(m_apPortion[id]->m_pTexture2) );
}
return true;
}
return false;
}
bool CZ3DMultipartSkin::SetMeshTexture( const char* szMeshName, const char* szTextureName, const char* szTexture2Name, const char* szSpecTextureName )
{
//DeclareBlockTimingCheck("mesh GetObject", aa);
//DeclareBlockTimingCheck("tex1 GetObject", bb);
//DeclareBlockTimingCheck("tex2 GetObject", cc);
int id;
int nPartId;
H3DMeshTag tagMesh;
//BlockTimingCheckStart(aa);
g_ContLODMesh.GetObject( tagMesh, szMeshName );
//BlockTimingCheckStop(aa);
nPartId = tagMesh.GetObject()->GetId();
id = GetPortionIndex( nPartId );
if( -1 == id ) // 잘못된 id
{
tagMesh.Release();
return false;
}
if( m_apPortion[id]->SetMesh( nPartId, tagMesh ) )
{
if( !m_bIsBatchMode )
{
m_lAniLODCounter = 0; // 메쉬가 바뀌었을 경우 blending 재계산이 필요하므로
m_apPortion[id]->BuildMesh( GetDevice() );
}
}
H3DTextureTag tagTexture;
// texture 1
if( NULL == szTextureName )
{
m_apPortion[id]->DeleteTexture( nPartId );
}
else
{
g_ContTexture.SetFilePath( WORLDCHRDIFF);
g_ContTexture.GetObject( tagTexture, szTextureName );
if( NULL == tagTexture.GetObject() )
{
WRONG_WAY( "Texture file not found!" );
}
m_apPortion[id]->SetTexture( nPartId, tagTexture );
}
// texture 2
if( NULL == szTexture2Name )
{
m_apPortion[id]->DeleteTexture2( nPartId );
return true;
}
g_ContTexture.SetFilePath( WORLDCHRBUM);
g_ContTexture.GetObject( tagTexture, szTexture2Name );
if( NULL == tagTexture.GetObject() )
{
WRONG_WAY( "Texture file not found!" );
}
m_apPortion[id]->SetTexture2( nPartId, tagTexture );
// texture 3
if( NULL == szSpecTextureName )
{
m_apPortion[id]->DeleteSpecTexture( nPartId );
return true;
}
g_ContTexture.SetFilePath( WORLDCHRENV);
g_ContTexture.GetObject( tagTexture, szSpecTextureName );
if( NULL == tagTexture.GetObject() )
{
WRONG_WAY( "Texture file not found!" );
}
m_apPortion[id]->SetSpecTexture( nPartId, tagTexture );
return true;
}
bool CZ3DMultipartSkin::DeleteMesh( int nPartId )
{
int id = GetPortionIndex( nPartId );
if( -1 == id )
{
return false;
}
if( m_apPortion[id]->DeleteMesh( nPartId ) )
{
if( !m_bIsBatchMode )
{
m_apPortion[id]->BuildMesh( GetDevice() );
m_lAniLODCounter = 0; // 메쉬가 바뀌었을 경우 blending 재계산이 필요하므로
}
return true;
}
return false;
}
bool CZ3DMultipartSkin::DeleteTex( int nPartId )
{
int id = GetPortionIndex( nPartId );
if( -1 == id )
{
return false;
}
if( m_apPortion[id]->DeleteTexPiece( nPartId ) )
{
if( !m_bIsBatchMode )
{
if( m_apPortion[id]->m_map_IdTexPieceTag.empty() )
{
m_apPortion[id]->m_pTexture->Flush();
}
}
return true;
}
return false;
}
bool CZ3DMultipartSkin::BatchOpen()
{
//_ASSERTE( !m_bIsBatchMode );
if( m_bIsBatchMode )
{
return false;
}
// batchopen으로 값 리셋하는 부분은 build mesh에 모두 포함되므로, 따로 호출하지 않는다.
/*for( int i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
m_apPortion[i]->BatchOpen();
}*/
m_bIsBatchMode = true;
return true;
}
bool CZ3DMultipartSkin::BatchClose()
{
//_ASSERTE( m_bIsBatchMode );
if( false == m_bIsBatchMode )
{
return false;
}
for( int i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( Z3D_MPT_TEXPIECE == m_MPT )
{
if( m_apPortion[i]->m_map_IdTexPieceTag.empty() )
{
m_apPortion[i]->m_pTexture->Flush();
}
else if( m_apPortion[i]->m_pTexture->IsEmpty() )
{
if( 0 == i )
{
if( false == m_apPortion[i]->m_pTexture->Load( "NULL_512x512.dds" ) )
{
return false;
}
}
else
{
if( false == m_apPortion[i]->m_pTexture->Load( "NULL_256x512.dds" ) )
{
return false;
}
}
}
if( m_apPortion[i]->m_map_IdTexPieceTag2.empty() )
{
m_apPortion[i]->m_pTexture2->Flush();
}
else if( m_apPortion[i]->m_pTexture2->IsEmpty() )
{
if( 0 == i )
{
if( false == m_apPortion[i]->m_pTexture2->Load( "BUMP_512x512.dds" ) )
{
return false;
}
}
else
{
if( false == m_apPortion[i]->m_pTexture2->Load( "BUMP_256x512.dds" ) )
{
return false;
}
}
}
}
m_apPortion[i]->BatchClose( GetDevice() );
}
m_lAniLODCounter = 0; // 메쉬가 바뀌어 blending 재계산이 필요하므로
m_bIsBatchMode = false;
return true;
}
vector3 ComputeTangentVector(BumpVertex pVtxA, BumpVertex pVtxB,BumpVertex pVtxC )
{
vector3 vAB=pVtxB.v-pVtxA.v;
vector3 vAC=pVtxC.v-pVtxA.v;
vector3 n=pVtxA.n;
vector3 vProjAB=vAB-( (n*vAB)*n );
vector3 vProjAC=vAC-( (n*vAC)*n );
float duAB=pVtxB.tu-pVtxA.tu;
float duAC=pVtxC.tu-pVtxA.tu;
float dvAB=pVtxB.tv-pVtxA.tv;
float dvAC=pVtxC.tv-pVtxA.tv;
if( duAC*dvAB > duAB*dvAC )
{
duAC=-duAC;
duAB=-duAB;
}
vector3 vTangent=duAC*vProjAB-duAB*vProjAC;
vTangent.Normalize();
return vTangent;
}
void CalcTagentSpaceVector(BumpVertex *pVertices,WORD *pIndices,int cVertex,int cIndices,vector3 *pU)
{
memset(pU,0,sizeof(vector3)*cVertex);
for(int i=0;i<cIndices*3;i+=3)
{
WORD a=pIndices[i+0];
WORD b=pIndices[i+1];
WORD c=pIndices[i+2];
pU[a]+=ComputeTangentVector(pVertices[a],pVertices[b],pVertices[c]);
pU[b]+=ComputeTangentVector(pVertices[b],pVertices[a],pVertices[c]);
pU[c]+=ComputeTangentVector(pVertices[c],pVertices[a],pVertices[b]);
}
for(i=0;i<cVertex;i++)
{
pU[i].Normalize();
}
}
void CZ3DMultipartSkin::ApplyAnimation()
{
// srand(time(0));
if( m_bIsBatchMode )
{
return;
}
if( CRenderOption::m_CharacterPerPixelLighting )
{
if( m_apPortion[0]->m_bSTVertexMode )
{
// st vector 포함시
BumpVertexST* pVertices; // shortcut to render vertex pool of portion
Z3DBlend2Vertex* pBlVertex;
matrix* pMat1,* pMat2; // fixed as 2 for now
float factor1, factor2;
int i, j, k, l;
Z3DLODMesh* pMesh;
STVectorStorage* pST;
float f1, f2, f3, f4;
int nLODLevel = GetLODLevel();
if( 1 )//CheckRecalcByAniLOD() )
{
// 원TM의 역행렬을 구해진 ani TM에 곱해준다.
for( i = 0; i < m_lSkelCount; i++ )
{
if( m_bTestMode )
{
m_pMatrixPalette[i].MakeIdent();
}
else
{
m_rpSkeleton[i].GetLocalizedTM( m_pMatrixPalette[i], m_rpSkeletonLocalizer[i] );
}
}
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( 0 == m_apPortion[i]->m_vec_pMesh.size() )
{
continue;
}
j = 0;
//pVertices = m_apPortion[i]->m_pVertices;
RainVertex *pRainVertices = NULL;
m_apPortion[i]->m_pSTVertexBuffer->Lock( 0, 0, (BYTE**)(&pVertices), D3DLOCK_DISCARD );
//Rain
m_apPortion[i]->m_lpRainVertexBuffer->Lock(0,0,(BYTE**)(&pRainVertices), NULL );
for( l = 0; l < (int)m_apPortion[i]->m_vec_pMesh.size(); l++ )
{
pMesh = m_apPortion[i]->m_vec_pMesh[l];
for( k = 0; k < pMesh->lVertexCount; k++ )
{
pST = &(m_apPortion[i]->m_vecpSTVectors[l][k]);
if( pMesh->pVertices[k].lodLevel >= nLODLevel )
{
pBlVertex = &(pMesh->pVertices[k]);
pMat1 = &(m_pMatrixPalette[pBlVertex->mtrx_id[0]]);
pMat2 = &(m_pMatrixPalette[pBlVertex->mtrx_id[1]]);
factor1 = pBlVertex->bfactor;
factor2 = 1.0f - factor1;
f1 = (factor1*pMat1->_11) + (factor2*pMat2->_11);
f2 = (factor1*pMat1->_21) + (factor2*pMat2->_21);
f3 = (factor1*pMat1->_31) + (factor2*pMat2->_31);
f4 = (factor1*pMat1->_41) + (factor2*pMat2->_41);
pVertices[j].v.x = (pBlVertex->pos.x*f1 + pBlVertex->pos.y*f2 + pBlVertex->pos.z*f3 + f4) * m_fScaleFactor;
pVertices[j].n.x = pBlVertex->normal.x*f1 + pBlVertex->normal.y*f2 + pBlVertex->normal.z*f3;
pVertices[j].s.x = (pST->s.x*f1 + pST->s.y*f2 + pST->s.z*f3);
pVertices[j].t.x = (pST->t.x*f1 + pST->t.y*f2 + pST->t.z*f3);
f1 = (factor1*pMat1->_12) + (factor2*pMat2->_12);
f2 = (factor1*pMat1->_22) + (factor2*pMat2->_22);
f3 = (factor1*pMat1->_32) + (factor2*pMat2->_32);
f4 = (factor1*pMat1->_42) + (factor2*pMat2->_42);
pVertices[j].v.y = (pBlVertex->pos.x*f1 + pBlVertex->pos.y*f2 + pBlVertex->pos.z*f3 + f4) * m_fScaleFactor;
pVertices[j].n.y = pBlVertex->normal.x*f1 + pBlVertex->normal.y*f2 + pBlVertex->normal.z*f3;
pVertices[j].s.y = (pST->s.x*f1 + pST->s.y*f2 + pST->s.z*f3);
pVertices[j].t.y = (pST->t.x*f1 + pST->t.y*f2 + pST->t.z*f3);
f1 = (factor1*pMat1->_13) + (factor2*pMat2->_13);
f2 = (factor1*pMat1->_23) + (factor2*pMat2->_23);
f3 = (factor1*pMat1->_33) + (factor2*pMat2->_33);
f4 = (factor1*pMat1->_43) + (factor2*pMat2->_43);
pVertices[j].v.z = (pBlVertex->pos.x*f1 + pBlVertex->pos.y*f2 + pBlVertex->pos.z*f3 + f4) * m_fScaleFactor;
pVertices[j].n.z = pBlVertex->normal.x*f1 + pBlVertex->normal.y*f2 + pBlVertex->normal.z*f3;
pVertices[j].s.z = (pST->s.x*f1 + pST->s.y*f2 + pST->s.z*f3);
pVertices[j].t.z = (pST->t.x*f1 + pST->t.y*f2 + pST->t.z*f3);
pVertices[j].tu = pBlVertex->tu;
pVertices[j].tv = pBlVertex->tv;
pRainVertices[j].vecPos = D3DXVECTOR3(pVertices[j].v.x,pVertices[j].v.y,pVertices[j].v.z);
pRainVertices[j].vecNormal = D3DXVECTOR3(pVertices[j].n.x,pVertices[j].n.y,pVertices[j].n.z);
if((m_apPortion[i]->m_bRainBufferSet) == false)
pRainVertices[j].fLoop = (100 + rand()%900) / 100.0f;
}
j++;
}
}
m_apPortion[i]->m_pSTVertexBuffer->Unlock();
// Rain
m_apPortion[i]->m_lpRainVertexBuffer->Unlock();
m_apPortion[i]->m_bRainBufferSet = true;
}
}
}
else
{
BumpVertex* pVertices; // shortcut to render vertex pool of portion
Z3DBlend2Vertex* pBlVertex;
matrix* pMat1,* pMat2; // fixed as 2 for now
float factor1, factor2;
int i, j, k, l;
Z3DLODMesh* pMesh;
float f1, f2, f3, f4;
// LOD level 구함 : 뼈다구의 root위치를 기준으로 - 차후에 다른 방법으로 바꿀지도?
// 외부에서 LOD 레벨 설정해주는것으로 바뀜.
//pMat1 = m_rpSkeleton[0].GetTM();
int nLODLevel = GetLODLevel();
if( 1 )//CheckRecalcByAniLOD() )
{
// 원TM의 역행렬을 구해진 ani TM에 곱해준다.
for( i = 0; i < m_lSkelCount; i++ )
{
if( m_bTestMode )
{
m_pMatrixPalette[i].MakeIdent();
}
else
{
m_rpSkeleton[i].GetLocalizedTM( m_pMatrixPalette[i], m_rpSkeletonLocalizer[i] );
}
}
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( 0 == m_apPortion[i]->m_vec_pMesh.size() )
{
continue;
}
j = 0;
//pVertices = m_apPortion[i]->m_pVertices;
m_apPortion[i]->m_pVertexBuffer->Lock( 0, 0, (BYTE**)(&pVertices), D3DLOCK_DISCARD );
for( l = 0; l < (int)m_apPortion[i]->m_vec_pMesh.size(); l++ )
{
pMesh = m_apPortion[i]->m_vec_pMesh[l];
for( k = 0; k < pMesh->lVertexCount; k++ )
{
if( pMesh->pVertices[k].lodLevel >= nLODLevel )
{
pBlVertex = &(pMesh->pVertices[k]);
pMat1 = &(m_pMatrixPalette[pBlVertex->mtrx_id[0]]);
pMat2 = &(m_pMatrixPalette[pBlVertex->mtrx_id[1]]);
factor1 = pBlVertex->bfactor;
factor2 = 1.0f - factor1;
f1 = (factor1*pMat1->_11) + (factor2*pMat2->_11);
f2 = (factor1*pMat1->_21) + (factor2*pMat2->_21);
f3 = (factor1*pMat1->_31) + (factor2*pMat2->_31);
f4 = (factor1*pMat1->_41) + (factor2*pMat2->_41);
pVertices[j].v.x = (pBlVertex->pos.x*f1 + pBlVertex->pos.y*f2 + pBlVertex->pos.z*f3 + f4) * m_fScaleFactor;
pVertices[j].u.x = (pBlVertex->u.x*f1 + pBlVertex->u.y*f2 + pBlVertex->u.z*f3);
pVertices[j].n.x = pBlVertex->normal.x*f1 + pBlVertex->normal.y*f2 + pBlVertex->normal.z*f3;
f1 = (factor1*pMat1->_12) + (factor2*pMat2->_12);
f2 = (factor1*pMat1->_22) + (factor2*pMat2->_22);
f3 = (factor1*pMat1->_32) + (factor2*pMat2->_32);
f4 = (factor1*pMat1->_42) + (factor2*pMat2->_42);
pVertices[j].v.y = (pBlVertex->pos.x*f1 + pBlVertex->pos.y*f2 + pBlVertex->pos.z*f3 + f4) * m_fScaleFactor;
pVertices[j].u.y = (pBlVertex->u.x*f1 + pBlVertex->u.y*f2 + pBlVertex->u.z*f3);
pVertices[j].n.y = pBlVertex->normal.x*f1 + pBlVertex->normal.y*f2 + pBlVertex->normal.z*f3;
f1 = (factor1*pMat1->_13) + (factor2*pMat2->_13);
f2 = (factor1*pMat1->_23) + (factor2*pMat2->_23);
f3 = (factor1*pMat1->_33) + (factor2*pMat2->_33);
f4 = (factor1*pMat1->_43) + (factor2*pMat2->_43);
pVertices[j].v.z = (pBlVertex->pos.x*f1 + pBlVertex->pos.y*f2 + pBlVertex->pos.z*f3 + f4) * m_fScaleFactor;
pVertices[j].u.z = (pBlVertex->u.x*f1 + pBlVertex->u.y*f2 + pBlVertex->u.z*f3);
pVertices[j].n.z = pBlVertex->normal.x*f1 + pBlVertex->normal.y*f2 + pBlVertex->normal.z*f3;
pVertices[j].tu = pBlVertex->tu;
pVertices[j].tv = pBlVertex->tv;
}
j++;
}
}
m_apPortion[i]->m_pVertexBuffer->Unlock();
}
}
}
}
else
{
// blending 계산 및 텍스처 세팅, 렌더링
D3DVERTEX* pVertices; // shortcut to render vertex pool of portion
Z3DBlend2Vertex* pBlVertex;
matrix* pMat1,* pMat2; // fixed as 2 for now
float factor1, factor2;
int i, j, k, l;
Z3DLODMesh* pMesh;
matrix m;
float f1, f2, f3, f4;
// LOD level 구함 : 뼈다구의 root위치를 기준으로 - 차후에 다른 방법으로 바꿀지도?
// 외부에서 LOD 레벨 설정해주는것으로 바뀜.
//pMat1 = m_rpSkeleton[0].GetTM();
int nLODLevel = GetLODLevel();
if( 1 )//CheckRecalcByAniLOD() )
{
// 원TM의 역행렬을 구해진 ani TM에 곱해준다.
for( i = 0; i < m_lSkelCount; i++ )
{
if( m_bTestMode )
{
m_pMatrixPalette[i].MakeIdent();
}
else
{
m_rpSkeleton[i].GetLocalizedTM( m_pMatrixPalette[i], m_rpSkeletonLocalizer[i] );
}
}
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( 0 == m_apPortion[i]->m_vec_pMesh.size() )
{
continue;
}
j = 0;
m_apPortion[i]->m_pVertexBuffer->Lock( 0, 0, (BYTE**)(&pVertices), D3DLOCK_DISCARD );
for( l = 0; l < (int)m_apPortion[i]->m_vec_pMesh.size(); l++ )
{
pMesh = m_apPortion[i]->m_vec_pMesh[l];
for( k = 0; k < pMesh->lVertexCount; k++ )
{
if( pMesh->pVertices[k].lodLevel >= nLODLevel )
{
pBlVertex = &(pMesh->pVertices[k]);
pMat1 = &(m_pMatrixPalette[pBlVertex->mtrx_id[0]]);
pMat2 = &(m_pMatrixPalette[pBlVertex->mtrx_id[1]]);
factor1 = pBlVertex->bfactor;
factor2 = 1.0f - factor1;
f1 = (factor1*pMat1->_11) + (factor2*pMat2->_11);
f2 = (factor1*pMat1->_21) + (factor2*pMat2->_21);
f3 = (factor1*pMat1->_31) + (factor2*pMat2->_31);
f4 = (factor1*pMat1->_41) + (factor2*pMat2->_41);
pVertices[j].x = (pBlVertex->pos.x*f1 + pBlVertex->pos.y*f2 + pBlVertex->pos.z*f3 + f4) * m_fScaleFactor;
pVertices[j].nx = pBlVertex->normal.x*f1 + pBlVertex->normal.y*f2 + pBlVertex->normal.z*f3;
f1 = (factor1*pMat1->_12) + (factor2*pMat2->_12);
f2 = (factor1*pMat1->_22) + (factor2*pMat2->_22);
f3 = (factor1*pMat1->_32) + (factor2*pMat2->_32);
f4 = (factor1*pMat1->_42) + (factor2*pMat2->_42);
pVertices[j].y = (pBlVertex->pos.x*f1 + pBlVertex->pos.y*f2 + pBlVertex->pos.z*f3 + f4) * m_fScaleFactor;
pVertices[j].ny = pBlVertex->normal.x*f1 + pBlVertex->normal.y*f2 + pBlVertex->normal.z*f3;
f1 = (factor1*pMat1->_13) + (factor2*pMat2->_13);
f2 = (factor1*pMat1->_23) + (factor2*pMat2->_23);
f3 = (factor1*pMat1->_33) + (factor2*pMat2->_33);
f4 = (factor1*pMat1->_43) + (factor2*pMat2->_43);
pVertices[j].z = (pBlVertex->pos.x*f1 + pBlVertex->pos.y*f2 + pBlVertex->pos.z*f3 + f4) * m_fScaleFactor;
pVertices[j].nz = pBlVertex->normal.x*f1 + pBlVertex->normal.y*f2 + pBlVertex->normal.z*f3;
pVertices[j].tu = pBlVertex->tu;
pVertices[j].tv = pBlVertex->tv;
}
j++;
}
}
m_apPortion[i]->m_pVertexBuffer->Unlock();
}
}
}
}
void CZ3DMultipartSkin::Render()
{
if(CRenderOption::m_CharacterPerPixelLighting)
{
if( m_bIsBatchMode )
{
return;
}
if(m_pEnvMap == NULL)
{
m_pEnvMap = new CTexture;
CTexture::SetPath(EFFECTTEXTUREPATH);
m_pEnvMap->Load("cube.dds");
}
int i, j;
int nLODLevel = GetLODLevel();
long lVertexOffset, lIndexOffset;
Z3DLODMesh* pMesh = NULL;
if(CRenderOption::m_CharacterPerPixelLighting)
{
//GetDevice()->SetVertexShader( BUMPVERTEXFVF );
}
else
{
GetDevice()->SetVertexShader( D3DFVF_VERTEX );
}
matrix m;
m.MakeIdent();
m._41 = m_vPivotPos.x;
m._42 = m_vPivotPos.y;
m._43 = m_vPivotPos.z;
GetDevice()->SetTransform( D3DTS_WORLD, m );
////////////// Bump Spec Shader Constant Setting ///////////////
bool bFirstLight = true;
LPDIRECT3DDEVICE8 lpDevice = GetDevice();
if(CRenderOption::m_CharacterPerPixelLighting)
{
for(int iLight = 0; iLight < 2; iLight++ )
{
if(iLight == 1)
bFirstLight = false;
static CShader_ClassicBumpSpec *pTestShader = NULL;
if(!pTestShader)
{
pTestShader = new CShader_ClassicBumpSpec;
}
// Get all the matrices, combine them, and set the vertex shader constant matrix.
D3DXMATRIX matWorld,matView,matProj;
lpDevice->GetTransform(D3DTS_WORLD,&matWorld);
lpDevice->GetTransform(D3DTS_VIEW,&matView);
lpDevice->GetTransform(D3DTS_PROJECTION,&matProj);
D3DXMATRIX matInvView;
D3DXMatrixInverse(&matInvView,NULL,&matView);
D3DXMATRIX matCamera;
D3DXMATRIX mat;
D3DXMATRIX matTranspose;
D3DXMatrixMultiply(&matCamera, &matWorld, &matView);
D3DXMatrixMultiply(&mat, &matCamera, &matProj);
D3DXMatrixTranspose(&matTranspose, &mat);
lpDevice->SetVertexShaderConstant(0, &matTranspose,4);
D3DXVECTOR4 uvScale(1.0f, 1.0f, 1.0f, 1.0f);
lpDevice->SetVertexShaderConstant( 6, &uvScale, 1 );
D3DXMATRIX worldToLocal;
D3DXMatrixInverse(&worldToLocal, NULL, &matWorld);
// object space 에서의 Camera pos
D3DXVECTOR3 cameraLocal(matInvView._41,matInvView._42,matInvView._43);
D3DXVec3TransformCoord(&cameraLocal, &cameraLocal, &worldToLocal);
if(bFirstLight) // 첫번째 라이트
CSceneStateMgr::_SetD3DRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE );
if(bFirstLight)
{
D3DXVECTOR3 vecLight(m_vPivotPos.x + 100.0f,m_vPivotPos.y ,m_vPivotPos.z + 100.0f);
/* D3DXVECTOR3 vecLight;
static bool bLight = true;
static int iUnit = 100;
vecLight = D3DXVECTOR3(m_vPivotPos.x + iUnit,m_vPivotPos.y + iUnit,m_vPivotPos.z + iUnit);
if(bLight)
{
iUnit -= 1;
}
else
{
iUnit += 1;
}
if(iUnit == -100)
bLight = !bLight;
if(iUnit == 100)
bLight = !bLight;
*/
D3DXVECTOR3 localPos;
D3DXVec3TransformCoord(&localPos, &vecLight, &worldToLocal);
lpDevice->SetVertexShaderConstant(4,&cameraLocal,1);
lpDevice->SetVertexShaderConstant(5,&localPos,1);
D3DXVECTOR4 vecAmb(0.2f,0.2f,0.2f,0.2f);
D3DXVECTOR4 vecDiff(0.8f,0.8f,0.8f,0.8f);
D3DXVECTOR4 vecSpec(1.0f,1.0f,1.0f,1.0f);
/*
float fAmbientColor[4]={CSceneManager::m_WeatherManager.m_InterCharacterAmbient.r/255.0f,
CSceneManager::m_WeatherManager.m_InterCharacterAmbient.g/255.0f,
CSceneManager::m_WeatherManager.m_InterCharacterAmbient.b/255.0f,1.0f};
float fLightColor[4]={CSceneManager::m_WeatherManager.m_InterCharacterLight.r/255.0f,
CSceneManager::m_WeatherManager.m_InterCharacterLight.g/255.0f,
CSceneManager::m_WeatherManager.m_InterCharacterLight.b/255.0f,1.0f};
int ic = 0;*/
/* for(ic = 0; ic < 4; ic++)
{
fAmbientColor[ic] *= 2.0f;
fLightColor[ic] *= 2.0f;
if(fLightColor[ic] > 1.0f)
fLightColor[ic] = 1.0f;
if(fAmbientColor[ic] > 1.0f)
fAmbientColor[ic] = 1.0f;
}*/
/*
float fSpecColor[4] = {
fLightColor[0] + 0.3f,
fLightColor[1] + 0.3f,
fLightColor[2] + 0.3f,1.0f };
for(ic = 0; ic < 4; ic++)
{
if(fSpecColor[ic] > 1.0f)
fSpecColor[ic] = 1.0f;
}*/
/*
D3DXVECTOR4 vecDiff(0.6f,0.6f,0.6f,0.6f);
D3DXVECTOR4 vecSpec(0.9f,0.9f,0.9f,0.9f);
*/
lpDevice->SetPixelShaderConstant(0,&vecAmb,1);
lpDevice->SetPixelShaderConstant(1,&vecDiff,1);
lpDevice->SetPixelShaderConstant(2,&vecSpec,1);
}
else if(iLight == 1)
{
D3DXVECTOR3 vecLight(m_vPivotPos.x - 100.0f,m_vPivotPos.y,m_vPivotPos.z - 100.0f);
D3DXVECTOR3 localPos;
D3DXVec3TransformCoord(&localPos, &vecLight, &worldToLocal);
lpDevice->SetVertexShaderConstant(4,&cameraLocal,1);
lpDevice->SetVertexShaderConstant(5,&localPos,1);
/*D3DXVECTOR4 vecAmb(0.2f,0.2f,0.2f,0.2f);
D3DXVECTOR4 vecDiff(0.8f,0.8f,0.8f,0.8f);
D3DXVECTOR4 vecSpec(1.0f,1.0f,1.0f,1.0f);
*/
D3DXVECTOR4 vecAmb(0.2f,0.2f,0.2f,0.2f);
D3DXVECTOR4 vecDiff(0.5f,0.65f,0.8f,0.8f);
D3DXVECTOR4 vecSpec(0.7f,0.91f,1.0f,1.0f);
lpDevice->SetPixelShaderConstant(0,&vecAmb,1);
lpDevice->SetPixelShaderConstant(1,&vecDiff,1);
lpDevice->SetPixelShaderConstant(2,&vecSpec,1);
}
////////////////
////////////////
CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,TRUE );
if(bFirstLight) // 첫번째 라이트
{
CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
}
else
{
CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
}
if(bFirstLight)
CSceneStateMgr::_SetD3DRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE );
pTestShader->m_iCurrentShader = 0;
pTestShader->Apply();
// Load diffuse texture map.
// static LPDIRECT3DTEXTURE8 pDiffuseTexture = NULL;
// static LPDIRECT3DTEXTURE8 pNormalTexture = NULL;
// static LPDIRECT3DTEXTURE8 pBumpTexture = NULL;
// if(!pDiffuseTexture)
// {
// pDiffuseTexture = TextureUtils::CreateTextureAlpha("c:/mp-project/character/data/texture/zsechead2.dds","c:/mp-project/character/data/texture/zsechead2_s.dds",lpDevice);
// pDiffuseTexture = TextureUtils::CreateTextureAlpha("c:/mp-project/character/data/texture/pinky_d.dds","c:/mp-project/character/data/texture/pinky_s.dds",lpDevice);
//pDiffuseTexture = TextureUtils::CreateTextureAlpha("c:/mp-project/character/data/texture/m_Sacred_armor.dds","c:/mp-project/texture/shader/demo-spec.bmp",lpDevice);
//pDiffuseTexture = TextureUtils::CreateTextureAlpha("c:/mp-project/character/data/texture/zsechead.dds","c:/mp-project/character/data/texture/zsechead_s.dds",lpDevice);
//pDiffuseTexture = TextureUtils::CreateTextureAlpha("c:/mp-project/character/data/texture/m_Sacred_armor.dds","c:/mp-project/character/data/texture/m_Sacred_armor_a.dds",lpDevice);
//pDiffuseTexture = TextureUtils::CreateTextureAlpha("c:/mp-project/character/data/texture/mon_ancientguard_warrior.dds","c:/mp-project/character/data/texture/2.bmp",lpDevice);
// }
// if(!pNormalTexture)
// {
/*
D3DXIMAGE_INFO imageinfo;
D3DXIMAGE_INFO imageinfo2;
D3DXGetImageInfoFromFile( "c:/mp-project/character/data/texture/zsechead_local.dds", &imageinfo );
D3DXCreateTextureFromFileEx( lpDevice,"c:/mp-project/character/data/texture/zsechead_local.dds",
imageinfo.Width, imageinfo.Height, imageinfo.MipLevels, 0,
imageinfo.Format, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0,
&imageinfo2, NULL, (LPDIRECT3DTEXTURE8*)&pNormalTexture );
*/
// D3DXIMAGE_INFO imageinfo;
// D3DXIMAGE_INFO imageinfo2;
// D3DXGetImageInfoFromFile( "c:/mp-project/character/data/texture/pinky_local.dds", &imageinfo );
// D3DXCreateTextureFromFileEx( lpDevice,"c:/mp-project/character/data/texture/pinky_local.dds",
// imageinfo.Width, imageinfo.Height, imageinfo.MipLevels, 0,
// imageinfo.Format, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0,
// &imageinfo2, NULL, (LPDIRECT3DTEXTURE8*)&pNormalTexture );
/*
D3DXIMAGE_INFO imageinfo;
D3DXIMAGE_INFO imageinfo2;
D3DXGetImageInfoFromFile( "c:/mp-project/character/data/texture/222.dds", &imageinfo );
D3DXCreateTextureFromFileEx( lpDevice,"c:/mp-project/character/data/texture/222.dds",
imageinfo.Width, imageinfo.Height, imageinfo.MipLevels, 0,
imageinfo.Format, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0,
&imageinfo2, NULL, (LPDIRECT3DTEXTURE8*)&pNormalTexture );
*/
/*
D3DXIMAGE_INFO imageinfo;
D3DXIMAGE_INFO imageinfo2;
D3DXGetImageInfoFromFile( "c:/mp-project/character/data/texture/zsechead2_local.dds", &imageinfo );
D3DXCreateTextureFromFileEx( lpDevice,"c:/mp-project/character/data/texture/zsechead2_local.dds",
imageinfo.Width, imageinfo.Height, imageinfo.MipLevels, 0,
imageinfo.Format, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0,
&imageinfo2, NULL, (LPDIRECT3DTEXTURE8*)&pNormalTexture );*/
//pNormalTexture = TextureUtils::CreateNormalMapAlpha(10.0f,"c:/mp-project/character/data/texture/pinky_b.dds","c:/mp-project/character/data/texture/pinky_lu.dds",lpDevice);
//pNormalTexture = TextureUtils::CreateNormalMapAlpha(10.0f,"c:/mp-project/character/data/texture/zsechead_h.dds","c:/mp-project/character/data/texture/zsechead_lu.dds",lpDevice);
//pNormalTexture = TextureUtils::CreateNormalMapAlpha(10.0f,"c:/mp-project/texture/shader/demo-bump.bmp","c:/mp-project/texture/shader/demo-pow.bmp",lpDevice);
//pNormalTexture = TextureUtils::CreateNormalMapAlpha(10.0f,"c:/mp-project/character/data/texture/m_Sacred_armor_b.dds","c:/mp-project/character/data/texture/m_Sacred_armor_l.dds",lpDevice);
//pNormalTexture = TextureUtils::CreateNormalMapAlpha(10.0f,"c:/mp-project/character/data/texture/1.bmp","c:/mp-project/character/data/texture/m_Sacred_armor_l.dds",lpDevice);
// }
// if(!pBumpTexture)
// {
//pBumpTexture = TextureUtils::CreateNormalMapAlpha(10.0f,"c:/mp-project/character/data/texture/zsechead_h.dds","c:/mp-project/character/data/texture/zsechead_lu.dds",lpDevice);
// pBumpTexture = TextureUtils::CreateNormalMapAlpha(20.0f,"c:/mp-project/character/data/texture/pinky_b.dds","c:/mp-project/character/data/texture/pinky_lu.dds",lpDevice);
// }
// lpDevice->SetTexture( 0, pDiffuseTexture );
// lpDevice->SetTexture( 1, pNormalTexture );
// if(iLight == 1)
// lpDevice->SetTexture( 1, pBumpTexture );
lpDevice->SetTexture( 2, TextureUtils::GetNormalisationCubemap(lpDevice) );
// Diff Render
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( m_apPortion[i]->m_alIndexCount[nLODLevel] )
{
if( Z3D_MPT_TEXPIECE == m_apPortion[i]->m_MPT )
{
GetDevice()->SetTexture( 0, *(m_apPortion[i]->m_pTexture) );
GetDevice()->SetTexture( 1, *(m_apPortion[i]->m_pTexture2) );
}
if(CRenderOption::m_CharacterPerPixelLighting)
{
if( m_apPortion[0]->m_bSTVertexMode )
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pSTVertexBuffer, sizeof(BumpVertexST) );
else
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(BumpVertex) );
}
else
{
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(D3DVERTEX) );
}
GetDevice()->SetIndices( m_apPortion[i]->m_apIndexBuffer[nLODLevel], 0 );
lVertexOffset = 0;
lIndexOffset = 0;
for( j = 0; j < m_apPortion[i]->m_vec_pMesh.size(); ++j )
{
pMesh = m_apPortion[i]->m_vec_pMesh[j];
if( pMesh->aIndex[nLODLevel].lIndexCount )
{
if( Z3D_MPT_TEXTURE == m_apPortion[i]->m_MPT )
{
if( m_apPortion[i]->m_vec_pTexture[j] )
{
GetDevice()->SetTexture( 0, (m_apPortion[i]->m_vecDiffuseTexture[j]) );
}
else
{
GetDevice()->SetTexture( 0, NULL );
}
if( m_apPortion[i]->m_vec_pTexture2[j] )
{
GetDevice()->SetTexture( 1, (m_apPortion[i]->m_vecBumpTexture[j]) );
}
else
{
GetDevice()->SetTexture( 1, NULL );
}
}
HRESULT hr = GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, lVertexOffset,
pMesh->lVertexCount, lIndexOffset,
(pMesh->aIndex[nLODLevel].lIndexCount)/3 );
}
lVertexOffset += pMesh->lVertexCount;
lIndexOffset += pMesh->aIndex[nLODLevel].lIndexCount;
}
}
}
if(bFirstLight)
CSceneStateMgr::_SetD3DRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE );
//lpDevice->SetTexture( 0, pNormalTexture );
//if(iLight == 1)
// lpDevice->SetTexture( 0, pBumpTexture );
lpDevice->SetTexture( 3, TextureUtils::GetSpecularCubemap(lpDevice) );
// Spec Render
CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND, D3DBLEND_DESTALPHA );
CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
pTestShader->m_iCurrentShader = 1;
pTestShader->Apply();
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( m_apPortion[i]->m_alIndexCount[nLODLevel] )
{
if( Z3D_MPT_TEXPIECE == m_apPortion[i]->m_MPT )
{
GetDevice()->SetTexture( 0, *(m_apPortion[i]->m_pTexture) );
GetDevice()->SetTexture( 1, *(m_apPortion[i]->m_pTexture2) );
}
if(CRenderOption::m_CharacterPerPixelLighting)
{
if( m_apPortion[0]->m_bSTVertexMode )
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pSTVertexBuffer, sizeof(BumpVertexST) );
else
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(BumpVertex) );
}
else
{
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(D3DVERTEX) );
}
GetDevice()->SetIndices( m_apPortion[i]->m_apIndexBuffer[nLODLevel], 0 );
lVertexOffset = 0;
lIndexOffset = 0;
for( j = 0; j < m_apPortion[i]->m_vec_pMesh.size(); ++j )
{
pMesh = m_apPortion[i]->m_vec_pMesh[j];
if( pMesh->aIndex[nLODLevel].lIndexCount )
{
if( Z3D_MPT_TEXTURE == m_apPortion[i]->m_MPT )
{
if( m_apPortion[i]->m_vec_pTexture[j] )
{
GetDevice()->SetTexture( 0, (m_apPortion[i]->m_vecBumpTexture[j]) );
}
else
{
GetDevice()->SetTexture( 0, NULL );
}
/*if( m_apPortion[i]->m_vec_pTexture2[j] )
{
GetDevice()->SetTexture( 1, *(m_apPortion[i]->m_vec_pTexture2[j]) );
}
else
{
GetDevice()->SetTexture( 1, NULL );
}*/
}
HRESULT hr = GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, lVertexOffset,
pMesh->lVertexCount, lIndexOffset,
(pMesh->aIndex[nLODLevel].lIndexCount)/3 );
}
lVertexOffset += pMesh->lVertexCount;
lIndexOffset += pMesh->aIndex[nLODLevel].lIndexCount;
}
}
}
}
CSceneStateMgr::_SetD3DRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE );
}
IncreaseAniLODCounter();
}
else
{
if( m_bIsBatchMode )
{
return;
}
int i, j;
int nLODLevel = GetLODLevel();
long lVertexOffset, lIndexOffset;
Z3DLODMesh* pMesh = NULL;
if(CRenderOption::m_CharacterPerPixelLighting)
{
//GetDevice()->SetVertexShader( BUMPVERTEXFVF );
}
else
{
GetDevice()->SetVertexShader( D3DFVF_VERTEX );
}
matrix m;
m.MakeIdent();
m._41 = m_vPivotPos.x;
m._42 = m_vPivotPos.y;
m._43 = m_vPivotPos.z;
GetDevice()->SetTransform( D3DTS_WORLD, m );
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( m_apPortion[i]->m_alIndexCount[nLODLevel] )
{
if( Z3D_MPT_TEXPIECE == m_apPortion[i]->m_MPT )
{
GetDevice()->SetTexture( 0, *(m_apPortion[i]->m_pTexture) );
GetDevice()->SetTexture( 1, *(m_apPortion[i]->m_pTexture2) );
}
if(CRenderOption::m_CharacterPerPixelLighting)
{
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(BumpVertex) );
}
else
{
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(D3DVERTEX) );
}
GetDevice()->SetIndices( m_apPortion[i]->m_apIndexBuffer[nLODLevel], 0 );
lVertexOffset = 0;
lIndexOffset = 0;
for( j = 0; j < (int)(m_apPortion[i]->m_vec_pMesh.size()); ++j )
{
pMesh = m_apPortion[i]->m_vec_pMesh[j];
if( pMesh->aIndex[nLODLevel].lIndexCount )
{
if( Z3D_MPT_TEXTURE == m_apPortion[i]->m_MPT )
{
if( m_apPortion[i]->m_vec_pTexture[j] )
{
GetDevice()->SetTexture( 0, *(m_apPortion[i]->m_vec_pTexture[j]) );
}
else
{
GetDevice()->SetTexture( 0, NULL );
}
if( m_apPortion[i]->m_vec_pTexture2[j] )
{
GetDevice()->SetTexture( 1, *(m_apPortion[i]->m_vec_pTexture2[j]) );
}
else
{
GetDevice()->SetTexture( 1, NULL );
}
}
HRESULT hr = GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, lVertexOffset,
pMesh->lVertexCount, lIndexOffset,
(pMesh->aIndex[nLODLevel].lIndexCount)/3 );
}
lVertexOffset += pMesh->lVertexCount;
lIndexOffset += pMesh->aIndex[nLODLevel].lIndexCount;
}
}
}
IncreaseAniLODCounter();
}
}
void CZ3DMultipartSkin::RenderShadow( DWORD vertexShader )
{
_ASSERTE( !m_bIsBatchMode );
if( NULL != vertexShader )
{
if( 0xFFFFFFFF == vertexShader )
{
if(CRenderOption::m_CharacterPerPixelLighting)
{
GetDevice()->SetVertexShader( BUMPVERTEXFVF );
}
else
{
GetDevice()->SetVertexShader( D3DFVF_VERTEX );
}
}
else
{
GetDevice()->SetVertexShader( vertexShader );
}
}
matrix m;
m.MakeIdent();
m._41 = m_vPivotPos.x;
m._42 = m_vPivotPos.y;
m._43 = m_vPivotPos.z;
GetDevice()->SetTransform( D3DTS_WORLD, m );
int i, j;
Z3DLODMesh* pMesh;
int nLODLevel = (m_lLODLevel+Z3D_LOD_LEVEL-1)/2;
long lVertexOffset, lIndexOffset;
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( m_apPortion[i]->m_alIndexCount[nLODLevel] )
{
if(CRenderOption::m_CharacterPerPixelLighting)
{
if( m_apPortion[0]->m_bSTVertexMode )
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pSTVertexBuffer, sizeof(BumpVertexST) );
else
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(BumpVertex) );
}
else
{
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(D3DVERTEX) );
}
lVertexOffset = 0;
lIndexOffset = 0;
for( j = 0; j < m_apPortion[i]->m_vec_pMesh.size(); ++j )
{
pMesh = m_apPortion[i]->m_vec_pMesh[j];
if( pMesh->aIndex[nLODLevel].lIndexCount )
{
GetDevice()->SetIndices( m_apPortion[i]->m_apIndexBuffer[nLODLevel], 0 );
GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, lVertexOffset,
pMesh->lVertexCount, lIndexOffset,
(pMesh->aIndex[nLODLevel].lIndexCount)/3 );
}
lVertexOffset += pMesh->lVertexCount;
lIndexOffset += pMesh->aIndex[nLODLevel].lIndexCount;
}
GetDevice()->SetStreamSource( 0, NULL, 0 );
GetDevice()->SetIndices( NULL, 0 );
}
}
}
/**/
void CZ3DMultipartSkin::RenderSpecular( DWORD vertexShader )
{
if( m_bIsBatchMode )
{
return;
}
if(m_pEnvMap == NULL)
{
m_pEnvMap = new CTexture;
CTexture::SetPath(EFFECTTEXTUREPATH);
m_pEnvMap->Load("cube.dds");
}
int i, j;
int nLODLevel = GetLODLevel();
long lVertexOffset, lIndexOffset;
Z3DLODMesh* pMesh = NULL;
if(CRenderOption::m_CharacterPerPixelLighting)
{
//GetDevice()->SetVertexShader( BUMPVERTEXFVF );
}
else
{
GetDevice()->SetVertexShader( D3DFVF_VERTEX );
}
matrix m;
m.MakeIdent();
m._41 = m_vPivotPos.x;
m._42 = m_vPivotPos.y;
m._43 = m_vPivotPos.z;
GetDevice()->SetTransform( D3DTS_WORLD, m );
////////////// Bump Spec Shader Constant Setting ///////////////
LPDIRECT3DDEVICE8 lpDevice = GetDevice();
if(CRenderOption::m_CharacterPerPixelLighting)
{
static CShader_ClassicBumpSpec *pTestShader = NULL;
if(!pTestShader)
{
pTestShader = new CShader_ClassicBumpSpec;
}
// Get all the matrices, combine them, and set the vertex shader constant matrix.
D3DXMATRIX matWorld,matView,matProj;
lpDevice->GetTransform(D3DTS_WORLD,&matWorld);
lpDevice->GetTransform(D3DTS_VIEW,&matView);
lpDevice->GetTransform(D3DTS_PROJECTION,&matProj);
D3DXMATRIX matInvView;
D3DXMatrixInverse(&matInvView,NULL,&matView);
D3DXMATRIX matCamera;
D3DXMATRIX mat;
D3DXMATRIX matTranspose;
D3DXMatrixMultiply(&matCamera, &matWorld, &matView);
D3DXMatrixMultiply(&mat, &matCamera, &matProj);
D3DXMatrixTranspose(&matTranspose, &mat);
lpDevice->SetVertexShaderConstant(0, &matTranspose,4);
D3DXVECTOR4 uvScale(1.0f, 1.0f, 1.0f, 1.0f);
lpDevice->SetVertexShaderConstant( 6, &uvScale, 1 );
D3DXMATRIX worldToLocal;
D3DXMatrixInverse(&worldToLocal, NULL, &matWorld);
// object space 에서의 Camera pos
D3DXVECTOR3 cameraLocal(matInvView._41,matInvView._42,matInvView._43);
D3DXVec3TransformCoord(&cameraLocal, &cameraLocal, &worldToLocal);
CSceneStateMgr::_SetD3DRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE );
//D3DXVECTOR3 vecLight(m_vPivotPos.x + 1000.0f,m_vPivotPos.y + 1000.0f,m_vPivotPos.z + 1000.0f);
D3DXVECTOR3 vecLight;
static bool bLight = true;
static int iUnit = 100;
vecLight = D3DXVECTOR3(m_vPivotPos.x + iUnit,m_vPivotPos.y + iUnit,m_vPivotPos.z + iUnit);
if(bLight)
{
iUnit -= 1;
}
else
{
iUnit += 1;
}
if(iUnit == -100)
bLight = !bLight;
if(iUnit == 100)
bLight = !bLight;
D3DXVECTOR3 localPos;
D3DXVec3TransformCoord(&localPos, &vecLight, &worldToLocal);
lpDevice->SetVertexShaderConstant(4,&cameraLocal,1);
lpDevice->SetVertexShaderConstant(5,&localPos,1);
D3DXVECTOR4 vecAmb(0.2f,0.2f,0.2f,0.2f);
D3DXVECTOR4 vecDiff(0.8f,0.8f,0.8f,0.8f);
D3DXVECTOR4 vecSpec(1.0f,1.0f,1.0f,1.0f);
lpDevice->SetPixelShaderConstant(0,&vecAmb,1);
lpDevice->SetPixelShaderConstant(1,&vecDiff,1);
lpDevice->SetPixelShaderConstant(2,&vecSpec,1);
////////////////
////////////////
/* CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE,TRUE );
CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );*/
CSceneStateMgr::_SetD3DRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE );
/**/ pTestShader->m_iCurrentShader = 0;
pTestShader->Apply();
// Load diffuse texture map.
static LPDIRECT3DTEXTURE8 pDiffuseTexture = NULL;
static LPDIRECT3DTEXTURE8 pNormalTexture = NULL;
if(!pDiffuseTexture)
{
pDiffuseTexture = TextureUtils::CreateTextureAlpha("c:/mp-project/character/data/texture/m_Sacred_armor.dds","c:/mp-project/texture/shader/demo-spec.bmp",lpDevice);
}
if(!pNormalTexture)
{
pNormalTexture = TextureUtils::CreateNormalMapAlpha(10.0f,"c:/mp-project/texture/shader/demo-bump.bmp","c:/mp-project/texture/shader/demo-pow.bmp",lpDevice);
}
lpDevice->SetTexture( 0, pDiffuseTexture );
lpDevice->SetTexture( 1, pNormalTexture );
lpDevice->SetTexture( 2, TextureUtils::GetNormalisationCubemap(lpDevice) );
// Diff Render
/* for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( m_apPortion[i]->m_alIndexCount[nLODLevel] )
{
if(CRenderOption::m_CharacterPerPixelLighting)
{
if( m_apPortion[0]->m_bSTVertexMode )
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pSTVertexBuffer, sizeof(BumpVertexST) );
else
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(BumpVertex) );
}
else
{
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(D3DVERTEX) );
}
GetDevice()->SetIndices( m_apPortion[i]->m_apIndexBuffer[nLODLevel], 0 );
lVertexOffset = 0;
lIndexOffset = 0;
for( j = 0; j < m_apPortion[i]->m_vec_pMesh.size(); ++j )
{
pMesh = m_apPortion[i]->m_vec_pMesh[j];
if( pMesh->aIndex[nLODLevel].lIndexCount )
{
}
HRESULT hr = GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, lVertexOffset,
pMesh->lVertexCount, lIndexOffset,
(pMesh->aIndex[nLODLevel].lIndexCount)/3 );
lVertexOffset += pMesh->lVertexCount;
lIndexOffset += pMesh->aIndex[nLODLevel].lIndexCount;
}
}
}
*/
CSceneStateMgr::_SetD3DRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE );
lpDevice->SetTexture( 0, pNormalTexture );
lpDevice->SetTexture( 3, TextureUtils::GetSpecularCubemap(lpDevice) );
// Spec Render
/* CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND, D3DBLEND_DESTALPHA );
CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );*/
pTestShader->m_iCurrentShader = 1;
pTestShader->Apply();
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( m_apPortion[i]->m_alIndexCount[nLODLevel] )
{
if(CRenderOption::m_CharacterPerPixelLighting)
{
if( m_apPortion[0]->m_bSTVertexMode )
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pSTVertexBuffer, sizeof(BumpVertexST) );
else
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(BumpVertex) );
}
else
{
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(D3DVERTEX) );
}
GetDevice()->SetIndices( m_apPortion[i]->m_apIndexBuffer[nLODLevel], 0 );
lVertexOffset = 0;
lIndexOffset = 0;
for( j = 0; j < m_apPortion[i]->m_vec_pMesh.size(); ++j )
{
pMesh = m_apPortion[i]->m_vec_pMesh[j];
if( pMesh->aIndex[nLODLevel].lIndexCount )
{
}
HRESULT hr = GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, lVertexOffset,
pMesh->lVertexCount, lIndexOffset,
(pMesh->aIndex[nLODLevel].lIndexCount)/3 );
lVertexOffset += pMesh->lVertexCount;
lIndexOffset += pMesh->aIndex[nLODLevel].lIndexCount;
}
}
}
CSceneStateMgr::_SetD3DRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE );
}
/////////////////////
/*
LPDIRECT3DDEVICE8 lpDevice = GetDevice();
if(CRenderOption::m_CharacterPerPixelLighting)
{
lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1);
// lpDevice->SetVertexShaderConstant(21, D3DXVECTOR4(1.0f,1.0f,1.0f,0.0f), 1);
lpDevice->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1);
lpDevice->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1);
lpDevice->SetVertexShaderConstant(CV_HALF, D3DXVECTOR4(0.5f, 0.5f, 0.5f, 0.5f), 1);
// Matrix Set
D3DXMATRIX matWorld,matView,matProject;
lpDevice->GetTransform(D3DTS_WORLD,&matWorld);
lpDevice->GetTransform(D3DTS_VIEW,&matView);
lpDevice->GetTransform(D3DTS_PROJECTION,&matProject);
D3DXMATRIX matTemp;
D3DXMATRIX matWorldView;
D3DXMATRIX matInvWorldView;
D3DXMATRIX matWorldViewProj;
D3DXMATRIX matInvWorld;
D3DXMatrixMultiply(&matTemp, &matWorld, &matView);
D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProject);
D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
D3DXMatrixInverse(&matInvWorld, NULL, &matWorld);
D3DXMatrixInverse(&matInvWorldView, NULL, &matWorldView);
// Set World Camera Pos
D3DXMATRIX pmatPos;
lpDevice->GetTransform(D3DTS_VIEW,&pmatPos);
D3DXMatrixInverse(&pmatPos, NULL, &pmatPos);
D3DXVECTOR3 vecCamera3 = D3DXVECTOR3(pmatPos._41,pmatPos._42,pmatPos._43);
D3DXVECTOR4 vecCamera4 = D3DXVECTOR4(vecCamera3.x,vecCamera3.y,vecCamera3.z,0.0f);
lpDevice->SetVertexShaderConstant(CV_EYE_POS_WORLD, vecCamera4, 1);
// Projection to clip space
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
lpDevice->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
// Transform to eye space
D3DXMatrixTranspose(&matWorldView, &matWorldView);
lpDevice->SetVertexShaderConstant(CV_WORLDVIEW_0, &matWorldView(0, 0), 4);
D3DXMatrixTranspose(&matWorldView, &matWorldView);
// Transform to world space
D3DXMatrixTranspose(&matWorld, &matWorld);
lpDevice->SetVertexShaderConstant(CV_WORLD_0, &matWorld(0, 0), 4);
D3DXMatrixTranspose(&matWorld, &matWorld);
// Transform for normals
lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_0, &matInvWorldView(0, 0), 1);
lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_1, &matInvWorldView(1, 0), 1);
lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_2, &matInvWorldView(2, 0), 1);
// Set BumpScale
// lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1);
}
///////////////////////////////////////////////////////////////////
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( m_apPortion[i]->m_alIndexCount[nLODLevel] )
{
if( Z3D_MPT_TEXPIECE == m_apPortion[i]->m_MPT )
{
GetDevice()->SetTexture( 0, *(m_apPortion[i]->m_pTexture) );
GetDevice()->SetTexture( 1, *(m_apPortion[i]->m_pTexture2) );
}
if(CRenderOption::m_CharacterPerPixelLighting)
{
if( m_apPortion[0]->m_bSTVertexMode )
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pSTVertexBuffer, sizeof(BumpVertexST) );
else
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(BumpVertex) );
}
else
{
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(D3DVERTEX) );
}
GetDevice()->SetIndices( m_apPortion[i]->m_apIndexBuffer[nLODLevel], 0 );
lVertexOffset = 0;
lIndexOffset = 0;
for( j = 0; j < m_apPortion[i]->m_vec_pMesh.size(); ++j )
{
pMesh = m_apPortion[i]->m_vec_pMesh[j];
if( pMesh->aIndex[nLODLevel].lIndexCount )
{
if( Z3D_MPT_TEXTURE == m_apPortion[i]->m_MPT )
{
if( m_apPortion[i]->m_vec_pTexture[j] )
{
GetDevice()->SetTexture( 0, *(m_apPortion[i]->m_vec_pTexture[j]) );
}
else
{
GetDevice()->SetTexture( 0, NULL );
}
if( m_apPortion[i]->m_vec_pTexture2[j] )
{
GetDevice()->SetTexture( 1, *(m_apPortion[i]->m_vec_pTexture2[j]) );
}
else
{
GetDevice()->SetTexture( 1, NULL );
}
}
//////////// Bump Setting /////////////////
if(CRenderOption::m_CharacterPerPixelLighting)
{
if(CRenderOption::m_bRain) {
if(CRenderOption::m_CharacterPerPixelLighting)
{
// Set BumpScale
lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1);
// lpDevice->SetVertexShaderConstant(21, D3DXVECTOR4(1.0f,1.0f,1.0f,0.0f), 1);
lpDevice->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1);
lpDevice->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1);
lpDevice->SetVertexShaderConstant(CV_HALF, D3DXVECTOR4(0.5f, 0.5f, 0.5f, 0.5f), 1);
// Matrix Set
D3DXMATRIX matWorld,matView,matProject;
lpDevice->GetTransform(D3DTS_WORLD,&matWorld);
lpDevice->GetTransform(D3DTS_VIEW,&matView);
lpDevice->GetTransform(D3DTS_PROJECTION,&matProject);
D3DXMATRIX matTemp;
D3DXMATRIX matWorldView;
D3DXMATRIX matInvWorldView;
D3DXMATRIX matWorldViewProj;
D3DXMATRIX matInvWorld;
D3DXMatrixMultiply(&matTemp, &matWorld, &matView);
D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProject);
D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
D3DXMatrixInverse(&matInvWorld, NULL, &matWorld);
D3DXMatrixInverse(&matInvWorldView, NULL, &matWorldView);
// Set World Camera Pos
D3DXMATRIX pmatPos;
lpDevice->GetTransform(D3DTS_VIEW,&pmatPos);
D3DXMatrixInverse(&pmatPos, NULL, &pmatPos);
D3DXVECTOR3 vecCamera3 = D3DXVECTOR3(pmatPos._41,pmatPos._42,pmatPos._43);
D3DXVECTOR4 vecCamera4 = D3DXVECTOR4(vecCamera3.x,vecCamera3.y,vecCamera3.z,0.0f);
lpDevice->SetVertexShaderConstant(CV_EYE_POS_WORLD, vecCamera4, 1);
// Projection to clip space
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
lpDevice->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
// Transform to eye space
D3DXMatrixTranspose(&matWorldView, &matWorldView);
lpDevice->SetVertexShaderConstant(CV_WORLDVIEW_0, &matWorldView(0, 0), 4);
D3DXMatrixTranspose(&matWorldView, &matWorldView);
// Transform to world space
D3DXMatrixTranspose(&matWorld, &matWorld);
lpDevice->SetVertexShaderConstant(CV_WORLD_0, &matWorld(0, 0), 4);
D3DXMatrixTranspose(&matWorld, &matWorld);
// Transform for normals
lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_0, &matInvWorldView(0, 0), 1);
lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_1, &matInvWorldView(1, 0), 1);
lpDevice->SetVertexShaderConstant(CV_WORLDVIEWIT_2, &matInvWorldView(2, 0), 1);
// Set BumpScale
// lpDevice->SetVertexShaderConstant(CV_BUMP_SCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1);
}
}
int iShaderIndex = CSceneManager::m_ShaderManager.GetShader((char *)SHADER_STR_GLARE);
CSceneManager::m_ShaderManager.Apply(iShaderIndex);
}
/////////////////
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZBIAS ,0);
HRESULT hr = GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, lVertexOffset,
pMesh->lVertexCount, lIndexOffset,
(pMesh->aIndex[nLODLevel].lIndexCount)/3 );
if(0 && (CRenderOption::m_CharacterPerPixelLighting) && (CSceneManager::m_bEnv)) { // 환경 mapping
if(CRenderOption::m_CharacterPerPixelLighting)
{
GetDevice()->SetVertexShader(NULL);
GetDevice()->SetPixelShader(NULL);
}
GetDevice()->SetVertexShader(NULL);
//GetDevice()->SetVertexShader( D3DFVF_VERTEX );
GetDevice()->SetVertexShader( BUMPVERTEXFVF );
GetDevice()->SetPixelShader(NULL);
GetDevice()->SetTexture(1, m_pEnvMap->GetTexture());
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
CSceneStateMgr::_SetD3DRenderState(D3DRS_TEXTUREFACTOR,0x80555555);
//CSceneStateMgr::_SetD3DRenderState(D3DRS_TEXTUREFACTOR,0xff555555);
CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLORARG1,D3DTA_CURRENT);
CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLORARG2,D3DTA_TEXTURE);
//CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLORARG2,D3DTA_TFACTOR);
CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLOROP,D3DTOP_MODULATE);
CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_COLORARG1,D3DTA_CURRENT);
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_COLORARG2,D3DTA_TEXTURE);
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_COLOROP,D3DTOP_MODULATEALPHA_ADDCOLOR);
//CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_COLOROP,D3DTOP_MODULATECOLOR_ADDALPHA );
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ALPHAARG1,D3DTA_CURRENT);
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ALPHAARG2,D3DTA_TFACTOR);
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
CSceneStateMgr::_SetD3DTextureStageState(2, D3DTSS_COLOROP,D3DTOP_DISABLE);
CSceneStateMgr::_SetD3DTextureStageState(2, D3DTSS_ALPHAOP,D3DTOP_DISABLE);
CSceneStateMgr::_SetD3DTextureStageState(3, D3DTSS_COLOROP,D3DTOP_DISABLE);
CSceneStateMgr::_SetD3DTextureStageState(3, D3DTSS_ALPHAOP,D3DTOP_DISABLE);
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT3);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ZBIAS ,13);
GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, lVertexOffset,
pMesh->lVertexCount, lIndexOffset,
(pMesh->aIndex[nLODLevel].lIndexCount)/3 );
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_DISABLE);
CSceneStateMgr::_SetD3DTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTSS_TCI_PASSTHRU);
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DTextureStageState(1, D3DTSS_ADDRESSW, D3DTADDRESS_WRAP);
CSceneStateMgr::_SetD3DRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
}
}
lVertexOffset += pMesh->lVertexCount;
lIndexOffset += pMesh->aIndex[nLODLevel].lIndexCount;
}
}
}*/
IncreaseAniLODCounter();
}
/*
void CZ3DMultipartSkin::RenderSpecular( DWORD vertexShader )
{
_ASSERTE( !m_bIsBatchMode );
if( NULL != vertexShader )
{
if( 0xFFFFFFFF == vertexShader )
{
if(CRenderOption::m_CharacterPerPixelLighting)
{
GetDevice()->SetVertexShader( BUMPVERTEXFVF );
}
else
{
GetDevice()->SetVertexShader( D3DFVF_VERTEX );
}
}
else
{
GetDevice()->SetVertexShader( vertexShader );
}
}
matrix m;
m.MakeIdent();
m._41 = m_vPivotPos.x;
m._42 = m_vPivotPos.y;
m._43 = m_vPivotPos.z;
GetDevice()->SetTransform( D3DTS_WORLD, m );
int i, j;
Z3DLODMesh* pMesh;
int nLODLevel = (m_lLODLevel+Z3D_LOD_LEVEL-1)/2;
long lVertexOffset, lIndexOffset;
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( m_apPortion[i]->m_alIndexCount[nLODLevel] )
{
if(CRenderOption::m_CharacterPerPixelLighting)
{
if( m_apPortion[0]->m_bSTVertexMode )
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pSTVertexBuffer, sizeof(BumpVertexST) );
else
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(BumpVertex) );
}
else
{
GetDevice()->SetStreamSource( 0, m_apPortion[i]->m_pVertexBuffer, sizeof(D3DVERTEX) );
}
lVertexOffset = 0;
lIndexOffset = 0;
for( j = 0; j < m_apPortion[i]->m_vec_pMesh.size(); ++j )
{
pMesh = m_apPortion[i]->m_vec_pMesh[j];
if( pMesh->aIndex[nLODLevel].lIndexCount )
{
GetDevice()->SetIndices( m_apPortion[i]->m_apIndexBuffer[nLODLevel], 0 );
if( m_apPortion[i]->m_vec_pSpecTexture[j] )
{
GetDevice()->SetTexture( 0, *(m_apPortion[i]->m_vec_pSpecTexture[j]) );
}
else
{
GetDevice()->SetTexture( 0, NULL );
}
GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, lVertexOffset,
pMesh->lVertexCount, lIndexOffset,
(pMesh->aIndex[nLODLevel].lIndexCount)/3 );
}
lVertexOffset += pMesh->lVertexCount;
lIndexOffset += pMesh->aIndex[nLODLevel].lIndexCount;
}
GetDevice()->SetStreamSource( 0, NULL, 0 );
GetDevice()->SetIndices( NULL, 0 );
}
}
}
*/
void CZ3DMultipartSkin::GetBoundingBox( vector3& r_vmin, vector3& r_vmax )
{
int i, j;
r_vmin = vector3( 0, 0, 0 );
r_vmax = vector3( 0, 0, 0 );
D3DVERTEXBUFFER_DESC vd;
if(CRenderOption::m_CharacterPerPixelLighting)
{
BumpVertex* pVertices;
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( 0 == m_apPortion[i]->m_vec_pMesh.size() )
{
continue;
}
m_apPortion[i]->m_pVertexBuffer->GetDesc( &vd );
m_apPortion[i]->m_pVertexBuffer->Lock( 0, 0, (BYTE**)(&pVertices), 0 );
for( j = 0; j < vd.Size/sizeof(BumpVertex); ++j )
{
if( pVertices[j].v.x < r_vmin.x )
{
r_vmin.x = pVertices[j].v.x;
}
if( pVertices[j].v.y < r_vmin.y )
{
r_vmin.y = pVertices[j].v.y;
}
if( pVertices[j].v.z < r_vmin.z )
{
r_vmin.z = pVertices[j].v.z;
}
if( pVertices[j].v.x > r_vmax.x )
{
r_vmax.x = pVertices[j].v.x;
}
if( pVertices[j].v.y > r_vmax.y )
{
r_vmax.y = pVertices[j].v.y;
}
if( pVertices[j].v.z > r_vmax.z )
{
r_vmax.z = pVertices[j].v.z;
}
}
m_apPortion[i]->m_pVertexBuffer->Unlock();
}
}
else
{
D3DVERTEX* pVertices;
for( i = 0; i < Z3D_MULTIPART_PORTION_COUNT; i++ )
{
if( 0 == m_apPortion[i]->m_vec_pMesh.size() )
{
continue;
}
m_apPortion[i]->m_pVertexBuffer->GetDesc( &vd );
m_apPortion[i]->m_pVertexBuffer->Lock( 0, 0, (BYTE**)(&pVertices), 0 );
for( j = 0; j < vd.Size/sizeof(D3DVERTEX); ++j )
{
if( pVertices[j].x < r_vmin.x )
{
r_vmin.x = pVertices[j].x;
}
if( pVertices[j].y < r_vmin.y )
{
r_vmin.y = pVertices[j].y;
}
if( pVertices[j].z < r_vmin.z )
{
r_vmin.z = pVertices[j].z;
}
if( pVertices[j].x > r_vmax.x )
{
r_vmax.x = pVertices[j].x;
}
if( pVertices[j].y > r_vmax.y )
{
r_vmax.y = pVertices[j].y;
}
if( pVertices[j].z > r_vmax.z )
{
r_vmax.z = pVertices[j].z;
}
}
m_apPortion[i]->m_pVertexBuffer->Unlock();
}
}
}
void CZ3DMultipartSkin::GetProcessedVertex( Z3DBlend2Vertex& v_in, vector3& v_out ) const
{
matrix m2[2];
m_rpSkeleton[v_in.mtrx_id[0]].GetLocalizedTM( m2[0], m_rpSkeletonLocalizer[v_in.mtrx_id[0]] );
m_rpSkeleton[v_in.mtrx_id[1]].GetLocalizedTM( m2[1], m_rpSkeletonLocalizer[v_in.mtrx_id[1]] );
float factor1 = v_in.bfactor;
float factor2 = 1.0f - factor1;
float f1 = (factor1*m2[0]._11) + (factor2*m2[1]._11);
float f2 = (factor1*m2[0]._21) + (factor2*m2[1]._21);
float f3 = (factor1*m2[0]._31) + (factor2*m2[1]._31);
float f4 = (factor1*m2[0]._41) + (factor2*m2[1]._41);
v_out.x = (v_in.pos.x*f1 + v_in.pos.y*f2 + v_in.pos.z*f3 + f4);
f1 = (factor1*m2[0]._12) + (factor2*m2[1]._12);
f2 = (factor1*m2[0]._22) + (factor2*m2[1]._22);
f3 = (factor1*m2[0]._32) + (factor2*m2[1]._32);
f4 = (factor1*m2[0]._42) + (factor2*m2[1]._42);
v_out.y = (v_in.pos.x*f1 + v_in.pos.y*f2 + v_in.pos.z*f3 + f4);
f1 = (factor1*m2[0]._13) + (factor2*m2[1]._13);
f2 = (factor1*m2[0]._23) + (factor2*m2[1]._23);
f3 = (factor1*m2[0]._33) + (factor2*m2[1]._33);
f4 = (factor1*m2[0]._43) + (factor2*m2[1]._43);
v_out.z = (v_in.pos.x*f1 + v_in.pos.y*f2 + v_in.pos.z*f3 + f4);
}
long CZ3DMultipartSkin::GetPolyCount( int nLODLevel ) const
{
if( -1 == nLODLevel )
{
nLODLevel = m_lLODLevel;
}
if( nLODLevel >= Z3D_LOD_LEVEL )
{
return 0;
}
long lSum = 0;
for( int i = 0; i < Z3D_MULTIPART_PORTION_COUNT; ++i )
{
lSum += m_apPortion[i]->m_alIndexCount[nLODLevel];
}
lSum /= 3;
return lSum;
}
void CZ3DMultipartSkin::ApplySTMode()
{
for( int i = 0; i < Z3D_MULTIPART_PORTION_COUNT; ++i )
{
m_apPortion[i]->BuildSTVertex( GetDevice() );
}
}
//////////////////////////////////////////////////////////////////////////
#include "SimpleParser.h"
bool Z3DPseudoClothDescriptor::Load( const char* szFileName )
{
CSimpleParser parser;
if( false == parser.OpenFile( szFileName, NULL ) )
{
return false;
}
char* szToken = NULL;
szToken = parser.GetNextToken();
if( NULL == szToken || 0 != strcmp( "Z3PCS0", szToken ) )
{
return false;
}
while( NULL != (szToken = parser.GetNextToken()) )
{
if( 0 == stricmp( "grid_width", szToken ) )
{
szToken = parser.GetNextToken();
lGridXCount = aton( szToken );
szToken = parser.GetNextToken();
}
else if( 0 == stricmp( "grid_height", szToken ) )
{
szToken = parser.GetNextToken();
lGridXCount = aton( szToken );
szToken = parser.GetNextToken();
}
}
return true;
}
void CZ3DPseudoCloth::FrameMove()
{
}
void CZ3DPseudoCloth::Render()
{
}
bool CZ3DPseudoCloth::SetScriptTexture( const char* szScriptName, const char* szTextureName, const char* szTexture2Name )
{
char szTmp[300];
//strcpy( szTmp, g_ContLODMesh.GetFilePath() );
strcat( szTmp, szScriptName );
Z3DPseudoClothDescriptor* pDesc = NULL;
pDesc = new Z3DPseudoClothDescriptor;
if( true == pDesc->Load( szTmp ) )
{
m_vecpDescriptors.push_back( pDesc );
}
return true;
}
void CZ3DPseudoCloth::Reset()
{
for( int i = 0; i < m_vecpDescriptors.size(); ++i )
{
SAFE_DELETE( m_vecpDescriptors[i] );
}
m_vecpDescriptors.clear();
}
bool CZ3DPseudoCloth::BatchOpen()
{
Reset();
return true;
}
bool CZ3DPseudoCloth::BatchClose()
{
for( int i = 0; i < m_vecpDescriptors.size(); ++i )
{
BuildActualPseudoCloth( m_vecpDescriptors[i] );
}
return true;
}
bool CZ3DPseudoCloth::BuildActualPseudoCloth( Z3DPseudoClothDescriptor* pDesc )
{
return true;
}