private static void DrawVoxels(MyLodTypeEnum lod, MyVoxelCacheCellRenderBatchType batchType, ref int ibChangesStats) { int index = m_sortedElements.GetVoxelIndex(lod, batchType); var matDict = m_sortedElements.Voxels[index]; if (matDict.RenderElementCount == 0) return; // Technique start var shader = GetShader(MyMeshDrawTechnique.VOXEL_MAP); SetupShaderPerDraw(shader, MyMeshDrawTechnique.VOXEL_MAP); BeginShaderAlternative(shader, MyMeshDrawTechnique.VOXEL_MAP, batchType); shader.Begin(); MyPerformanceCounter.PerCameraDraw.TechniqueChanges[(int)lod]++; foreach (var mat in matDict.Voxels) { var firstElement = mat.Value.FirstOrDefault(); if (firstElement == null) continue; // Setup material SetupShaderForMaterialAlternative(shader, batchType, firstElement.VoxelBatch.Material0, firstElement.VoxelBatch.Material1, firstElement.VoxelBatch.Material2); MyPerformanceCounter.PerCameraDraw.MaterialChanges[(int)lod]++; MyEntity lastEntity = null; VertexBuffer lastVertexBuffer = null; foreach (var renderElement in mat.Value) { if (!object.ReferenceEquals(lastVertexBuffer, renderElement.VertexBuffer)) { lastVertexBuffer = renderElement.VertexBuffer; m_device.Indices = renderElement.IndexBuffer; m_device.SetStreamSource(0, renderElement.VertexBuffer, 0, renderElement.VertexStride); m_device.VertexDeclaration = renderElement.VertexDeclaration; MyPerformanceCounter.PerCameraDraw.VertexBufferChanges[(int)lod]++; ibChangesStats++; } if (lastEntity != renderElement.Entity) { lastEntity = renderElement.Entity; MyPerformanceCounter.PerCameraDraw.EntityChanges[(int)lod]++; SetupShaderForEntity(shader, renderElement); shader.D3DEffect.CommitChanges(); } m_renderProfiler.StartProfilingBlock("DrawIndexedPrimitives"); m_device.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, renderElement.VertexCount, renderElement.IndexStart, renderElement.TriCount); MyPerformanceCounter.PerCameraDraw.TotalDrawCalls++; m_renderProfiler.EndProfilingBlock(); } } shader.End(); // Technique End }
static void SetupShaderForMaterialAlternative(MyEffectBase shader, MyVoxelCacheCellRenderBatchType batchType, MyMwcVoxelMaterialsEnum m0, MyMwcVoxelMaterialsEnum?m1, MyMwcVoxelMaterialsEnum?m2) { MyEffectVoxels effectVoxels = shader as MyEffectVoxels; if (batchType == MyVoxelCacheCellRenderBatchType.SINGLE_MATERIAL) { effectVoxels.UpdateVoxelTextures(OverrideVoxelMaterial ?? m0); } else if (batchType == MyVoxelCacheCellRenderBatchType.MULTI_MATERIAL) { effectVoxels.UpdateVoxelMultiTextures(OverrideVoxelMaterial ?? m0, OverrideVoxelMaterial ?? m1, OverrideVoxelMaterial ?? m2); } }
public int GetVoxelIndex(MyLodTypeEnum lod, MyVoxelCacheCellRenderBatchType technique) { return ((byte)lod * VoxelTechniqueCount) + (int)technique; }
static void BeginShaderAlternative(MyEffectBase shader, MyMeshDrawTechnique technique, MyVoxelCacheCellRenderBatchType batchType) { switch (technique) { case MyMeshDrawTechnique.DECAL: { if (shader is MyEffectModelsDNS) { (shader as MyEffectModelsDNS).BeginBlended(); } } break; case MyMeshDrawTechnique.HOLO: { if (m_currentLodDrawPass != MyLodTypeEnum.LOD_NEAR && !MyRenderConstants.RenderQualityProfile.ForwardRender) { (shader as MyEffectModelsDNS).ApplyHolo(false); } else { (shader as MyEffectModelsDNS).ApplyHolo(true); } } break; case MyMeshDrawTechnique.ALPHA_MASKED: { (shader as MyEffectModelsDNS).ApplyMasked(); } break; case MyMeshDrawTechnique.VOXEL_MAP: { MyEffectVoxels effectVoxels = shader as MyEffectVoxels; if (batchType == MyVoxelCacheCellRenderBatchType.SINGLE_MATERIAL) { effectVoxels.Apply(); } else if (batchType == MyVoxelCacheCellRenderBatchType.MULTI_MATERIAL) { effectVoxels.ApplyMultimaterial(); } break; } case MyMeshDrawTechnique.VOXELS_STATIC_ASTEROID: { ((MyEffectVoxelsStaticAsteroid)shader).Apply(); } break; case MyMeshDrawTechnique.MESH: { ((MyEffectModelsDNS)shader).SetTechnique(MyRenderConstants.RenderQualityProfile.ModelsRenderTechnique); } break; case MyMeshDrawTechnique.VOXELS_DEBRIS: { ((MyEffectVoxelsDebris)shader).SetTechnique(MyRenderConstants.RenderQualityProfile.VoxelsRenderTechnique); } break; default: { System.Diagnostics.Debug.Assert(false); } break; } }
static void SetupShaderForMaterialAlternative(MyEffectBase shader, MyVoxelCacheCellRenderBatchType batchType, MyMwcVoxelMaterialsEnum m0, MyMwcVoxelMaterialsEnum? m1, MyMwcVoxelMaterialsEnum? m2) { MyEffectVoxels effectVoxels = shader as MyEffectVoxels; if (batchType == MyVoxelCacheCellRenderBatchType.SINGLE_MATERIAL) { effectVoxels.UpdateVoxelTextures(OverrideVoxelMaterial ?? m0); } else if (batchType == MyVoxelCacheCellRenderBatchType.MULTI_MATERIAL) { effectVoxels.UpdateVoxelMultiTextures(OverrideVoxelMaterial ?? m0, OverrideVoxelMaterial ?? m1, OverrideVoxelMaterial ?? m2); } }
private static void DrawVoxels(MyLodTypeEnum lod, MyVoxelCacheCellRenderBatchType batchType, ref int ibChangesStats) { int index = m_sortedElements.GetVoxelIndex(lod, batchType); var matDict = m_sortedElements.Voxels[index]; if (matDict.RenderElementCount == 0) { return; } // Technique start var shader = GetShader(MyMeshDrawTechnique.VOXEL_MAP); SetupShaderPerDraw(shader, MyMeshDrawTechnique.VOXEL_MAP); BeginShaderAlternative(shader, MyMeshDrawTechnique.VOXEL_MAP, batchType); shader.Begin(); MyPerformanceCounter.PerCameraDraw.TechniqueChanges[(int)lod]++; foreach (var mat in matDict.Voxels) { var firstElement = mat.Value.FirstOrDefault(); if (firstElement == null) { continue; } // Setup material SetupShaderForMaterialAlternative(shader, batchType, firstElement.VoxelBatch.Material0, firstElement.VoxelBatch.Material1, firstElement.VoxelBatch.Material2); MyPerformanceCounter.PerCameraDraw.MaterialChanges[(int)lod]++; MyEntity lastEntity = null; VertexBuffer lastVertexBuffer = null; foreach (var renderElement in mat.Value) { if (!object.ReferenceEquals(lastVertexBuffer, renderElement.VertexBuffer)) { lastVertexBuffer = renderElement.VertexBuffer; m_device.Indices = renderElement.IndexBuffer; m_device.SetStreamSource(0, renderElement.VertexBuffer, 0, renderElement.VertexStride); m_device.VertexDeclaration = renderElement.VertexDeclaration; MyPerformanceCounter.PerCameraDraw.VertexBufferChanges[(int)lod]++; ibChangesStats++; } if (lastEntity != renderElement.Entity) { lastEntity = renderElement.Entity; MyPerformanceCounter.PerCameraDraw.EntityChanges[(int)lod]++; SetupShaderForEntity(shader, renderElement); shader.D3DEffect.CommitChanges(); } m_renderProfiler.StartProfilingBlock("DrawIndexedPrimitives"); m_device.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, renderElement.VertexCount, renderElement.IndexStart, renderElement.TriCount); MyPerformanceCounter.PerCameraDraw.TotalDrawCalls++; m_renderProfiler.EndProfilingBlock(); } } shader.End(); // Technique End }
static void BeginShaderAlternative(MyEffectBase shader, MyMeshDrawTechnique technique, MyVoxelCacheCellRenderBatchType batchType) { switch (technique) { case MyMeshDrawTechnique.DECAL: { if (shader is MyEffectModelsDNS) { (shader as MyEffectModelsDNS).BeginBlended(); } } break; case MyMeshDrawTechnique.HOLO: { if (m_currentLodDrawPass != MyLodTypeEnum.LOD_NEAR && !MyRenderConstants.RenderQualityProfile.ForwardRender) { (shader as MyEffectModelsDNS).ApplyHolo(false); } else { (shader as MyEffectModelsDNS).ApplyHolo(true); } } break; case MyMeshDrawTechnique.ALPHA_MASKED: { (shader as MyEffectModelsDNS).ApplyMasked(); } break; case MyMeshDrawTechnique.VOXEL_MAP: { MyEffectVoxels effectVoxels = shader as MyEffectVoxels; if (batchType == MyVoxelCacheCellRenderBatchType.SINGLE_MATERIAL) { effectVoxels.Apply(); } else if (batchType == MyVoxelCacheCellRenderBatchType.MULTI_MATERIAL) { effectVoxels.ApplyMultimaterial(); } break; } case MyMeshDrawTechnique.VOXELS_STATIC_ASTEROID: { ((MyEffectVoxelsStaticAsteroid)shader).Apply(); } break; case MyMeshDrawTechnique.MESH: { ((MyEffectModelsDNS)shader).SetTechnique(MyRenderConstants.RenderQualityProfile.ModelsRenderTechnique); } break; case MyMeshDrawTechnique.VOXELS_DEBRIS: { ((MyEffectVoxelsDebris)shader).SetTechnique(MyRenderConstants.RenderQualityProfile.VoxelsRenderTechnique); } break; default: { System.Diagnostics.Debug.Assert(false); } break; } }
public int GetVoxelIndex(MyLodTypeEnum lod, MyVoxelCacheCellRenderBatchType technique) { return(((byte)lod * VoxelTechniqueCount) + (int)technique); }