// Z3DRenderable.cpp: implementation of the CZ3DRenderable class. // ////////////////////////////////////////////////////////////////////// #pragma warning(disable:4786) #include "Z3DRenderable.h" #include "3DMath.h" #include "SimpleParser.h" #include #include "GMMemory.h" IDirect3DDevice8* CZ3DRenderable::ms_pDevice; std::list CZ3DRenderable::ms_listpObjects; std::vector CZ3DRenderable::ms_vec_pRenderObjects; std::vector CZ3DRenderable::ms_vec_pSecondRenderObjects; //unsigned long CZ3DRenderable::ms_ulVertexStateBlockHandle; //unsigned long CZ3DRenderable::ms_ulPixelStateBlockHandle; vector3 CZ3DRenderable::ms_vec_CameraPos; D3DXMATRIX CZ3DRenderable::ms_IdentityD3DMatrix; vector3 CZ3DRenderable::m_vecCameraPosition; D3DMATERIAL8 CZ3DRenderable::ms_Material; bool CZ3DRenderable::_Init(PDIRECT3DDEVICE8 pDevice) { if( !pDevice ) return false; ms_pDevice = pDevice; D3DXMatrixIdentity( &ms_IdentityD3DMatrix ); // ms_pDevice->CreateStateBlock( D3DSBT_PIXELSTATE, &ms_ulPixelStateBlockHandle ); // ms_pDevice->CreateStateBlock( D3DSBT_VERTEXSTATE, &ms_ulVertexStateBlockHandle ); return true; } bool CZ3DRenderable::_Close() { if( ms_pDevice ) { // ms_pDevice->DeleteStateBlock( ms_ulVertexStateBlockHandle ); // ms_pDevice->DeleteStateBlock( ms_ulPixelStateBlockHandle ); ms_pDevice = NULL; } return true; } static bool operator< ( CZ3DRenderable& a, CZ3DRenderable& b ) { return (a.GetTexturePtr() < b.GetTexturePtr()); } static DWORD s_dwAmbient; static DWORD s_dwZWriteEnable; static DWORD s_dwLighting; static DWORD s_dwAlphaBlend; static DWORD s_dwAlphaTest; static DWORD s_dwSrcBlend; static DWORD s_dwDestBlend; static DWORD s_dwTS0Op; static DWORD s_dwTS0Arg1; static DWORD s_dwTS0Arg2; static DWORD s_dwTS1Op; void CZ3DRenderable::Process() { std::list::iterator iter; // get camera position for LOD level calculation matrix m; ms_pDevice->GetTransform( D3DTS_VIEW, m ); matrix matForViewPosition; matForViewPosition.Inverse(m); ms_vec_CameraPos=matForViewPosition.GetLoc(); // clear pervious work vector if( !(ms_vec_pRenderObjects.empty()) ) ms_vec_pRenderObjects.clear(); if( !(ms_vec_pSecondRenderObjects.empty()) ) ms_vec_pSecondRenderObjects.clear(); // make non-culled object vector for( iter = ms_listpObjects.begin(); iter != ms_listpObjects.end(); iter++ ) { if( !((*iter)->IsCulled()) && !((*iter)->IsRenderIndividually()) ) { ms_vec_pRenderObjects.push_back( *iter ); // check second-renderability if( (*iter)->IsSecondRenderable() ) { ms_vec_pSecondRenderObjects.push_back( *iter ); } } } ptr_greater pg; std::sort( ms_vec_pRenderObjects.begin(), ms_vec_pRenderObjects.end(), pg ); // save current renderstates // GetDevice()->CreateStateBlock( D3DSBT_ALL, &ms_ulRenderStateBlockHandle ); // GetDevice()->CaptureStateBlock( ms_ulPixelStateBlockHandle ); // GetDevice()->CaptureStateBlock( ms_ulVertexStateBlockHandle ); GetDevice()->GetRenderState( D3DRS_AMBIENT, &s_dwAmbient ); GetDevice()->GetRenderState( D3DRS_ZWRITEENABLE, &s_dwZWriteEnable ); GetDevice()->GetRenderState( D3DRS_LIGHTING, &s_dwLighting ); GetDevice()->GetRenderState( D3DRS_ALPHABLENDENABLE, &s_dwAlphaBlend ); GetDevice()->GetRenderState( D3DRS_ALPHATESTENABLE, &s_dwAlphaTest ); GetDevice()->GetRenderState( D3DRS_SRCBLEND, &s_dwSrcBlend ); GetDevice()->GetRenderState( D3DRS_DESTBLEND, &s_dwDestBlend ); GetDevice()->GetTextureStageState( 0, D3DTSS_ALPHAOP, &s_dwTS0Op ); GetDevice()->GetTextureStageState( 0, D3DTSS_ALPHAARG1, &s_dwTS0Arg1 ); GetDevice()->GetTextureStageState( 0, D3DTSS_ALPHAARG2, &s_dwTS0Arg2 ); GetDevice()->GetTextureStageState( 1, D3DTSS_ALPHAOP, &s_dwTS1Op ); // setting up renderstate here GetDevice()->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_ARGB(0xff, 0x80, 0x80, 0x80) ); ms_Material.Ambient.a = 1.0f; ms_Material.Ambient.r = 1.0f; ms_Material.Ambient.g = 1.0f; ms_Material.Ambient.b = 1.0f; ms_Material.Diffuse.a = 1.0f; ms_Material.Diffuse.r = 1.0f; ms_Material.Diffuse.g = 1.0f; ms_Material.Diffuse.b = 1.0f; ms_Material.Emissive.a = 1.0f; ms_Material.Emissive.r = 0.0f; ms_Material.Emissive.g = 0.0f; ms_Material.Emissive.b = 0.0f; ms_Material.Power = 0; //GetDevice()->SetMaterial( &ms_Material ); GetDevice()->SetRenderState( D3DRS_ALPHABLENDENABLE,TRUE); GetDevice()->SetRenderState( D3DRS_ALPHATESTENABLE,TRUE); GetDevice()->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); GetDevice()->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE ); GetDevice()->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); // render CZ3DRenderable* pRenderable; GetDevice()->SetTexture( 0, NULL ); IDirect3DTexture8* pPrevTexture = NULL; for( int i = 0; i < (int)ms_vec_pRenderObjects.size(); i++ ) { pRenderable = ms_vec_pRenderObjects[i]; if( pPrevTexture != pRenderable->GetTexturePtr() && (IDirect3DTexture8*)0xFFFFFFFF != pRenderable->GetTexturePtr() ) { // texture change GetDevice()->SetTexture( 0, pRenderable->GetTexturePtr() ); //GetDevice()->SetTexture( 0, NULL ); pPrevTexture = pRenderable->GetTexturePtr(); } ms_Material.Diffuse.a = pRenderable->GetTransparency(); GetDevice()->SetMaterial( &ms_Material ); pRenderable->Render(); } GetDevice()->SetTexture( 0, NULL ); // GetDevice()->SetStreamSource( 0, NULL, 0 ); // GetDevice()->SetIndices( NULL, 0 ); GetDevice()->SetTextureStageState( 1, D3DTSS_ALPHAOP, s_dwTS1Op ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG2, s_dwTS0Arg2 ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG1, s_dwTS0Arg1 ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAOP, s_dwTS0Op ); GetDevice()->SetRenderState( D3DRS_DESTBLEND, s_dwDestBlend ); GetDevice()->SetRenderState( D3DRS_SRCBLEND, s_dwSrcBlend ); GetDevice()->SetRenderState( D3DRS_ALPHATESTENABLE, s_dwAlphaTest ); GetDevice()->SetRenderState( D3DRS_ALPHABLENDENABLE, s_dwAlphaBlend ); GetDevice()->SetRenderState( D3DRS_LIGHTING, s_dwLighting ); GetDevice()->SetRenderState( D3DRS_ZWRITEENABLE, s_dwZWriteEnable ); GetDevice()->SetRenderState( D3DRS_AMBIENT, s_dwAmbient ); // GetDevice()->SetRenderState( D3DRS_ALPHABLENDENABLE,FALSE); // GetDevice()->SetRenderState( D3DRS_ALPHATESTENABLE,FALSE); // GetDevice()->ApplyStateBlock( ms_ulVertexStateBlockHandle ); // GetDevice()->ApplyStateBlock( ms_ulPixelStateBlockHandle ); // GetDevice()->DeleteStateBlock( ms_ulRenderStateBlockHandle ); } void CZ3DRenderable::SecondProcess() { // setting up second render state( alpha'd object ) // save current renderstates // GetDevice()->CreateStateBlock( D3DSBT_ALL, &ms_ulRenderStateBlockHandle ); // GetDevice()->CaptureStateBlock( ms_ulPixelStateBlockHandle ); // GetDevice()->CaptureStateBlock( ms_ulVertexStateBlockHandle ); GetDevice()->GetRenderState( D3DRS_AMBIENT, &s_dwAmbient ); GetDevice()->GetRenderState( D3DRS_ZWRITEENABLE, &s_dwZWriteEnable ); GetDevice()->GetRenderState( D3DRS_LIGHTING, &s_dwLighting ); GetDevice()->GetRenderState( D3DRS_ALPHABLENDENABLE, &s_dwAlphaBlend ); GetDevice()->GetRenderState( D3DRS_ALPHATESTENABLE, &s_dwAlphaTest ); GetDevice()->GetRenderState( D3DRS_SRCBLEND, &s_dwSrcBlend ); GetDevice()->GetRenderState( D3DRS_DESTBLEND, &s_dwDestBlend ); GetDevice()->GetTextureStageState( 0, D3DTSS_ALPHAOP, &s_dwTS0Op ); GetDevice()->GetTextureStageState( 0, D3DTSS_ALPHAARG1, &s_dwTS0Arg1 ); GetDevice()->GetTextureStageState( 0, D3DTSS_ALPHAARG2, &s_dwTS0Arg2 ); GetDevice()->GetTextureStageState( 1, D3DTSS_ALPHAOP, &s_dwTS1Op ); static D3DMATERIAL8 tmpMtrl; GetDevice()->GetMaterial( &tmpMtrl ); // setting up renderstate here GetDevice()->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80) ); ms_Material.Ambient.a = 1.0f; ms_Material.Ambient.r = 0.4f; ms_Material.Ambient.g = 0.4f; ms_Material.Ambient.b = 0.4f; ms_Material.Diffuse.a = 1.0f; ms_Material.Diffuse.r = 1.60f; ms_Material.Diffuse.g = 1.60f; ms_Material.Diffuse.b = 1.60f; ms_Material.Emissive.a = 1.0f; ms_Material.Emissive.r = 0.0f; ms_Material.Emissive.g = 0.0f; ms_Material.Emissive.b = 0.0f; ms_Material.Power = 0.0f; //GetDevice()->SetMaterial( &ms_Material ); // TEST now GetDevice()->SetRenderState( D3DRS_ZWRITEENABLE, FALSE); GetDevice()->SetRenderState( D3DRS_LIGHTING, FALSE ); DWORD dwCullState; GetDevice()->GetRenderState( D3DRS_CULLMODE, &dwCullState ); GetDevice()->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); GetDevice()->SetRenderState( D3DRS_ALPHABLENDENABLE,TRUE); GetDevice()->SetRenderState( D3DRS_ALPHATESTENABLE,FALSE); GetDevice()->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); GetDevice()->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); GetDevice()->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); GetDevice()->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); GetDevice()->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); GetDevice()->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE ); GetDevice()->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); ptr_greater pg; std::sort( ms_vec_pSecondRenderObjects.begin(), ms_vec_pSecondRenderObjects.end(), pg ); // render CZ3DRenderable* pRenderable; GetDevice()->SetTexture( 0, NULL ); IDirect3DTexture8* pPrevTexture = NULL; for( int i = 0; i < (int)ms_vec_pSecondRenderObjects.size(); i++ ) { pRenderable = ms_vec_pSecondRenderObjects[i]; if( pPrevTexture != pRenderable->GetTexturePtr() && (IDirect3DTexture8*)0xFFFFFFFF != pRenderable->GetTexturePtr() ) { // texture change GetDevice()->SetTexture( 0, pRenderable->GetTexturePtr() ); pPrevTexture = pRenderable->GetTexturePtr(); } /*if( pRenderable->IsLightenSecondRender() ) { GetDevice()->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); } else { GetDevice()->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); }*/ GetDevice()->SetRenderState( D3DRS_SRCBLEND, pRenderable->m_SecondRenderSrcBlend ); GetDevice()->SetRenderState( D3DRS_DESTBLEND, pRenderable->m_SecondRenderDestBlend ); ms_Material.Diffuse.a = pRenderable->GetTransparency(); GetDevice()->SetMaterial( &ms_Material ); pRenderable->SecondRender(); } GetDevice()->SetMaterial( &tmpMtrl ); GetDevice()->SetTexture( 0, NULL ); GetDevice()->SetStreamSource( 0, NULL, 0 ); GetDevice()->SetIndices( NULL, 0 ); GetDevice()->SetRenderState( D3DRS_CULLMODE, dwCullState ); GetDevice()->SetTextureStageState( 1, D3DTSS_ALPHAOP, s_dwTS1Op ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG2, s_dwTS0Arg2 ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAARG1, s_dwTS0Arg1 ); GetDevice()->SetTextureStageState( 0, D3DTSS_ALPHAOP, s_dwTS0Op ); GetDevice()->SetRenderState( D3DRS_DESTBLEND, s_dwDestBlend ); GetDevice()->SetRenderState( D3DRS_SRCBLEND, s_dwSrcBlend ); GetDevice()->SetRenderState( D3DRS_ALPHATESTENABLE, s_dwAlphaTest ); GetDevice()->SetRenderState( D3DRS_ALPHABLENDENABLE, s_dwAlphaBlend ); GetDevice()->SetRenderState( D3DRS_LIGHTING, s_dwLighting ); GetDevice()->SetRenderState( D3DRS_ZWRITEENABLE, s_dwZWriteEnable ); GetDevice()->SetRenderState( D3DRS_AMBIENT, s_dwAmbient ); // GetDevice()->ApplyStateBlock( ms_ulVertexStateBlockHandle ); // GetDevice()->ApplyStateBlock( ms_ulPixelStateBlockHandle ); // GetDevice()->DeleteStateBlock( ms_ulRenderStateBlockHandle ); }