void MirrorRenderLoop_cl::DrawStaticGeometry(const VisStaticGeometryInstanceCollection_cl &collection, int iPassType) { INSERT_PERF_MARKER_SCOPE("MirrorRenderLoop_cl::DrawStaticGeometry"); m_CustomGeoInstances.Clear(); int iNumGI = collection.GetNumEntries(); VCompiledShaderPass *pCurrentPass = NULL; for (int i=0; i<iNumGI; i++) { VisStaticGeometryInstance_cl *pGI = collection.GetEntry(i); if ( pGI->GetGeometryType() == STATIC_GEOMETRY_TYPE_TERRAIN ) ((VTerrainSector*)pGI)->EnsureLoaded(); VCompiledShaderPass *pPass = GetMirrorShader (pGI->GetSurface (), m_pMirror->m_eReflectionShaderMode); if (pPass != pCurrentPass) { if (m_CustomGeoInstances.GetNumEntries() > 0) { VASSERT(pCurrentPass != NULL); Vision::RenderLoopHelper.RenderStaticGeometryWithShader(m_CustomGeoInstances, *pCurrentPass); // can use simplified lightmap shader m_CustomGeoInstances.Clear(); } pCurrentPass = pPass; } m_CustomGeoInstances.AppendEntry(pGI); } // Render remaining instances if (m_CustomGeoInstances.GetNumEntries() > 0 && pCurrentPass != NULL) Vision::RenderLoopHelper.RenderStaticGeometryWithShader(m_CustomGeoInstances, *pCurrentPass); // can use simplified lightmap shader }
// renders visible wallmarks of specified pass type (pre or post, which is relevant in deferred context) void VWallmarkManager::RenderProjectedWallmarks(VPassType_e ePassType) { INSERT_PERF_MARKER_SCOPE("Wallmark Rendering (VWallmarkManager::RenderProjectedWallmarks)"); const int iWallmarkCount = m_AllProjectedWallmarks.Count(); IVisVisibilityCollector_cl *pVisCollector = Vision::Contexts.GetCurrentContext()->GetVisibilityCollector(); if (!pVisCollector || !iWallmarkCount) return; const VisStaticGeometryInstanceCollection_cl *pGeoInstances = pVisCollector->GetVisibleStaticGeometryInstances(); VisStaticGeometryInstance_cl::ResetTags(); pGeoInstances->TagEntries(); VisStaticGeometryInstanceCollection_cl &targetGiCollection = m_TempGeoInstanceCollection; VisRenderContext_cl *pContext = Vision::Contexts.GetCurrentContext(); VisRenderContext_cl *pLODContext = pContext->GetLODReferenceContext(); hkvVec3 vLODPos = pLODContext ? pLODContext->GetCamera()->GetPosition() : pContext->GetCamera()->GetPosition(); unsigned int iContextFilter = pContext->GetRenderFilterMask(); const VisFrustum_cl *pFrustum = pVisCollector->GetBaseFrustum(); int i; for (i=0;i<iWallmarkCount;i++) { VProjectedWallmark *pProjWallmark = m_AllProjectedWallmarks.GetAt(i); if ((pProjWallmark->GetVisibleBitmask() & iContextFilter)==0 || (ePassType & pProjWallmark->m_ePassType) == 0) continue; pProjWallmark->PrepareForRendering(); const VisStaticGeometryInstanceCollection_cl &wmGiList = pProjWallmark->GetStaticGeometryCollection(); #ifdef HK_DEBUG const int iNum = wmGiList.GetNumEntries(); for (int j=0;j<iNum;j++) { VisStaticGeometryInstance_cl *pInst = wmGiList.GetEntry(j); VASSERT_MSG(pInst && (pInst->GetGeometryType()==STATIC_GEOMETRY_TYPE_MESHINSTANCE || pInst->GetGeometryType()==STATIC_GEOMETRY_TYPE_TERRAIN), "The wallmark conains invalid primitive references") } #endif // clip against its bounding box (primitive visibility might overestimate visible parts) const hkvAlignedBBox &bbox = pProjWallmark->GetBoundingBox(); if (pProjWallmark->m_fFarClipDistance>0.f && pProjWallmark->m_fFarClipDistance<bbox.getDistanceTo(vLODPos)) continue; if (pFrustum && !pFrustum->Overlaps(bbox)) continue; const int iGeomFilter = pProjWallmark->GetGeometryTypeFilterMask(); if (iGeomFilter&PROJECTOR_AFFECTS_STATICMESHES) { // standard geometry targetGiCollection.Clear(); wmGiList.GetTaggedEntriesOfType(targetGiCollection,STATIC_GEOMETRY_TYPE_MESHINSTANCE); if (targetGiCollection.GetNumEntries()) { // render the static geometry instances using lightmapped or non-lightmapped shader VProjectorShaderPass *pShader = GetWallmarkShader(pProjWallmark,STATIC_GEOMETRY_TYPE_MESHINSTANCE); Vision::RenderLoopHelper.RenderStaticGeometryWithShader(targetGiCollection, *pShader); } } if (iGeomFilter&PROJECTOR_AFFECTS_TERRAIN) { // terrain geometry (different shader) targetGiCollection.Clear(); wmGiList.GetTaggedEntriesOfType(targetGiCollection,STATIC_GEOMETRY_TYPE_TERRAIN); if (targetGiCollection.GetNumEntries()>0) { // render the static geometry instances using lightmapped or non-lightmapped shader VProjectorShaderPass *pShader = GetWallmarkShader(pProjWallmark,STATIC_GEOMETRY_TYPE_TERRAIN); if (pShader) Vision::RenderLoopHelper.RenderStaticGeometryWithShader(targetGiCollection, *pShader); } } // entities if (iGeomFilter&PROJECTOR_AFFECTS_ENTITIES) { const VisEntityCollection_cl *pVisibleEntities = pVisCollector->GetVisibleEntities(); const unsigned int iInfluenceMask = pProjWallmark->GetInfluenceBitmask(); m_TempEntityCollection.Clear(); const int iEntCount = pVisibleEntities->GetNumEntries(); for (int j=0;j<iEntCount;j++) { VisBaseEntity_cl *pEntity = pVisibleEntities->GetEntry(j); if (pEntity==NULL || (pEntity->GetVisibleBitmask()&iInfluenceMask)==0) continue; const hkvAlignedBBox &entityBox(*pEntity->GetCurrentVisBoundingBoxPtr()); if (!entityBox.overlaps(bbox)) continue; m_TempEntityCollection.AppendEntry(pEntity); } if (m_TempEntityCollection.GetNumEntries()>0) { VProjectorShaderPass *pShader = GetWallmarkShader(pProjWallmark,STATIC_GEOMETRY_TYPE_MESHINSTANCE); // we can use this shader - VS skinning is used implicitly Vision::RenderLoopHelper.RenderEntitiesWithShader(m_TempEntityCollection, *pShader); } } } }