// This methods needs to be called after every cell cache released!! It releases vertex buffer. It's important, // because when this cell cache will be associated to a new cell, not same material vertex buffer will be used so unused needs to be disposed!! public void Reset() { if (Batches != null) { for (int i = 0; i < Batches.Count; i++) { MyVoxelCacheCellRenderBatch batch = Batches[i]; if (batch != null) { if (batch.VertexBuffer != null) { // Dispose and set to null, so GC can take it batch.VertexBuffer.Dispose(); batch.VertexBuffer = null; MyPerformanceCounter.PerAppLifetime.VoxelVertexBuffersSize -= batch.VertexBufferSize; batch.VertexBufferSize = 0; } if (batch.IndexBuffer != null) { // Dispose and set to null, so GC can take it batch.IndexBuffer.Dispose(); batch.IndexBuffer = null; MyPerformanceCounter.PerAppLifetime.VoxelIndexBuffersSize -= batch.IndexBufferSize; batch.IndexBufferSize = 0; } } } Contains = false; Batches.Clear(); } }
void EndMultiMaterial(MyMultiMaterialHelper helper) { if (helper.VertexCount > 0) { // This will just preload textures used by this material - so they are ready in memory when first time drawn MyVoxelMaterials.Get(helper.Material0).GetTextures(); MyVoxelMaterials.Get(helper.Material1).GetTextures(); MyVoxelMaterials.Get(helper.Material2).GetTextures(); MyVoxelCacheCellRenderBatch newBatch = new MyVoxelCacheCellRenderBatch(); // Vertex buffer newBatch.VertexBufferCount = helper.VertexCount; newBatch.VertexBuffer = new VertexBuffer(MyMinerGame.Static.GraphicsDevice, MyVertexFormatVoxelSingleMaterial.Stride * newBatch.VertexBufferCount, Usage.WriteOnly, VertexFormat.None, Pool.Default); newBatch.VertexBuffer.Lock(0, 0, LockFlags.None).WriteRange(helper.Vertices, 0, newBatch.VertexBufferCount); newBatch.VertexBuffer.Unlock(); newBatch.VertexBuffer.Tag = this; newBatch.VertexBuffer.DebugName = "VoxelBatchMulti"; newBatch.VertexBufferSize = helper.VertexCount * MyVertexFormatVoxelSingleMaterial.Stride; MyPerformanceCounter.PerAppLifetime.VoxelVertexBuffersSize += newBatch.VertexBufferSize; // Index buffer (because everything must have IB) newBatch.IndexBufferCount = helper.VertexCount; newBatch.IndexBuffer = new IndexBuffer(MyMinerGame.Static.GraphicsDevice, newBatch.IndexBufferCount * sizeof(short), Usage.WriteOnly, Pool.Default, true); short[] indices = new short[helper.VertexCount]; for (short i = 0; i < indices.Length; i++) { indices[i] = i; } newBatch.IndexBuffer.Lock(0, 0, LockFlags.None).WriteRange(indices); newBatch.IndexBuffer.Unlock(); newBatch.IndexBuffer.DebugName = "VoxelBatchMulti"; newBatch.IndexBuffer.Tag = this; newBatch.IndexBufferSize = helper.VertexCount * sizeof(short); MyPerformanceCounter.PerAppLifetime.VoxelIndexBuffersSize += newBatch.IndexBufferSize; newBatch.Type = MyVoxelCacheCellRenderBatchType.MULTI_MATERIAL; newBatch.Material0 = helper.Material0; newBatch.Material1 = helper.Material1; newBatch.Material2 = helper.Material2; newBatch.UpdateSortOrder(); Batches.Add(newBatch); } // Reset helper arrays, so we can start adding triangles to them again helper.VertexCount = 0; }
void EndSingleMaterial(MySingleMaterialHelper materialHelper) { if (materialHelper.IndexCount > 0 && materialHelper.VertexCount > 0) { // This will just preload textures used by this material - so they are ready in memory when first time drawn MyVoxelMaterials.Get(materialHelper.Material).GetTextures(); MyVoxelCacheCellRenderBatch newBatch = new MyVoxelCacheCellRenderBatch(); // Vertex buffer newBatch.VertexBufferCount = materialHelper.VertexCount; newBatch.VertexBuffer = new VertexBuffer(MyMinerGame.Static.GraphicsDevice, MyVertexFormatVoxelSingleMaterial.Stride * newBatch.VertexBufferCount, Usage.WriteOnly, VertexFormat.None, Pool.Default); newBatch.VertexBuffer.Lock(0, 0, LockFlags.None).WriteRange(materialHelper.Vertices, 0, newBatch.VertexBufferCount); newBatch.VertexBuffer.Unlock(); newBatch.VertexBuffer.Tag = newBatch; newBatch.VertexBuffer.DebugName = "VoxelBatchSingle"; newBatch.VertexBufferSize = materialHelper.VertexCount * MyVertexFormatVoxelSingleMaterial.Stride; MyPerformanceCounter.PerAppLifetime.VoxelVertexBuffersSize += newBatch.VertexBufferSize; // Index buffer newBatch.IndexBufferCount = materialHelper.IndexCount; newBatch.IndexBuffer = new IndexBuffer(MyMinerGame.Static.GraphicsDevice, newBatch.IndexBufferCount * sizeof(short), Usage.WriteOnly, Pool.Default, true); newBatch.IndexBuffer.Lock(0, 0, LockFlags.None).WriteRange(materialHelper.Indices, 0, newBatch.IndexBufferCount); newBatch.IndexBuffer.Unlock(); newBatch.IndexBuffer.DebugName = "VoxelBatchSingle"; newBatch.IndexBufferSize = materialHelper.IndexCount * sizeof(short); MyPerformanceCounter.PerAppLifetime.VoxelIndexBuffersSize += newBatch.IndexBufferSize; newBatch.Type = MyVoxelCacheCellRenderBatchType.SINGLE_MATERIAL; newBatch.Material0 = materialHelper.Material; newBatch.Material1 = null; newBatch.Material2 = null; newBatch.UpdateSortOrder(); Batches.Add(newBatch); } // Reset helper arrays, so we can start adding triangles to them again materialHelper.IndexCount = 0; materialHelper.VertexCount = 0; MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[(int)materialHelper.Material]++; }
// For sorting batches by type and material // We want first multi-clear, then single-material and multi-material as last public int CompareTo(object compareToObject) { MyVoxelCacheCellRenderBatch compareToBatch = (MyVoxelCacheCellRenderBatch)compareToObject; return(this.SortOrder.CompareTo(compareToBatch.SortOrder)); }
/// <summary> /// SetupShader /// </summary> /// <param name="shader"></param> public static MyEffectBase SetupShaderForMaterial(MyMeshMaterial material, MyVoxelCacheCellRenderBatch voxelBatch) { switch (material.DrawTechnique) { case MyMeshDrawTechnique.MESH: case MyMeshDrawTechnique.DECAL: case MyMeshDrawTechnique.HOLO: case MyMeshDrawTechnique.ALPHA_MASKED: { MyEffectModelsDNS shader = GetEffect(MyEffects.ModelDNS) as MyEffectModelsDNS; if (material != null) { shader.SetTextureDiffuse(material.DiffuseTexture); shader.SetTextureNormal(material.NormalTexture); //Do we need this? Graphicians dont use this //shader.SetDiffuseColor(material.DiffuseColor); shader.SetSpecularIntensity(material.SpecularIntensity); shader.SetSpecularPower(material.SpecularPower); shader.SetDiffuseUVAnim(material.DiffuseUVAnim); shader.SetEmissivityUVAnim(material.EmissiveUVAnim); shader.SetEmissivityOffset(material.EmissivityOffset); if (material.DrawTechnique == MyMeshDrawTechnique.HOLO) { shader.SetEmissivity(material.HoloEmissivity); } // Commented due 856 - graphicians have to reexport white diffuse colors from MAX //shader.SetDiffuseColor(material.DiffuseColor); } else { shader.SetTextureDiffuse(null); shader.SetTextureNormal(null); shader.SetSpecularPower(1); shader.SetSpecularIntensity(1); //this value is set from object if not from material //shader.SetDiffuseColor(material.DiffuseColor); } if (CheckDiffuseTextures) { if (!shader.IsTextureDiffuseSet()) { LazyLoadDebugTextures(); shader.SetTextureDiffuse(m_debugTexture); shader.SetDiffuseColor(Vector3.One); shader.SetEmissivity(1); } else { if (material.DrawTechnique != MyMeshDrawTechnique.HOLO) { shader.SetEmissivity(0); } } } if (CheckNormalTextures) { if (!shader.IsTextureNormalSet()) { LazyLoadDebugTextures(); shader.SetTextureDiffuse(m_debugTexture); shader.SetEmissivity(1); } else { shader.SetTextureDiffuse(material.NormalTexture); //shader.SetTextureDiffuse(m_debugNormalTexture); shader.SetEmissivity(0); } } if (!shader.IsTextureNormalSet()) { LazyLoadDebugTextures(); shader.SetTextureNormal(m_debugTexture); } return shader; } break; case MyMeshDrawTechnique.VOXELS_DEBRIS: { MyEffectVoxelsDebris effectVoxelsDebris = GetEffect(MyEffects.VoxelDebrisMRT) as MyEffectVoxelsDebris; return effectVoxelsDebris; } break; case MyMeshDrawTechnique.VOXEL_MAP: { MyEffectVoxels effectVoxels = MyRender.GetEffect(MyEffects.VoxelsMRT) as MyEffectVoxels; if (voxelBatch.Type == MyVoxelCacheCellRenderBatchType.SINGLE_MATERIAL) { effectVoxels.UpdateVoxelTextures(OverrideVoxelMaterial ?? voxelBatch.Material0); } else if (voxelBatch.Type == MyVoxelCacheCellRenderBatchType.MULTI_MATERIAL) { effectVoxels.UpdateVoxelMultiTextures(OverrideVoxelMaterial ?? voxelBatch.Material0, OverrideVoxelMaterial ?? voxelBatch.Material1, OverrideVoxelMaterial ?? voxelBatch.Material2); } return effectVoxels; } break; case MyMeshDrawTechnique.VOXELS_STATIC_ASTEROID: { MyEffectVoxelsStaticAsteroid effectVoxelsStaticAsteroid = GetEffect(MyEffects.VoxelStaticAsteroidMRT) as MyEffectVoxelsStaticAsteroid; return effectVoxelsStaticAsteroid; } break; default: { throw new MyMwcExceptionApplicationShouldNotGetHere(); } } return null; }