370 lines
No EOL
13 KiB
C++
370 lines
No EOL
13 KiB
C++
#include "StdAfx.h"
|
|
#include "EtSprite.h"
|
|
#include "EtCamera.h"
|
|
#include "../EternityEngine/D3DDevice9/EtStateManager.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
|
#endif
|
|
|
|
CEtCustomSprite::CEtCustomSprite()
|
|
{
|
|
EtMatrixIdentity(&m_WorldMat);
|
|
EtMatrixIdentity(&m_ViewMat);
|
|
EtMatrixIdentity(&m_ProjMat);
|
|
|
|
D3DVERTEXELEMENT9 VertexElement[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
|
|
{ 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
|
|
D3DDECL_END() };
|
|
|
|
m_nVertexDecl = GetEtDevice()->CreateVertexDeclaration( VertexElement );
|
|
m_dwFlag = 0;
|
|
}
|
|
|
|
void CEtCustomSprite::Begin( DWORD Flags)
|
|
{
|
|
EtMatrixIdentity(&m_WorldMat);
|
|
EtMatrixIdentity(&m_ViewMat);
|
|
EtMatrixIdentity(&m_ProjMat);
|
|
m_dwFlag = Flags;
|
|
}
|
|
|
|
void CEtCustomSprite::SetTransform( EtMatrix *pTransform)
|
|
{
|
|
m_ProjMat = *pTransform;
|
|
}
|
|
|
|
void CEtCustomSprite::SetWorldViewLH( EtMatrix *pWorld, EtMatrix *pView)
|
|
{
|
|
m_WorldMat = *pWorld;
|
|
m_ViewMat = *pView;
|
|
}
|
|
|
|
void CEtCustomSprite::Draw( LPDIRECT3DTEXTURE9 pTexture, CONST RECT *pSrcRect, CONST D3DXVECTOR3 *pCenter, CONST D3DXVECTOR3 *pPosition, D3DCOLOR Color)
|
|
{
|
|
RECT Rect = *pSrcRect;
|
|
EtMatrix TransMat = m_ProjMat;
|
|
if( Rect.top == Rect.bottom )
|
|
{
|
|
Rect.bottom += (Rect.right-Rect.left);
|
|
TransMat._21 = 0.f;
|
|
TransMat._22 = 1.f;
|
|
TransMat._23 = 0.f;
|
|
TransMat._24 = 0.f;
|
|
}
|
|
|
|
LPDIRECT3DDEVICE9 pd3dDevice = (LPDIRECT3DDEVICE9)GetEtDevice()->GetDevicePtr();
|
|
EtMatrix BackupProjMat, BackupWorldMat;
|
|
pd3dDevice->GetTransform( D3DTS_PROJECTION, &BackupProjMat );
|
|
pd3dDevice->GetTransform( D3DTS_WORLD, &BackupWorldMat);
|
|
if( m_dwFlag & D3DXSPRITE_OBJECTSPACE )
|
|
{
|
|
GetEtDevice()->SetWorldTransform( &TransMat );
|
|
}
|
|
else
|
|
{
|
|
EtMatrix OffsetMat;
|
|
EtMatrix ProjMat;
|
|
EtMatrixTranslation(&OffsetMat, -0.5f, -0.5f, 0.f);
|
|
D3DXMatrixOrthoOffCenterLH(&ProjMat, 0.f, (float)GetEtDevice()->Width(), (float)GetEtDevice()->Height(), 0.f, 0.f, 1.f);
|
|
EtMatrixMultiply(&TransMat, &TransMat, &OffsetMat);
|
|
EtMatrixMultiply(&TransMat, &TransMat, &ProjMat);
|
|
EtMatrix MatIdent;
|
|
EtMatrixIdentity(&MatIdent);
|
|
GetEtDevice()->SetWorldTransform( &MatIdent );
|
|
GetEtDevice()->SetViewTransform( &MatIdent );
|
|
GetEtDevice()->SetProjTransform( &TransMat );
|
|
}
|
|
GetEtDevice()->SetCullMode( CULL_NONE );
|
|
GetEtDevice()->SetVertexShader( NULL );
|
|
GetEtDevice()->SetPixelShader( NULL );
|
|
GetEtDevice()->EnableAlphaBlend( true );
|
|
GetEtDevice()->SetFVF( FVF_XYZ | FVF_TEX1 );
|
|
GetEtDevice()->SetTexture( 0, pTexture );
|
|
GetEtDevice()->SetVertexDeclaration( m_nVertexDecl );
|
|
|
|
GetEtDevice()->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
|
|
GetEtDevice()->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
|
|
|
|
GetEtDevice()->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
|
|
GetEtDevice()->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
|
|
|
|
GetEtDevice()->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
|
GetEtDevice()->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR );
|
|
|
|
GetEtDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
|
GetEtDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR );
|
|
|
|
DWORD dwTextureFilterCaps = GetEtDevice()->GetTextureFilterCaps();
|
|
|
|
if( dwTextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) {
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC );
|
|
}
|
|
else {
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
|
|
}
|
|
if( dwTextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) {
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC );
|
|
}
|
|
else {
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
|
|
}
|
|
|
|
if( dwTextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR) {
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
|
|
}
|
|
else {
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT );
|
|
}
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MAXANISOTROPY, GetEtDevice()->GetMaxAnisotropy() );
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MAXMIPLEVEL, 0);
|
|
|
|
GetEtDevice()->SetRenderState( D3DRS_TEXTUREFACTOR, Color);
|
|
|
|
D3DSURFACE_DESC Desc;
|
|
pTexture->GetLevelDesc( 0, &Desc);
|
|
|
|
int nTexWidth = Desc.Width;
|
|
int nTexHeight = Desc.Height;
|
|
|
|
float fScaleX = (float)(Rect.right - Rect.left) / nTexWidth;
|
|
float fScaleY = (float)(Rect.bottom - Rect.top ) / nTexHeight;
|
|
STextureVertex Vertices[ 4 ];
|
|
Vertices[ 0 ].Position = EtVector3( 0, 0, 0.f);
|
|
Vertices[ 0 ].TexCoordinate = EtVector2( (float)Rect.left / nTexWidth , (float)Rect.top / nTexHeight );
|
|
Vertices[ 1 ].Position = EtVector3( nTexWidth*fScaleX, 0, 0.f);
|
|
Vertices[ 1 ].TexCoordinate = EtVector2( (float)Rect.right / nTexWidth , (float)Rect.top / nTexHeight );
|
|
Vertices[ 2 ].Position = EtVector3( 0, nTexHeight*fScaleY, 0.f);
|
|
Vertices[ 2 ].TexCoordinate = EtVector2( (float)Rect.left / nTexWidth, (float)Rect.bottom / nTexHeight );
|
|
Vertices[ 3 ].Position = EtVector3( nTexWidth*fScaleX, nTexHeight*fScaleY, 0.f);
|
|
Vertices[ 3 ].TexCoordinate = EtVector2( (float)Rect.right / nTexWidth, (float)Rect.bottom / nTexHeight );
|
|
|
|
GetEtDevice()->DrawPrimitiveUP( PT_TRIANGLESTRIP, 2, Vertices, sizeof( STextureVertex ) );
|
|
|
|
GetEtDevice()->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
|
|
GetEtDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
|
|
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MAXANISOTROPY, 1 );
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
|
|
|
|
GetEtDevice()->SetProjTransform( &BackupProjMat );
|
|
GetEtDevice()->SetWorldTransform( &BackupWorldMat );
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
CEtSprite::CEtSprite(void)
|
|
{
|
|
m_bBegin = false;
|
|
m_pSprite = NULL;
|
|
m_pCustomSprite = NULL;
|
|
m_pDXSprite = NULL;
|
|
}
|
|
|
|
CEtSprite::~CEtSprite(void)
|
|
{
|
|
SAFE_DELETE( m_pCustomSprite );
|
|
SAFE_DELETE( m_pDXSprite );
|
|
}
|
|
|
|
void CEtSprite::Initialize()
|
|
{
|
|
m_pCustomSprite = new CEtCustomSprite;
|
|
m_pDXSprite = new CEtDXSprite;
|
|
m_pSprite = m_pDXSprite;
|
|
}
|
|
|
|
void CEtSprite::SetTransform( EtMatrix &TransMat )
|
|
{
|
|
m_pSprite->SetTransform( &TransMat );
|
|
}
|
|
|
|
void CEtSprite::SetWorldViewMat( EtMatrix &WorldMat, EtMatrix &ViewMat )
|
|
{
|
|
m_pSprite->SetWorldViewLH( &WorldMat, &ViewMat );
|
|
}
|
|
|
|
void CEtSprite::Begin( DWORD dwFlags )
|
|
{
|
|
m_pSprite = m_pDXSprite;//m_pDXSprite;
|
|
|
|
if( m_pSprite != m_pCustomSprite && GetEtStateManager()->IsEnable() ) {
|
|
GetEtStateManager()->Capture();
|
|
|
|
GetEtDevice()->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
|
|
GetEtDevice()->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATER );
|
|
GetEtDevice()->SetRenderState( D3DRS_ALPHAREF, 0x00 );
|
|
GetEtDevice()->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
|
|
GetEtDevice()->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
|
|
GetEtDevice()->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
|
|
GetEtDevice()->SetRenderState( D3DRS_SRCBLEND ,D3DBLEND_SRCALPHA );
|
|
GetEtDevice()->SetRenderState( D3DRS_DESTBLEND ,D3DBLEND_INVSRCALPHA );
|
|
|
|
GetEtDevice()->SetSamplerState( 0 ,D3DSAMP_ADDRESSU ,D3DTADDRESS_CLAMP );
|
|
GetEtDevice()->SetSamplerState( 0 ,D3DSAMP_ADDRESSV ,D3DTADDRESS_CLAMP );
|
|
|
|
DWORD dwTextureFilterCaps = GetEtDevice()->GetTextureFilterCaps();
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MAGFILTER, ( dwTextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR );
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MINFILTER, ( dwTextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR );
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MIPFILTER, ( dwTextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR) ? D3DTEXF_LINEAR : D3DTEXF_POINT );
|
|
GetEtDevice()->SetSamplerState( 0, D3DSAMP_MAXANISOTROPY, GetEtDevice()->GetMaxAnisotropy() );
|
|
|
|
//GetEtStateManager()->FlushDeferedStates();
|
|
m_pSprite->Begin( dwFlags | D3DXSPRITE_DONOTSAVESTATE );
|
|
}
|
|
else {
|
|
m_pSprite->Begin( dwFlags );
|
|
}
|
|
m_bBegin = true;
|
|
}
|
|
|
|
void CEtSprite::End()
|
|
{
|
|
m_pSprite->End();
|
|
|
|
if( m_pSprite != m_pCustomSprite && GetEtStateManager()->IsEnable() ) {
|
|
GetEtStateManager()->Restore();
|
|
}
|
|
|
|
m_bBegin = false;
|
|
}
|
|
|
|
void CEtSprite::Flush()
|
|
{
|
|
m_pSprite->Flush();
|
|
}
|
|
|
|
void CEtSprite::DrawSprite( EtTexture *pTexture, int nTexWidth, int nTexHeight, SUICoord &UVCoord, DWORD dwColor, SUICoord &ScreenCoord, float fRotate, float fZValue, float fShear )
|
|
{
|
|
if( fZValue > 1.0f || fZValue < 0.f ) {
|
|
return;
|
|
}
|
|
|
|
bool bInternalBegin = false;
|
|
if( m_bBegin == false )
|
|
{
|
|
Begin( 0 );
|
|
bInternalBegin = true;
|
|
}
|
|
|
|
RECT Rect;
|
|
float fScaleX, fScaleY;
|
|
EtVector3 vPosition;
|
|
EtMatrix ScaleMat, TransMat;
|
|
float fSpriteSizeX, fSpriteSizeY;
|
|
|
|
fSpriteSizeX = ( UVCoord.fX + UVCoord.fWidth ) * nTexWidth;
|
|
fSpriteSizeY = ( UVCoord.fY + UVCoord.fHeight ) * nTexHeight;
|
|
SetRect( &Rect, ( int )(floorf( UVCoord.fX * nTexWidth + 0.5f )), ( int )(floorf( UVCoord.fY * nTexHeight + 0.5f )), ( int )(floorf(fSpriteSizeX+0.5f)), ( int )(floorf(fSpriteSizeY+0.5f)) );
|
|
|
|
fScaleX = ScreenCoord.fWidth * GetEtDevice()->Width() / ( UVCoord.fWidth * nTexWidth );
|
|
fScaleY = ScreenCoord.fHeight * GetEtDevice()->Height() / ( UVCoord.fHeight * nTexHeight );
|
|
|
|
EtMatrixScaling( &ScaleMat, fScaleX, fScaleY, 1.0f );
|
|
EtMatrixTranslation( &TransMat, ScreenCoord.fX * GetEtDevice()->Width(), ScreenCoord.fY * GetEtDevice()->Height(), fZValue );
|
|
EtMatrixMultiply( &TransMat, &ScaleMat, &TransMat );
|
|
|
|
if( fShear != 0.0f ) {
|
|
EtMatrix ShearMat;
|
|
EtMatrixIdentity(&ShearMat);
|
|
ShearMat._21 = -fShear * fScaleY / fScaleX;
|
|
EtMatrixMultiply( &TransMat, &ShearMat, &TransMat );
|
|
}
|
|
|
|
if( fRotate != 0.0f )
|
|
{
|
|
EtMatrix MoveOffsetMat, RotateMat;
|
|
float fSpriteCenterX, fSpriteCenterY;
|
|
|
|
fSpriteCenterX = UVCoord.fWidth * nTexWidth * 0.5f;
|
|
fSpriteCenterY = UVCoord.fHeight * nTexHeight * 0.5f;
|
|
EtMatrixTranslation( &MoveOffsetMat, -fSpriteCenterX, -fSpriteCenterY, 0.0f );
|
|
EtMatrixRotationZ( &RotateMat, EtToRadian( fRotate ) );
|
|
EtMatrixMultiply( &RotateMat, &MoveOffsetMat, &RotateMat );
|
|
EtMatrixTranslation( &MoveOffsetMat, fSpriteCenterX, fSpriteCenterY, 0.0f );
|
|
EtMatrixMultiply( &RotateMat, &RotateMat, &MoveOffsetMat );
|
|
EtMatrixMultiply( &TransMat, &RotateMat, &TransMat );
|
|
}
|
|
|
|
/*EtViewPort viewPort;
|
|
GetEtDevice()->GetViewport( &viewPort );
|
|
|
|
float fViewportScaleX = (float)GetEtDevice()->Width() / viewPort.Width;
|
|
float fViewportScaleY = (float)GetEtDevice()->Height() / viewPort.Height;
|
|
|
|
D3DXMATRIX viewPortMat( fViewportScaleX , 0.f, 0.f, 0.f,
|
|
0.f, fViewportScaleY, 0.f, 0.f,
|
|
0.f, 0.f, 1.f, 0.f,
|
|
-fViewportScaleX * viewPort.X,
|
|
-fViewportScaleY * viewPort.Y, 0.f, 1.f );
|
|
|
|
EtMatrixMultiply(&TransMat, &TransMat, &viewPortMat);*/
|
|
m_pSprite->SetTransform( &TransMat );
|
|
Draw( pTexture, &Rect, NULL, NULL, dwColor );
|
|
|
|
if( bInternalBegin )
|
|
{
|
|
End();
|
|
}
|
|
}
|
|
|
|
void CEtSprite::Draw( LPDIRECT3DTEXTURE9 pTexture, CONST RECT *pSrcRect, CONST D3DXVECTOR3 *pCenter, CONST D3DXVECTOR3 *pPosition, D3DCOLOR Color)
|
|
{
|
|
GetEtStateManager()->FlushDeferedStates();
|
|
m_pSprite->Draw( pTexture, pSrcRect, pCenter, pPosition, Color );
|
|
}
|
|
|
|
void CEtSprite::DrawSprite3D( EtTexture *pTexture, int nTexWidth, int nTexHeight, DWORD dwColor, EtVector2 &vSize, EtVector3 &vPosition, float fRotate, SUICoord *pCoord )
|
|
{
|
|
EtCameraHandle hCamera = CEtCamera::GetActiveCamera();
|
|
if( !hCamera ) return;
|
|
EtMatrix *pViewMat = hCamera->GetViewMat();
|
|
EtMatrix *pProjMat = hCamera->GetProjMat();
|
|
EtVector3 vUpLeft, vDownRight;
|
|
float fTransZ;
|
|
|
|
EtVec3TransformCoord( &vUpLeft, &vPosition, pViewMat );
|
|
vDownRight = vUpLeft;
|
|
vUpLeft.x -= vSize.x * 0.5f;
|
|
vUpLeft.y += vSize.y * 0.5f;
|
|
vDownRight.x += vSize.x * 0.5f;
|
|
vDownRight.y -= vSize.y * 0.5f;
|
|
EtVec3TransformCoord( &vUpLeft, &vUpLeft, pProjMat );
|
|
EtVec3TransformCoord( &vDownRight, &vDownRight, pProjMat );
|
|
fTransZ = vUpLeft.z;
|
|
|
|
SUICoord UVCoord, ScreenCoord;
|
|
|
|
if( pCoord ) UVCoord = *pCoord;
|
|
else UVCoord.SetCoord( 0.0f, 0.0f, 1.0f, 1.0f );
|
|
|
|
ScreenCoord.SetCoord( ( vUpLeft.x + 1.0f ) * 0.5f, 1.0f - ( vUpLeft.y + 1.0f ) * 0.5f, ( vDownRight.x - vUpLeft.x ) * 0.5f, ( vUpLeft.y - vDownRight.y ) * 0.5f );
|
|
DrawSprite( pTexture, nTexWidth, nTexHeight, UVCoord, dwColor, ScreenCoord, fRotate, fTransZ );
|
|
}
|
|
|
|
void CEtSprite::DrawRect( SUICoord &ScreenCoord, DWORD dwColor, float fZValue )
|
|
{
|
|
SUICoord UVCoord;
|
|
UVCoord.SetCoord( 0.0f, 0.0f, 1.0f, 1.0f );
|
|
DrawSprite( (EtTexture*)CEtTexture::GetWhiteTexture()->GetTexturePtr(), 1, 1, UVCoord, dwColor, ScreenCoord, 0.f, fZValue, 0.f );
|
|
}
|
|
|
|
void CEtSprite::OnLostDevice()
|
|
{
|
|
if( m_pDXSprite )
|
|
{
|
|
m_pDXSprite->OnLostDevice();
|
|
}
|
|
}
|
|
|
|
void CEtSprite::OnResetDevice()
|
|
{
|
|
if( m_pDXSprite )
|
|
{
|
|
m_pDXSprite->OnResetDevice();
|
|
}
|
|
} |