void VTerrainDecorationEntityModel::RenderBatchIR(VTerrainVisibilityCollectorComponent *pInfoComp, VTerrainDecorationInstance **pInstList, int iCount, RenderMode_e eRenderMode) { // IR Rendering VTerrainDecorationModelManager* pManager = (VTerrainDecorationModelManager *)GetParentManager(); VShaderEffectLib* pEffectLib = pManager->GetInfraredShaderLib(); if (iCount > 0 && pManager->m_iInstancingBatchCount > 0 && pEffectLib != NULL) { int iMaxInstanceCount, iInstanceStreamMask; VisSurface_cl* pSurface = m_spMesh->GetSurface(0); if (m_spInstancingTechIRPrePass == NULL) { // lazy IR shader init RecreateIRShaders(pSurface, pEffectLib); } if (m_spInstancingTechIRPrePass == NULL || m_spInstancingTechIRMainPass == NULL) return; const int iPrimitiveCount = m_spModelMesh->GetCurrentPrimitiveCount(); const int iVertexCount = m_spModelMesh->GetVertexCount(); const VisMeshBuffer_cl::MB_PrimitiveType_e ePrimType = m_spModelMesh->GetPrimitiveType(); bool bPrePass = (eRenderMode == RENDER_MODE_IR_PREPASS); VCompiledShaderPass* pShader = bPrePass? m_spInstancingTechIRPrePass->GetShader(0) : m_spInstancingTechIRMainPass->GetShader(0); const int iStreamMask = m_spModelMesh->GetStreamMask() & (pShader->GetStreamMask() | VERTEX_STREAM_INDEXBUFFER); VisMeshBuffer_cl* pInstanceMesh = pManager->GetInstanceBuffer(iMaxInstanceCount, iInstanceStreamMask); iInstanceStreamMask &= pShader->GetStreamMask(); // perform the rendering Vision::RenderLoopHelper.BeginMeshRendering(); Vision::RenderLoopHelper.BindDefaultStateGroups(pSurface, pShader); if (!bPrePass || pSurface->GetTransparencyType() != VIS_TRANSP_NONE) Vision::RenderLoopHelper.BindMeshTexture(pSurface->GetBaseTextureObject(), 0, NULL); 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, iStreamMask); } Vision::RenderLoopHelper.EndMeshRendering(); } }
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(); } }
void VTerrainDecorationEntityModel::RenderBatchDepthShadow(VTerrainVisibilityCollectorComponent *pInfoComp, VTerrainDecorationInstance **pInstList, int iCount) { // depth shader rendering INSERT_PERF_MARKER_SCOPE("VTerrainDecorationEntityModel::RenderBatchDepthShadow"); VTerrainDecorationModelManager *pManager = (VTerrainDecorationModelManager *)GetParentManager(); if (m_spInstancingTechShadow!=NULL && iCount>4 && pManager->m_iInstancingBatchCount>0 /* && bAllowInstancing*/) { VCompiledShaderPass *pShader = m_spInstancingTechShadow->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); 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(); } else { // non-instancing version VisDrawCallInfo_t surfaceShaderList[RLP_MAX_ENTITY_SURFACESHADERS]; const int iNumSubmeshes = m_spMesh->GetSubmeshCount(); int iAsmCount = 0; for (int i=0;i<iNumSubmeshes;i++) { VDynamicSubmesh *pSubmesh = m_spMesh->GetSubmesh(i); VisDrawCallInfo_t &assignment(surfaceShaderList[iAsmCount]); if (pSubmesh->GetSurface()->m_spShadowmapFill==NULL) continue; assignment.Set(pSubmesh, pSubmesh->GetSurface(), pSubmesh->GetSurface()->m_spShadowmapFill->GetShader(0)); iAsmCount++; } Vision::RenderLoopHelper.BeginEntityRendering(); for (int i=0;i<iCount;i++) { hkvMat4 transform(pInstList[i]->m_Orientation,pInstList[i]->m_vPosition); Vision::RenderLoopHelper.RenderModelWithSurfaceShaderList(m_spMesh, transform.getPointer (),iAsmCount,surfaceShaderList); } Vision::RenderLoopHelper.EndEntityRendering(); } }