void CClientLeafSystem::CollateRenderablesInLeaf( int leaf, int worldListLeafIndex, SetupRenderInfo_t &info ) { bool portalTestEnts = r_PortalTestEnts.GetBool() && !r_portalsopenall.GetBool(); // Collate everything. unsigned short idx = m_RenderablesInLeaf.FirstElement(leaf); for ( ;idx != m_RenderablesInLeaf.InvalidIndex(); idx = m_RenderablesInLeaf.NextElement(idx) ) { ClientRenderHandle_t handle = m_RenderablesInLeaf.Element(idx); RenderableInfo_t& renderable = m_Renderables[handle]; // Early out on static props if we don't want to render them if ((!m_DrawStaticProps) && (renderable.m_Flags & RENDER_FLAGS_STATIC_PROP)) continue; // Early out if we're told to not draw small objects (top view only, /* that's why we don't check the z component). if (!m_DrawSmallObjects) { CCachedRenderInfo& cachedInfo = m_CachedRenderInfos[renderable.m_CachedRenderInfo]; float sizeX = cachedInfo.m_Maxs.x - cachedInfo.m_Mins.x; float sizeY = cachedInfo.m_Maxs.y - cachedInfo.m_Mins.y; if ((sizeX < 50.f) && (sizeY < 50.f)) continue; }*/ Assert( m_DrawSmallObjects ); // MOTODO // Don't hit the same ent in multiple leaves twice. if ( renderable.m_RenderGroup != RENDER_GROUP_TRANSLUCENT_ENTITY ) { if ( renderable.m_RenderFrame2 == info.m_nRenderFrame ) continue; renderable.m_RenderFrame2 = info.m_nRenderFrame; } else { // Translucent entities already have had ComputeTranslucentRenderLeaf called on them // so m_RenderLeaf should be set to the nearest leaf, so that's what we want here. if ( renderable.m_RenderLeaf != leaf ) continue; } // Prevent culling if the renderable is invisible // NOTE: OPAQUE objects can have alpha == 0. // They are made to be opaque because they don't have to be sorted. unsigned char nAlpha = renderable.m_pRenderable->GetFxBlend(); if ( nAlpha == 0 ) continue; Vector absMins, absMaxs; CalcRenderableWorldSpaceAABB( renderable.m_pRenderable, absMins, absMaxs ); // If the renderable is inside an area, cull it using the frustum for that area. if ( portalTestEnts && renderable.m_Area != -1 ) { VPROF( "r_PortalTestEnts" ); if ( !engine->DoesBoxTouchAreaFrustum( absMins, absMaxs, renderable.m_Area ) ) continue; } else { // cull with main frustum if ( engine->CullBox( absMins, absMaxs ) ) continue; } // UNDONE: Investigate speed tradeoffs of occlusion culling brush models too? if ( renderable.m_Flags & RENDER_FLAGS_STUDIO_MODEL ) { // test to see if this renderable is occluded by the engine's occlusion system if ( engine->IsOccluded( absMins, absMaxs ) ) continue; } if( renderable.m_RenderGroup != RENDER_GROUP_TRANSLUCENT_ENTITY ) { RenderGroup_t group = (RenderGroup_t)renderable.m_RenderGroup; AddRenderableToRenderList( *info.m_pRenderList, renderable.m_pRenderable, worldListLeafIndex, group, handle); } else { bool bTwoPass = ((renderable.m_Flags & RENDER_FLAGS_TWOPASS) != 0) && ( nAlpha == 255 ); AddRenderableToRenderList( *info.m_pRenderList, renderable.m_pRenderable, worldListLeafIndex, (RenderGroup_t)renderable.m_RenderGroup, handle, bTwoPass ); // Add to both lists if it's a two-pass model... if (bTwoPass) { AddRenderableToRenderList( *info.m_pRenderList, renderable.m_pRenderable, worldListLeafIndex, RENDER_GROUP_OPAQUE_ENTITY, handle, bTwoPass ); } } } // Do detail objects. // These don't have render handles! if ( IsPC() && info.m_bDrawDetailObjects && ShouldDrawDetailObjectsInLeaf( leaf, info.m_nDetailBuildFrame ) ) { idx = m_Leaf[leaf].m_FirstDetailProp; int count = m_Leaf[leaf].m_DetailPropCount; while( --count >= 0 ) { IClientRenderable* pRenderable = DetailObjectSystem()->GetDetailModel(idx); // FIXME: This if check here is necessary because the detail object system also maintains // lists of sprites... if (pRenderable) { if( pRenderable->IsTransparent() ) { // Lots of the detail entities are invsible so avoid sorting them and all that. if( pRenderable->GetFxBlend() > 0 ) { AddRenderableToRenderList( *info.m_pRenderList, pRenderable, worldListLeafIndex, RENDER_GROUP_TRANSLUCENT_ENTITY, DETAIL_PROP_RENDER_HANDLE ); } } else { AddRenderableToRenderList( *info.m_pRenderList, pRenderable, worldListLeafIndex, RENDER_GROUP_OPAQUE_ENTITY, DETAIL_PROP_RENDER_HANDLE ); } } ++idx; } } }