// ---------------------------------------------------------------------------- void vHavokChainConstraintChainRenderer::DrawEntity(VPassType_e ePassType) { // Code copied from VisionRenderLoop_cl::DrawEntitiesShaders() if (!m_spChainEntity->HasShadersForPass(ePassType)) return; VisDrawCallInfo_t SurfaceShaderList[RLP_MAX_ENTITY_SURFACESHADERS]; // Get a list of the corresponding pass type shader set VisShaderSet_cl *pShaderSet = m_spChainEntity->GetActiveShaderSet(); if (pShaderSet == NULL) return; int iNumSurfaceShaders = pShaderSet->GetShaderAssignmentList(SurfaceShaderList, ePassType, RLP_MAX_ENTITY_SURFACESHADERS); VASSERT(iNumSurfaceShaders < RLP_MAX_ENTITY_SURFACESHADERS); if (iNumSurfaceShaders == 0) return; // If the model has lit surfaces, and if the shaders makes use of the lighting information, we need to set up // the global lights. if (m_spChainMesh->HasLitSurfaces()) { if(pShaderSet->GetCombinedTrackingMask() & (VSHADER_TRACKING_LIGHTGRID_PS|VSHADER_TRACKING_LIGHTGRID_GS|VSHADER_TRACKING_LIGHTGRID_VS)) { Vision::RenderLoopHelper.TrackLightGridInfo(m_spChainEntity); } } // Render the entity with the surface shader list Vision::RenderLoopHelper.RenderEntityWithSurfaceShaderList(m_spChainEntity, iNumSurfaceShaders, SurfaceShaderList); }
// Render shaders on entities void VPostProcessTranslucencies::DrawEntitiesShaders(const VisEntityCollection_cl &EntityCollection, VPassType_e ePassType) { VisDrawCallInfo_t SurfaceShaderList[RLP_MAX_ENTITY_SURFACESHADERS]; unsigned int iNumEntities = EntityCollection.GetNumEntries(); unsigned int i; Vision::RenderLoopHelper.BeginEntityRendering(); for (i=0; i<iNumEntities; i++) { VisBaseEntity_cl *pEntity = EntityCollection.GetEntry(i); // Foreground entities will be handled separately if (pEntity->IsObjectAlwaysInForegroundEnabled()) continue; if ( pEntity->HasShadersForPass(ePassType) ) { // Get a list of the corresponding pass type surface shaders VisShaderSet_cl *pShaderSet = pEntity->GetActiveShaderSet(); if (pShaderSet == NULL) continue; int iNumSurfaceShaders = pShaderSet->GetShaderAssignmentList(SurfaceShaderList, ePassType, RLP_MAX_ENTITY_SURFACESHADERS); VASSERT(iNumSurfaceShaders < RLP_MAX_ENTITY_SURFACESHADERS); if (iNumSurfaceShaders == 0) continue; VDynamicMesh *pMesh = pEntity->GetMesh(); // If the model has lit surfaces, and if the shaders makes use of the lighting information, we need to set up // the global lights. if (pMesh != NULL && pMesh->HasLitSurfaces() && (pShaderSet->GetCombinedTrackingMask()&(VSHADER_TRACKING_LIGHTGRID_PS|VSHADER_TRACKING_LIGHTGRID_GS|VSHADER_TRACKING_LIGHTGRID_VS)) ) { Vision::RenderLoopHelper.TrackLightGridInfo(pEntity); } // Render the entity with the surface shader list Vision::RenderLoopHelper.RenderEntityWithSurfaceShaderList(pEntity, iNumSurfaceShaders, SurfaceShaderList); } } Vision::RenderLoopHelper.EndEntityRendering(); }
void VTerrainDecorationEntityModel::RenderBatchOTW(VTerrainVisibilityCollectorComponent *pInfoComp, VTerrainDecorationInstance **pInstList, int iCount) { // OTW rendering VTerrainDecorationModelManager *pManager = (VTerrainDecorationModelManager *)GetParentManager(); if (m_spInstancingTech!=NULL && iCount>4 && pManager->m_iInstancingBatchCount>0 /* && bAllowInstancing*/) { VCompiledShaderPass *pShader = m_spInstancingTech->GetShader(0); Vision::RenderLoopHelper.BeginMeshRendering(); VisSurface_cl *pSurface = m_spMesh->GetSurface(0); Vision::RenderLoopHelper.BindSurfaceTextures(pSurface,pShader,NULL); Vision::RenderLoopHelper.BindDefaultStateGroups(pSurface,pShader); VisMeshBuffer_cl::MB_PrimitiveType_e ePrimType = m_spModelMesh->GetPrimitiveType(); int iPrimitiveCount = m_spModelMesh->GetCurrentPrimitiveCount(); int iVertexCount = m_spModelMesh->GetVertexCount(); int iMaxInstanceCount, iInstanceStreamMask; VisMeshBuffer_cl *pInstanceMesh = ((VTerrainDecorationModelManager *)GetParentManager())->GetInstanceBuffer(iMaxInstanceCount,iInstanceStreamMask); // lightmap version if (m_iLightmapSampler>=0 && pInfoComp!=NULL) { #ifdef HK_DEBUG const VStateGroupTexture *pStateGroupTexture = pShader->GetStateGroupTexture(VSS_PixelShader, m_iLightmapSampler); VASSERT(pStateGroupTexture!=NULL && pStateGroupTexture->m_cTextureType==TEXTURETYPE_LIGHTMAP); #endif VStateGroupSampler *pLMSampler = pShader->GetStateGroupSampler(VSS_PixelShader, m_iLightmapSampler); VTerrainSector *pLastSector = NULL; VTextureObject *pTerrainLightmap = NULL; const VTerrainConfig& config(pInfoComp->m_pTerrain->m_Config); VTerrainSectorManager §ormanager(pInfoComp->m_pTerrain->m_SectorManager); while (iCount>0) { int iWantedRenderCount = hkvMath::Min(iCount,iMaxInstanceCount); int iRenderCount = 0; // fill the instance buffer: { VISION_PROFILE_FUNCTION(VTerrainSectorManager::PROFILING_RENDERDECORARION_INSTANCE_SETUP); VModelInstanceData_t *pDest = (VModelInstanceData_t *)pInstanceMesh->LockVertices(VIS_LOCKFLAG_DISCARDABLE,0,iWantedRenderCount); // fill buffer up to lightmap change for (int i=0;i<iWantedRenderCount;i++,iRenderCount++,pDest++) { if (pLastSector!=pInstList[i]->m_pOwnerSector) { pLastSector = pInstList[i]->m_pOwnerSector; VTextureObject *pNewLightmap = pLastSector->m_pMeshPage[0].GetSurfaceSafe().m_spModelLightmaps[0]; if (pNewLightmap!=pTerrainLightmap) { if (iRenderCount>0) // start a new batch so break here break; } } pDest->Set(*pInstList[i]); } pInstanceMesh->UnLockVertices(); } // bind sector specific properties VTerrainSector *pStateSetupSector = pInstList[0]->m_pOwnerSector; // this is where the batch starts hkvVec4 vWorld2Sector(false); // transforms worldspace to sector 0..1 range config.GetWorldSpaceToSectorTransform(pStateSetupSector->m_iIndexX,pStateSetupSector->m_iIndexY,vWorld2Sector); sectormanager.SetWorld2SectorTransform(vWorld2Sector); // standard range -> lightmap const hkvVec4 vSector2LM = pStateSetupSector->GetLightmapScaleOffset(); VisRenderStates_cl::VSSetModelUVToLightmap(vSector2LM.data); Vision::RenderLoopHelper.BindMeshTexture(pStateSetupSector->m_pMeshPage[0].GetSurfaceSafe().m_spModelLightmaps[0],m_iLightmapSampler,pLMSampler); // advance by actual render counts pInstList += iRenderCount; iCount-=iRenderCount; RENDER_INSTANCES(iRenderCount, m_iModelStreams); } } else // non-lightmapped version { while (iCount>0) { int iRenderCount = hkvMath::Min(iCount,iMaxInstanceCount); // fill the instance buffer: { VISION_PROFILE_FUNCTION(VTerrainSectorManager::PROFILING_RENDERDECORARION_INSTANCE_SETUP); VModelInstanceData_t *pDest = (VModelInstanceData_t *)pInstanceMesh->LockVertices(VIS_LOCKFLAG_DISCARDABLE,0,iRenderCount); for (int i=0;i<iRenderCount;i++,pInstList++,pDest++) pDest->Set(*pInstList[0]); pInstanceMesh->UnLockVertices(); } iCount-=iRenderCount; RENDER_INSTANCES(iRenderCount, m_iModelStreams); } } Vision::RenderLoopHelper.EndMeshRendering(); return; } ////////////////////////////////////////////////////////// // Non-instancing version const VisDrawCallInfo_t *pSurfaceShaderList; VDynamicMesh *pMesh = m_spMesh; VASSERT(m_spVegetationShaders!=NULL); VisShaderSet_cl *pSet = m_spVegetationShaders; int iAsmCount = pSet->GetShaderAssignmentList(&pSurfaceShaderList); VColorRef iLastColor; #ifdef _VR_DX11 VisRenderStates_cl::SetVSConstantBuffer(7,&m_PerInstanceData); #endif if (m_bNeedsLightmap && pInfoComp!=NULL) { VTerrainSector *pLastSector = NULL; VTextureObject *pTerrainLightmap = NULL; const VTerrainConfig& config(pInfoComp->m_pTerrain->m_Config); VTerrainSectorManager §ormanager(pInfoComp->m_pTerrain->m_SectorManager); Vision::RenderLoopHelper.BeginEntityRendering(); for (int i=0;i<iCount;i++,pInstList++) { if (pLastSector!=(*pInstList)->m_pOwnerSector) { pLastSector = (*pInstList)->m_pOwnerSector; VTextureObject *pNewLightmap = pLastSector->m_pMeshPage[0].GetSurfaceSafe().m_spModelLightmaps[0]; if (pNewLightmap!=pTerrainLightmap) { // assign new model lightmaps const int iSrfCount = m_spMesh->GetSurfaceCount(); for (int j=0;j<iSrfCount;j++) m_spMesh->GetSurface(j)->m_spModelLightmaps[0] = pNewLightmap; // and also force a shader re-binding for (int j=0;j<iAsmCount;j++) pSurfaceShaderList[j].GetShader()->m_bModified=true; pTerrainLightmap = pNewLightmap; } hkvVec4 vWorld2Sector(false); // transforms worldspace to sector 0..1 range config.GetWorldSpaceToSectorTransform(pLastSector->m_iIndexX,pLastSector->m_iIndexY,vWorld2Sector); sectormanager.SetWorld2SectorTransform(vWorld2Sector); // standard range -> lightmap const hkvVec4 vSector2LM = pLastSector->GetLightmapScaleOffset(); VisRenderStates_cl::VSSetModelUVToLightmap(vSector2LM.data); } // per instance tint color if (i==0 || iLastColor!=(*pInstList)->m_InstanceColor) { iLastColor = (*pInstList)->m_InstanceColor; VPerInstanceData_t &data(m_PerInstanceData.BeginUpdate()); VColorRef::RGBA_To_Float((*pInstList)->m_InstanceColor, data.vPerInstanceColor); m_PerInstanceData.EndUpdate(); #ifndef _VR_DX11 VisRenderStates_cl::SetVSConstantBuffer(7,&m_PerInstanceData); #endif } // finally render object hkvMat4 transform((*pInstList)->m_Orientation,(*pInstList)->m_vPosition); Vision::RenderLoopHelper.RenderModelWithSurfaceShaderList(m_spMesh,transform.getPointer (),iAsmCount,pSurfaceShaderList); } VisRenderStates_cl::SetVSConstantBuffer(7,NULL); Vision::RenderLoopHelper.EndEntityRendering(); } else { Vision::RenderLoopHelper.BeginEntityRendering(); // no lightmaps -> simple loop for (int i=0;i<iCount;i++,pInstList++) { // per instance tint color if (i==0 || iLastColor!=(*pInstList)->m_InstanceColor) { iLastColor = (*pInstList)->m_InstanceColor; VPerInstanceData_t &data(m_PerInstanceData.BeginUpdate()); VColorRef::RGBA_To_Float((*pInstList)->m_InstanceColor, data.vPerInstanceColor); m_PerInstanceData.EndUpdate(); #ifndef _VR_DX11 VisRenderStates_cl::SetVSConstantBuffer(7,&m_PerInstanceData); #endif } hkvMat4 transform((*pInstList)->m_Orientation,(*pInstList)->m_vPosition); Vision::RenderLoopHelper.RenderModelWithSurfaceShaderList(m_spMesh,transform.getPointer(),iAsmCount,pSurfaceShaderList); } VisRenderStates_cl::SetVSConstantBuffer(7,NULL); Vision::RenderLoopHelper.EndEntityRendering(); } }
// Renders foreground entities (i.e. entities which have been flagged as "always in foreground") void VPostProcessTranslucencies::DrawTransparentForegroundEntities(const VisEntityCollection_cl &EntityCollection) { unsigned int iNumEntities = EntityCollection.GetNumEntries(); // this collection only contains foreground objects if (iNumEntities==0 || m_spForegroundFillPassTechnique==NULL) return; INSERT_PERF_MARKER_SCOPE("VisionRenderLoop_cl::DrawForegroundEntities"); unsigned int i; const hkvMat4* pLastProj = NULL; Vision::RenderLoopHelper.BeginEntityRendering(); const int iPassCount = m_spForegroundFillPassTechnique->GetShaderCount(); for (int iPass=0;iPass<=iPassCount;iPass++) // +1 passes, where the last one is the actual material pass { for (i=0; i<iNumEntities; i++) { VisBaseEntity_cl *pEntity = EntityCollection.GetEntry(i); // Render only Entities that are flagged as "always in foreground" VASSERT_MSG(pEntity->IsObjectAlwaysInForegroundEnabled(), "Only entities with this flag should be passed to this function"); if (pEntity->HasShadersForPass(VPT_TransparentPass)) { VDynamicMesh *pMesh = pEntity->GetMesh(); VisShaderSet_cl *pShaderSet = pEntity->GetActiveShaderSet(); VASSERT(pMesh && pShaderSet); const hkvMat4* pThisProj = pEntity->GetCustomProjectionMatrixForForegroundObject(); if (pThisProj != pLastProj) { VisRenderStates_cl::SetCurrentProjectionMatrix(pThisProj); pLastProj = pThisProj; } if (iPass<iPassCount) // depth fill pass { VCompiledShaderPass *pPass = m_spForegroundFillPassTechnique->GetShader(iPass); Vision::RenderLoopHelper.RenderEntityWithShaders(pEntity, 1, &pPass); } else // material pass { const VisDrawCallInfo_t *pAssignment; int iNumSurfaceShaders = pShaderSet->GetShaderAssignmentList(&pAssignment); // If the shaders make use of the lighting information, we need to track the light grid if (pMesh != NULL && pMesh->HasLitSurfaces() && (pShaderSet->GetCombinedTrackingMask() & (VSHADER_TRACKING_LIGHTGRID_PS|VSHADER_TRACKING_LIGHTGRID_GS|VSHADER_TRACKING_LIGHTGRID_VS)) ) { Vision::RenderLoopHelper.TrackLightGridInfo(pEntity); } // Render the entity with the surface shader list Vision::RenderLoopHelper.RenderEntityWithSurfaceShaderList(pEntity, iNumSurfaceShaders, pAssignment); } } } } Vision::RenderLoopHelper.EndEntityRendering(); // reset to context projection matrix if (pLastProj) { VisRenderStates_cl::SetCurrentProjectionMatrix(NULL); } }