// Level init, shutdown void CPixelVisibilitySystem::LevelInitPreEntity() { bool fastqueries = HasFastQueries(); // printf("\n ** fast queries: %s **", fastqueries?"true":"false" ); m_hwCanTestGlows = r_dopixelvisibility.GetBool() && fastqueries && engine->GetDXSupportLevel() >= 80; if ( m_hwCanTestGlows ) { CMatRenderContextPtr pRenderContext( materials ); OcclusionQueryObjectHandle_t query = pRenderContext->CreateOcclusionQueryObject(); if ( query != INVALID_OCCLUSION_QUERY_OBJECT_HANDLE ) { pRenderContext->DestroyOcclusionQueryObject( query ); } else { m_hwCanTestGlows = false; } } m_pProxyMaterial = materials->FindMaterial("engine/occlusionproxy", TEXTURE_GROUP_CLIENT_EFFECTS); m_pProxyMaterial->IncrementReferenceCount(); m_pDrawMaterial = materials->FindMaterial("engine/occlusionproxy_countdraw", TEXTURE_GROUP_CLIENT_EFFECTS); m_pDrawMaterial->IncrementReferenceCount(); m_freeQueriesList = m_queryList.CreateList(); m_activeSetsList = m_setList.CreateList(); m_freeSetsList = m_setList.CreateList(); }
unsigned short CPixelVisibilitySystem::FindOrCreateQueryForView( CPixelVisSet *pSet, int viewID ) { unsigned short node = FindQueryForView( pSet, viewID ); if ( node != m_queryList.InvalidIndex() ) return node; node = AllocQuery(); m_queryList.LinkToHead( pSet->queryList, node ); m_queryList[node].SetView( viewID ); return node; }
unsigned short CPixelVisibilitySystem::FindQueryForView( CPixelVisSet *pSet, int viewID ) { unsigned short node = m_queryList.Head( pSet->queryList ); while ( node != m_queryList.InvalidIndex() ) { if ( m_queryList[node].IsForView( viewID ) ) return node; node = m_queryList.Next( node ); } return m_queryList.InvalidIndex(); }
void CPixelVisibilitySystem::LevelShutdownPostEntity() { m_pProxyMaterial->DecrementReferenceCount(); m_pProxyMaterial = NULL; m_pDrawMaterial->DecrementReferenceCount(); m_pDrawMaterial = NULL; DeleteUnusedSets(true); m_setList.Purge(); m_queryList.Purge(); m_freeQueriesList = m_queryList.InvalidIndex(); m_activeSetsList = m_setList.InvalidIndex(); m_freeSetsList = m_setList.InvalidIndex(); }
unsigned short CPixelVisibilitySystem::AllocQuery() { unsigned short node = m_queryList.Head(m_freeQueriesList); if ( node != m_queryList.InvalidIndex() ) { m_queryList.Unlink( m_freeQueriesList, node ); } else { node = m_queryList.Alloc(); } return node; }
void CPixelVisibilitySystem::DeleteUnusedQueries( CPixelVisSet *pSet, bool bDeleteAll ) { unsigned short node = m_queryList.Head( pSet->queryList ); while ( node != m_queryList.InvalidIndex() ) { unsigned short next = m_queryList.Next( node ); if ( bDeleteAll || !m_queryList[node].IsActive() ) { m_queryList.Unlink( pSet->queryList, node); m_queryList.LinkToHead( m_freeQueriesList, node ); } node = next; } }
void CPixelVisibilitySystem::EndView() { if ( !PixelVisibility_IsAvailable() && CurrentViewID() >= 0 ) return; if ( m_setList.Head( m_activeSetsList ) == m_setList.InvalidIndex() ) return; CMatRenderContextPtr pRenderContext( materials ); IMaterial *pProxy = m_drawQueries ? m_pDrawMaterial : m_pProxyMaterial; pRenderContext->Bind( pProxy ); // BUGBUG: If you draw both queries, the measure query fails for some reason. if ( r_pixelvisibility_partial.GetBool() && !m_drawQueries ) { pRenderContext->DepthRange( 0.0f, 0.01f ); unsigned short node = m_setList.Head( m_activeSetsList ); while( node != m_setList.InvalidIndex() ) { CPixelVisSet *pSet = &m_setList[node]; unsigned short queryNode = FindQueryForView( pSet, CurrentViewID() ); if ( queryNode != m_queryList.InvalidIndex() ) { m_queryList[queryNode].IssueCountingQuery( pRenderContext, pSet->proxySize, pSet->proxyAspect, pProxy, pSet->sizeIsScreenSpace ); } node = m_setList.Next( node ); } pRenderContext->DepthRange( 0.0f, 1.0f ); } { unsigned short node = m_setList.Head( m_activeSetsList ); while( node != m_setList.InvalidIndex() ) { CPixelVisSet *pSet = &m_setList[node]; unsigned short queryNode = FindQueryForView( pSet, CurrentViewID() ); if ( queryNode != m_queryList.InvalidIndex() ) { m_queryList[queryNode].IssueQuery( pRenderContext, pSet->proxySize, pSet->proxyAspect, pProxy, pSet->sizeIsScreenSpace ); } node = m_setList.Next( node ); } } }
void CPixelVisibilitySystem::DeleteUnusedSets( bool bDeleteAll ) { unsigned short node = m_setList.Head( m_activeSetsList ); while ( node != m_setList.InvalidIndex() ) { unsigned short next = m_setList.Next( node ); CPixelVisSet *pSet = &m_setList[node]; if ( bDeleteAll || !m_setList[node].IsActive() ) { DeleteUnusedQueries( pSet, true ); } else { DeleteUnusedQueries( pSet, false ); } if ( m_queryList.Head(pSet->queryList) == m_queryList.InvalidIndex() ) { FreeSet( node ); } node = next; } }
// Level init, shutdown void CPixelVisibilitySystem::LevelInitPreEntity() { m_hwCanTestGlows = r_dopixelvisibility.GetBool() && engine->GetDXSupportLevel() >= 80; if ( m_hwCanTestGlows ) { unsigned short query = materials->CreateOcclusionQueryObject(); if ( query != INVALID_OCCLUSION_QUERY_OBJECT_HANDLE ) { materials->DestroyOcclusionQueryObject( query ); } else { m_hwCanTestGlows = false; } } m_pProxyMaterial = materials->FindMaterial("engine/occlusionproxy", TEXTURE_GROUP_CLIENT_EFFECTS); m_pProxyMaterial->IncrementReferenceCount(); m_pDrawMaterial = materials->FindMaterial("engine/occlusionproxy_countdraw", TEXTURE_GROUP_CLIENT_EFFECTS); m_pDrawMaterial->IncrementReferenceCount(); m_freeQueriesList = m_queryList.CreateList(); m_activeSetsList = m_setList.CreateList(); m_freeSetsList = m_setList.CreateList(); }
unsigned short CPixelVisibilitySystem::AllocSet() { unsigned short node = m_setList.Head(m_freeSetsList); if ( node != m_setList.InvalidIndex() ) { m_setList.Unlink( m_freeSetsList, node ); } else { node = m_setList.Alloc(); m_setList[node].queryList = m_queryList.CreateList(); } m_setList.LinkToHead( m_activeSetsList, node ); return node; }
CPixelVisSet *CPixelVisibilitySystem::FindOrCreatePixelVisSet( const pixelvis_queryparams_t ¶ms, pixelvis_handle_t *queryHandle ) { if ( queryHandle[0] ) { unsigned short handle = queryHandle[0] & 0xFFFF; handle--; unsigned short serial = queryHandle[0] >> 16; if ( m_setList.IsValidIndex(handle) && m_setList[handle].serial == serial ) { return &m_setList[handle]; } } unsigned short node = AllocSet(); m_setList[node].Init( params ); unsigned int out = m_setList[node].serial; unsigned short nodeHandle = node + 1; out <<= 16; out |= nodeHandle; queryHandle[0] = out; return &m_setList[node]; }
void CPixelVisibilitySystem::FreeSet( unsigned short node ) { m_setList.Unlink( m_activeSetsList, node ); m_setList.LinkToHead( m_freeSetsList, node ); m_setList[node].serial++; }