DragonNest/Common/EternityEngine/EtRenderStack.cpp

667 lines
19 KiB
C++
Raw Permalink Normal View History

#include "StdAfx.h"
#include "EtRenderStack.h"
#include "EtShadowMap.h"
#include "EtMRTMng.h"
#include "EtLight.h"
#include "EtBackBufferMng.h"
#include "EtLensFlare.h"
#include "EtCustomRender.h"
#include "EtOptionController.h"
#include "EtWater.h"
#include "D3DDevice9/EtStateManager.h"
#include "D3DDevice9/EtCallBack.h"
#include "StringUtil.h"
#include "EtSkyBoxRTT.h"
#include "EtEngine.h"
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
#define _USE_INSTANCING 1
extern float g_fTotalElapsedTime;
int GetDepthTechnique( int nTechniqueIndex, int nBakeDepthIndex )
{
int nDepthIndex = nBakeDepthIndex;
int nResult = nDepthIndex + ( nTechniqueIndex & 1 );
return nResult;
}
void CEtRenderStack::RadixSort( std::vector< SRenderStackElement* > &vecSortNeed )
{
int nBufferIndex = 0;
for( std::vector< SRenderStackElement* >::iterator it = vecSortNeed.begin(); it != vecSortNeed.end(); ++it) {
SRenderStackElement *pElem = *it;
float fDistVal = EtMax(pElem->fDist, 0);
int nIndex = ((int)(fDistVal)) % 10;
m_vecRadixSort[ nBufferIndex ][ nIndex ].push_back( pElem );
}
float fDivide = 10.0f;
bool bContinue = false;
do {
bContinue = false;
for( int i = 0; i < 10; i++)
{
int nSize = (int)m_vecRadixSort[ nBufferIndex ][ i ].size();
for( int j = 0; j < nSize; j++) {
SRenderStackElement *pElem = m_vecRadixSort[ nBufferIndex ][ i ][ j ];
float fDistVal = EtMax(pElem->fDist , 0.f);
int nIndex = ((int)(fDistVal / fDivide )) % 10;
if( nIndex != 0) bContinue = true;
assert( 1 - nBufferIndex < 2 && nIndex < 10 );
m_vecRadixSort[ 1 - nBufferIndex ][ nIndex ].push_back( pElem );
}
m_vecRadixSort[ nBufferIndex ][ i ].clear();
}
fDivide *= 10;
nBufferIndex = 1 - nBufferIndex;
}while( bContinue );
vecSortNeed.clear();
for( int i = 0; i < 10; i++)
{
int nSize = (int)m_vecRadixSort[ nBufferIndex ][ i ].size();
for( int j = 0; j < nSize; j++) {
vecSortNeed.push_back( m_vecRadixSort[ nBufferIndex ][ i ][ j ] );
}
m_vecRadixSort[ nBufferIndex ][ i ].clear();
ASSERT( m_vecRadixSort[ 1 - nBufferIndex ][ i ].empty() );
}
}
bool NormalRenderSort( SRenderStackElement *Element1, SRenderStackElement *Element2 )
{
if( Element1->renderPriority != Element2->renderPriority )
{
if( Element1->renderPriority < Element2->renderPriority )
return true;
else
return false;
}
else
{
if( Element1->fDist < Element2->fDist )
{
return true;
}
else
{
return false;
}
}
}
bool AlphaRenderSort( const SRenderStackElement *Element1, const SRenderStackElement *Element2 )
{
if( Element1->renderPriority != Element2->renderPriority )
{
if( Element1->renderPriority < Element2->renderPriority )
return true;
else
return false;
}
else
{
if( Element1->fDist > Element2->fDist )
{
return true;
}
else
{
return false;
}
}
}
CEtRenderStack *g_pRenderStack[ 2 ];
bool CEtRenderStack::s_bUseOcclusion = false;
bool CEtRenderStack::s_bRenderDepth = false;
CEtRenderStack::CEtRenderStack(void)
{
m_fComputeAniTime = 0.0f;
m_nCurentUniqueID = 0;
m_nCurOcclusionMngIndex = 0;
m_nInteractivePosIndex = -1;
m_nDiffuseTexParamIndex = -1;
m_nVolumeTexParamIndex = -1;
m_vInteractivePos = EtVector4( 0.0f, 0.0f, 0.0f, 0.0f );
}
CEtRenderStack::~CEtRenderStack(void)
{
SAFE_RELEASE_SPTR( m_hBakeDepthMaterial );
SAFE_DELETE_PVEC( m_RenderBlockPoolFree );
SAFE_DELETE_PVEC( m_RenderBlockPoolUsed );
}
SRenderStackElement* CEtRenderStack::AllocBlock( SRenderStackElement &RenderElement )
{
SRenderStackElement *pBlock = NULL;
if( m_RenderBlockPoolFree.empty() ) {
pBlock = new SRenderStackElement;
}
else {
pBlock = m_RenderBlockPoolFree.back();
m_RenderBlockPoolFree.pop_back();
}
*pBlock = RenderElement;
m_RenderBlockPoolUsed.push_back( pBlock );
return pBlock;
}
void CEtRenderStack::RefreshAllocBlock()
{
m_RenderBlockPoolFree.insert( m_RenderBlockPoolFree.end(), m_RenderBlockPoolUsed.begin(), m_RenderBlockPoolUsed.end() );
m_RenderBlockPoolUsed.clear();
}
void CEtRenderStack::ClassifyAlphaDepth()
{
for( std::vector< SRenderStackElement* >::iterator it = m_vecRenderElement[ PASS_ALPHA ].begin(); it != m_vecRenderElement[ PASS_ALPHA ].end(); )
{
if( ( *it )->nBakeDepthIndex == DT_NONE )
{
++it;
}
else
{
m_vecRenderElement[ PASS_ALPHADEPTH ].push_back( *it );
it = m_vecRenderElement[ PASS_ALPHA ].erase( it );
}
}
}
void CEtRenderStack::RenderDepthBlock( PassType passType, bool bAutoDeleteList )
{
if( !s_bRenderDepth )
{
if( bAutoDeleteList )
{
m_vecRenderElement[ passType ].clear();
}
return;
}
if( m_vecRenderElement[ passType ].empty() )
{
return;
}
if( !m_hBakeDepthMaterial )
{
int nTexIndex = -1;
m_vInteractivePos = EtVector4( 0.0f, 0.0f, 0.0f, 0.0f );
m_hBakeDepthMaterial = ::LoadResource( "BakeDepth.fx", RT_SHADER );
m_nDiffuseTexParamIndex = ::AddCustomParam( m_vecBakeDepthParam, EPT_TEX, m_hBakeDepthMaterial, "g_DiffuseTex", &nTexIndex );
m_nVolumeTexParamIndex = ::AddCustomParam( m_vecBakeDepthParam, EPT_TEX, m_hBakeDepthMaterial, "g_DiffuseVolumeTex", &nTexIndex );
::AddCustomParam( m_vecBakeDepthParam, EPT_VECTOR_PTR, m_hBakeDepthMaterial, "g_InteractivePos", &m_vInteractivePos );
::AddCustomParam( m_vecBakeDepthParam, EPT_FLOAT_PTR, m_hBakeDepthMaterial, "g_ComputeAniTimeForDepth", &m_fComputeAniTime );
}
CEtMRTMng::GetInstance().BeginDepthTarget();
CEtMaterial *pBakeDepthMaterial = m_hBakeDepthMaterial.GetPointer();
int nPasses = 0;
std::vector< SRenderStackElement* >::iterator it;
for( it = m_vecRenderElement[ passType ].begin(); it != m_vecRenderElement[ passType ].end(); )
{
SRenderStackElement *pCurBlock = *it;
if( pCurBlock->nBakeDepthIndex == DT_NONE )
{
++it;
continue;
}
int nDepthTechnique = GetDepthTechnique( pCurBlock->nTechniqueIndex, pCurBlock->nBakeDepthIndex );
if( pCurBlock->nBakeDepthIndex == DT_TERRAIN )
{
nDepthTechnique = DT_OPAQUE;
}
switch( nDepthTechnique )
{
case DT_GRASS:
{
if( m_nInteractivePosIndex == -1 )
{
EtParameterHandle hFindHandle = pCurBlock->hMaterial->GetParameterByName( "g_InteractivePos" );
int i;
std::vector< SCustomParam > &vecCustomParam = *pCurBlock->pvecCustomParam;
for( i = 0; i < ( int )vecCustomParam.size(); i++ )
{
if( vecCustomParam[ i ].hParamHandle == hFindHandle )
{
m_nInteractivePosIndex = i;
break;
}
}
}
if( ( m_nInteractivePosIndex >= 0 ) && ( m_nInteractivePosIndex < ( int )pCurBlock->pvecCustomParam->size() ) )
{
memcpy( &m_vInteractivePos, ( *pCurBlock->pvecCustomParam )[ m_nInteractivePosIndex ].pPointer, sizeof( EtVector4 ) );
}
}
break;
case DT_VOLUME:
case DT_VOLUME + 1:
{
if( m_nVolumeTexParamIndex != -1 )
{
m_vecBakeDepthParam[ m_nVolumeTexParamIndex ].nTextureIndex = pCurBlock->nDiffuseTexIndex;
}
if( pCurBlock->pvecCustomParam )
{
int i;
std::vector< SCustomParam > &vecCustomParam = *pCurBlock->pvecCustomParam;
for( i = 0; i < ( int )vecCustomParam.size(); i++ )
{
if( ( vecCustomParam[ i ].nVariableCount == 1 ) && ( vecCustomParam[ i ].Type == EPT_FLOAT ) )
{
if( pCurBlock->hMaterial->IsParameterName( vecCustomParam[ i ].hParamHandle , "g_AniTime" ) )
{
m_fComputeAniTime = fmodf( g_fTotalElapsedTime, vecCustomParam[ i ].fFloat ) / vecCustomParam[ i ].fFloat;
break;
}
}
}
}
}
break;
}
++it;
pBakeDepthMaterial->SetTechnique( nDepthTechnique );
pBakeDepthMaterial->BeginEffect( nPasses );
pBakeDepthMaterial->BeginPass( 0 );
pBakeDepthMaterial->SetGlobalParams();
if( pCurBlock->nSaveMatIndex != -1 )
{
if( ( pCurBlock->pRenderSubMesh ) && ( pCurBlock->pRenderSubMesh->GetLinkCount() ) )
{
pBakeDepthMaterial->SetWorldMatArray( &pCurBlock->WorldMat, pCurBlock->nSaveMatIndex,
pCurBlock->pRenderSubMesh->GetLinkCount(), pCurBlock->pRenderSubMesh->GetLinkIndex() );
}
}
pBakeDepthMaterial->SetWorldMatParams( &pCurBlock->WorldMat, &pCurBlock->PrevWorldMat );
if( m_nDiffuseTexParamIndex != -1 )
{
m_vecBakeDepthParam[ m_nDiffuseTexParamIndex ].nTextureIndex = pCurBlock->nDiffuseTexIndex;
}
pBakeDepthMaterial->SetCustomParamList( m_vecBakeDepthParam );
// Set RenderState, SamplerState
bool bZWrite = true;
if( pCurBlock->nStateBlockIndex != -1 )
{
const SStateBlock *pStateBlock = GetEtStateManager()->GetStateBlock( pCurBlock->nStateBlockIndex );
pStateBlock->SetState();
bZWrite = GetEtDevice()->EnableZWrite( true );
}
pBakeDepthMaterial->CommitChanges();
int nOcclusionIndex;
if( ( s_bUseOcclusion ) && ( passType == PASS_OPAQUE ) )
{
nOcclusionIndex = m_OcclusionMng[ m_nCurOcclusionMngIndex ].AllocOcclusion();
m_mapOcclusionCheck[ m_nCurOcclusionMngIndex ].insert( std::make_pair( pCurBlock->nRenderUniqueID, nOcclusionIndex ) );
m_OcclusionMng[ m_nCurOcclusionMngIndex ].BeginOcclusion( nOcclusionIndex );
}
int nVertexDeclIndex = pBakeDepthMaterial->GetVertexDeclIndex( nDepthTechnique, 0 );
if( nVertexDeclIndex != -1 )
{
if( pCurBlock->pRenderSubMesh )
{
pCurBlock->pRenderSubMesh->Draw( nVertexDeclIndex );
}
else
{
pCurBlock->pRenderMeshStream->Draw( nVertexDeclIndex, pCurBlock->nDrawStart, pCurBlock->nDrawCount );
}
}
if( ( s_bUseOcclusion ) && ( passType == PASS_OPAQUE ) )
{
m_OcclusionMng[ m_nCurOcclusionMngIndex ].EndOcclusion( nOcclusionIndex );
}
// Restore RenderState, SamplerSate
if( pCurBlock->nStateBlockIndex != -1 )
{
GetEtDevice()->EnableZWrite( bZWrite );
const SStateBlock *pStateBlock = GetEtStateManager()->GetStateBlock( pCurBlock->nStateBlockIndex );
pStateBlock->RestoreState();
}
pBakeDepthMaterial->EndPass();
pBakeDepthMaterial->EndEffect();
}
if( bAutoDeleteList )
{
m_vecRenderElement[ passType ].clear();
}
CEtMRTMng::GetInstance().EndDepthTarget();
}
void CEtRenderStack::RenderBlock( PassType passType, bool bAutoDeleteList )
{
if( m_vecRenderElement[ passType ].empty() ) {
return;
}
RenderPriorityEnum prevBackBufferPriority = RP_NONE;
bool bLightSettingNeeded = ( passType != PASS_SHADOW && passType != PASS_WATER );
int nElementSize = ( int )m_vecRenderElement[ passType ].size();
for( int i = 0; i <nElementSize; i++ )
{
SRenderStackElement *pBlock = m_vecRenderElement[ passType ][ i ];
if(passType == PASS_USEBACKBUFFER ) {
if( prevBackBufferPriority != pBlock->renderPriority ) {
GetEtBackBufferMng()->DumpBackBuffer();
prevBackBufferPriority = pBlock->renderPriority;
}
}
if( bLightSettingNeeded ) {
CEtLight::SetInfluenceLight( pBlock->pInfluenceLight );
CEtLight::SetDirLightAttenuation( pBlock->fDirLightAttenuation );
}
if( pBlock->bIsAlphaSky )
{
GetEtDevice()->EnableAlphaBlend( true );
GetEtDevice()->EnableZWrite( false );
}
CEtMaterial *pCurMaterial = pBlock->hMaterial.GetPointer();
#ifdef PRE_FIX_MATERIAL_DUMP
if( pCurMaterial == NULL )
continue;
#endif
int nCurTechnique = pBlock->nTechniqueIndex;
pCurMaterial->SetTechnique( nCurTechnique );
int nPasses=0;
pCurMaterial->BeginEffect( nPasses );
pCurMaterial->BeginPass( 0 );
pCurMaterial->SetGlobalParams();
if( ( pBlock->nSaveMatIndex != -1 ) )
{
if( ( pBlock->pRenderSubMesh ) && ( pBlock->pRenderSubMesh->GetLinkCount() ) )
{
pCurMaterial->SetWorldMatArray( &pBlock->WorldMat, pBlock->nSaveMatIndex,
pBlock->pRenderSubMesh->GetLinkCount(), pBlock->pRenderSubMesh->GetLinkIndex() );
}
}
pCurMaterial->SetWorldMatParams( &pBlock->WorldMat, &pBlock->PrevWorldMat );
if( pBlock->pvecCustomParam )
{
pCurMaterial->SetCustomParamList( *pBlock->pvecCustomParam );
}
// Set RenderState, SamplerState
if( pBlock->nStateBlockIndex != -1 ) {
const SStateBlock *pStateBlock = GetEtStateManager()->GetStateBlock( pBlock->nStateBlockIndex );
pStateBlock->SetState();
}
pCurMaterial->CommitChanges();
EtCmpFunc ZFunc;
DWORD dwAlphaRef;
if( pBlock->bIsTwoPassAlpha )
{
DWORD dwColorWrite = GetEtDevice()->SetColorWriteEnable( 0 );
bool bZWrite = GetEtDevice()->EnableZWrite( true );
bool bEnableAlpha = GetEtDevice()->EnableAlphaBlend( false );
dwAlphaRef = GetEtDevice()->SetAlphaRef( 1 );
if( pBlock->pRenderSubMesh )
pBlock->pRenderSubMesh->Draw( pCurMaterial->GetVertexDeclIndex( pBlock->nTechniqueIndex, 0 ), pBlock->nDrawStart, pBlock->nDrawCount );
else
pBlock->pRenderMeshStream->Draw( pCurMaterial->GetVertexDeclIndex( pBlock->nTechniqueIndex, 0 ), pBlock->nDrawStart, pBlock->nDrawCount );
GetEtDevice()->SetAlphaRef( dwAlphaRef );
GetEtDevice()->EnableAlphaBlend( bEnableAlpha );
GetEtDevice()->EnableZWrite( bZWrite );
GetEtDevice()->SetColorWriteEnable( dwColorWrite );
ZFunc = GetEtDevice()->SetZFunc( CF_EQUAL );
}
if( pBlock->pRenderSubMesh )
pBlock->pRenderSubMesh->Draw( pCurMaterial->GetVertexDeclIndex( pBlock->nTechniqueIndex, 0 ), pBlock->nDrawStart, pBlock->nDrawCount );
else
pBlock->pRenderMeshStream->Draw( pCurMaterial->GetVertexDeclIndex( pBlock->nTechniqueIndex, 0 ), pBlock->nDrawStart, pBlock->nDrawCount );
if( pBlock->bIsTwoPassAlpha )
{
GetEtDevice()->SetZFunc( ZFunc );
}
// Restore RenderState, SamplerSate
if( pBlock->nStateBlockIndex != -1 ) {
const SStateBlock *pStateBlock = GetEtStateManager()->GetStateBlock( pBlock->nStateBlockIndex );
pStateBlock->RestoreState();
}
pCurMaterial->EndPass();
pCurMaterial->EndEffect();
if( pBlock->bIsAlphaSky )
{
GetEtDevice()->EnableAlphaBlend( false );
GetEtDevice()->EnableZWrite( true );
}
}
if( bAutoDeleteList )
{
m_vecRenderElement[ passType ].clear();
}
}
void CEtRenderStack::UpdateSkyBoxRTT()
{
EtCameraHandle hCamera = CEtCamera::GetActiveCamera();
CEtSkyBoxRTT::GetInstance().UpdateCamera( *hCamera->GetInvViewMat() );
}
void CEtRenderStack::FlushRender( bool bExtraRender )
{
UpdateSkyBoxRTT();
// Bake Shadow
if( GetEtShadowMap() )
{
GetEtShadowMap()->Bake( this );
}
// Bake Water
if( GetEtWater() )
{
GetEtWater()->Bake( this, m_fElapsedTime);
}
// Bake Depth
CEtMRTMng::GetInstance().ClearDepthTarget();
if( !s_bUseOcclusion )
{
m_InstancingManager.ClassifyBlock( m_vecRenderElement[ PASS_OPAQUE ], m_vecRenderElement[ PASS_INSTANCING ] );
m_InstancingManager.RenderDepth( m_vecRenderElement[ PASS_INSTANCING ] );
}
std::sort( m_vecRenderElement[ PASS_OPAQUE ].begin(), m_vecRenderElement[ PASS_OPAQUE ].end(), NormalRenderSort );
RenderDepthBlock( PASS_OPAQUE );
CalcOcclusion(); // <20><>Ŭ<EFBFBD><C5AC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
m_nCurOcclusionMngIndex = 1 - m_nCurOcclusionMngIndex;
// Render Opaque Color Pass
GetEtDevice()->ClearBuffer( 0, 1.0f, 0, false, true, true ); // Z Buffer Clear
if( s_bUseOcclusion )
{
m_InstancingManager.ClassifyBlock( m_vecRenderElement[ PASS_OPAQUE ], m_vecRenderElement[ PASS_INSTANCING ] );
}
m_InstancingManager.Render( m_vecRenderElement[ PASS_INSTANCING ] );
GetEtDevice()->EnableAlphaBlend( true );
GetEtDevice()->EnableZWrite( false );
RenderBlock( PASS_ALPHASKYBOX, false );
GetEtDevice()->EnableAlphaBlend( false );
GetEtDevice()->EnableZWrite( true );
RenderDepthBlock( PASS_ALPHASKYBOX, true );
RenderBlock( PASS_OPAQUE );
GetEtDevice()->EnableAlphaBlend( true );
GetEtDevice()->EnableZWrite( false );
std::stable_sort( m_vecRenderElement[ PASS_ALPHA ].begin(), m_vecRenderElement[ PASS_ALPHA ].end(), AlphaRenderSort );
RenderBlock( PASS_ALPHA, false );
GetEtDevice()->EnableAlphaBlend( false );
RenderDepthBlock( PASS_ALPHA, true );
std::stable_sort( m_vecRenderElement[ PASS_USEBACKBUFFER ].begin(), m_vecRenderElement[ PASS_USEBACKBUFFER ].end(), AlphaRenderSort );
GetEtDevice()->EnableAlphaBlend( true );
RenderBlock( PASS_USEBACKBUFFER );
GetEtDevice()->EnableAlphaBlend( false );
if( bExtraRender )
{
CEtLensFlare::RenderFlareList( m_fElapsedTime );
}
GetEtDevice()->EnableAlphaBlend( false );
GetEtPostProcessMng()->Render( m_fElapsedTime );
GetEtDevice()->EnableAlphaBlend( true );
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȵ<EFBFBD><C8B5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̴ϱ<CCB4> <20>׳<EFBFBD> <20><><EFBFBD><20>׸<EFBFBD><D7B8><EFBFBD>..
CEtObject::DrawCollisionList( g_nCurFrustumMask );
if( bExtraRender )
{
CEtCustomRender::RenderCustomList( m_fElapsedTime );
}
GetEtDevice()->EnableZWrite( true );
GetEtDevice()->EnableAlphaBlend( false );
if( CEtCamera::GetActiveCamera() )
{
CEtCamera::GetActiveCamera()->EndCamera();
}
RefreshAllocBlock();
#if defined(_DEBUG) || defined(_RDEBUG)
for( int i = 0; i < PASS_COUNT; i++)
{
ASSERT( m_vecRenderElement[i].empty() );
}
#endif
}
void CEtRenderStack::CalcOcclusion()
{
if( !s_bUseOcclusion ) return;
PROFILE_TIME_TEST_BLOCK_START( "Occlusion Culling" );
int i;
int nSkipCount = 0;
int nPrevOcclusionMng = 1 - m_nCurOcclusionMngIndex;
CEtOcclusionMng *pPrevOcclusionMng = &m_OcclusionMng[ nPrevOcclusionMng ];
int nCurRenderElementCount = ( int )m_vecRenderElement[ PASS_OPAQUE ].size();
for( i = 0; i < nCurRenderElementCount; i++ )
{
if( i >= nCurRenderElementCount - nSkipCount )
{
break;
}
std::map< int, int >::iterator it = m_mapOcclusionCheck[ nPrevOcclusionMng ].find( m_vecRenderElement[ PASS_OPAQUE ][ i ]->nRenderUniqueID );
if( it != m_mapOcclusionCheck[ nPrevOcclusionMng ].end() )
{
DWORD dwRet;
dwRet = pPrevOcclusionMng->ResultOcclusion( it->second );
if( dwRet == 0 )
{
nSkipCount++;
std::swap( m_vecRenderElement[ PASS_OPAQUE ][ i ], m_vecRenderElement[ PASS_OPAQUE ][ nCurRenderElementCount - nSkipCount ] );
i--;
}
}
}
if( nSkipCount )
{
m_vecRenderElement[ PASS_OPAQUE ].erase( m_vecRenderElement[ PASS_OPAQUE ].begin() + ( nCurRenderElementCount - nSkipCount ), m_vecRenderElement[ PASS_OPAQUE ].end() );
}
m_mapOcclusionCheck[ nPrevOcclusionMng ].clear();
pPrevOcclusionMng->ClearOcclusion();
PROFILE_TIME_TEST_BLOCK_END();
}
CEtRenderStack *GetCurRenderStack()
{
return g_pRenderStack[ 0 ];
}
int CEtRenderStack::AddNormalRenderElement( SRenderStackElement &RenderElement, int nRenderUniqueID )
{
if( nRenderUniqueID == -1 )
{
nRenderUniqueID = m_nCurentUniqueID;
m_nCurentUniqueID++;
}
RenderElement.nRenderUniqueID = nRenderUniqueID;
m_vecRenderElement[ PASS_OPAQUE ].push_back( AllocBlock( RenderElement ) );
return nRenderUniqueID;
}
void CEtRenderStack::EmptyRenderElement()
{
for( int i = 0; i < PASS_COUNT; i++) {
m_vecRenderElement[i].clear();
}
RefreshAllocBlock();
}
void CEtRenderStack::Sort( int passType, bool bOpaque )
{
if( bOpaque ) {
std::sort( m_vecRenderElement[ passType ].begin(), m_vecRenderElement[ passType ].end(), NormalRenderSort );
}
else {
std::sort( m_vecRenderElement[ passType ].begin(), m_vecRenderElement[ passType ].end(), AlphaRenderSort );
}
}
void CEtRenderStack::FlushBuffer()
{
for( int i=0; i<PASS_COUNT; i++ ) SAFE_DELETE_VEC( m_vecRenderElement[i] );
for( int i=0; i<2; i++ ) {
m_OcclusionMng[i].FlushBuffer();
SAFE_DELETE_VEC( m_vecOcclusionCheck[i] );
SAFE_DELETE_MAP( m_mapOcclusionCheck[i] );
for( int j=0; j<10; j++ )
SAFE_DELETE_VEC( m_vecRadixSort[i][j] );
}
SAFE_DELETE_PVEC( m_RenderBlockPoolFree );
SAFE_DELETE_PVEC( m_RenderBlockPoolUsed );
}