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; }
public static MyMultiMaterialHelper GetForMultimaterial(MyMwcVoxelMaterialsEnum material0, MyMwcVoxelMaterialsEnum material1, MyMwcVoxelMaterialsEnum material2) { int id = MyVoxelCacheCellRender.GetMultimaterialId(material0, material1, material2); MyMultiMaterialHelper helper = null; m_preallocatedMultiMaterialHelpers.TryGetValue(id, out helper); if (helper == null) { helper = new MyMultiMaterialHelper(); helper.LoadData(); helper.SetMaterials(material0, material1, material2); m_preallocatedMultiMaterialHelpers.Add(id, helper); } return(helper); //m_multiMaterialHelper.SetMaterials(material0, material1, material2); //return m_multiMaterialHelper; }
// This method adds triangles from one data cell into this render cell. Single-texture triangles are added using indices (so we use m_notCompressedIndex buffer). // For this we need to find indices. We use lookup array for it. // Now we support only 16-bit indices, so vertex buffer can't have more then short.MaxValue vertices. public void AddTriangles(List <MyVoxelCacheCellData> cacheDataArray) { // MyPerformanceTimer.VoxelGpuBuffersBuild.Start(); //MyMwcVoxelMaterialsEnum? CurrentSingleMaterial = null; // bool triangleAdded = true; // while (triangleAdded) // { // triangleAdded = false; //CurrentSingleMaterial = null; foreach (var cacheData in cacheDataArray) { // Increase lookup count, so we will think that all vertexes in helper arrays are new for (int i = 0; i < MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount.Length; i++) { MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[i]++; } for (int i = 0; i < cacheData.VoxelTrianglesCount; i++) { MyVoxelTriangle triangle = cacheData.VoxelTriangles[i]; MyVoxelVertex vertex0 = cacheData.VoxelVertices[triangle.VertexIndex0]; MyVoxelVertex vertex1 = cacheData.VoxelVertices[triangle.VertexIndex1]; MyVoxelVertex vertex2 = cacheData.VoxelVertices[triangle.VertexIndex2]; if ((vertex0.Material == vertex1.Material) && (vertex0.Material == vertex2.Material)) { int matIndex = (int)vertex0.Material; // This is single-texture triangleVertexes, so we can choose material from any edge MySingleMaterialHelper materialHelper = MyVoxelCacheCellRenderHelper.GetForMaterial(vertex0.Material); // Add vertex0 to vertex buffer AddVertexToBuffer(materialHelper, ref vertex0, matIndex, triangle.VertexIndex0); // Add vertex1 to vertex buffer AddVertexToBuffer(materialHelper, ref vertex1, matIndex, triangle.VertexIndex1); // Add vertex2 to vertex buffer AddVertexToBuffer(materialHelper, ref vertex2, matIndex, triangle.VertexIndex2); //triangleAdded = true; // Add indices int nextTriangleIndex = materialHelper.IndexCount; materialHelper.Indices[nextTriangleIndex + 0] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][triangle.VertexIndex0].VertexIndex; materialHelper.Indices[nextTriangleIndex + 1] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][triangle.VertexIndex1].VertexIndex; materialHelper.Indices[nextTriangleIndex + 2] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][triangle.VertexIndex2].VertexIndex; materialHelper.IndexCount += 3; if ((materialHelper.VertexCount >= MyVoxelCacheCellRenderHelper.MAX_VERTICES_COUNT_STOP) || (materialHelper.IndexCount >= MyVoxelCacheCellRenderHelper.MAX_INDICES_COUNT_STOP)) { // If this batch is almost full (or is full), we end it and start with new one EndSingleMaterial(materialHelper); } } else { int id = GetMultimaterialId(vertex0.Material, vertex1.Material, vertex2.Material); // Assign current material MyMultiMaterialHelper multiMaterialHelper = MyVoxelCacheCellRenderHelper.GetForMultimaterial(vertex0.Material, vertex1.Material, vertex2.Material); //triangleAdded = true; #if PACKED_VERTEX_FORMAT // Copy packed normals multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 0].PackedNormal = vertex0.PackedNormal; multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 1].PackedNormal = vertex0.PackedNormal; multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 2].PackedNormal = vertex0.PackedNormal; #endif multiMaterialHelper.AddVertex(ref vertex0); multiMaterialHelper.AddVertex(ref vertex1); multiMaterialHelper.AddVertex(ref vertex2); if (multiMaterialHelper.VertexCount >= MyVoxelCacheCellRenderHelper.MAX_VERTICES_COUNT_STOP) { EndMultiMaterial(multiMaterialHelper); } } } /* * if (multiMaterialHelper != null) * { * int id = GetMultimaterialId(multiMaterialHelper.Material0, multiMaterialHelper.Material1, multiMaterialHelper.Material2); * MyVoxelCacheCellRenderHelper.FinishedMultiMaterials[id] = true; * EndMultimaterial(multiMaterialHelper); * } * * if (singleMaterialHelper != null) * { * MyVoxelCacheCellRenderHelper.FinishedSingleMaterials[(int)singleMaterialHelper.Material] = true; * EndSingleMaterial(singleMaterialHelper); * } */ } // } //MyPerformanceTimer.VoxelGpuBuffersBuild.End(); }
public static MyMultiMaterialHelper GetForMultimaterial(MyMwcVoxelMaterialsEnum material0, MyMwcVoxelMaterialsEnum material1, MyMwcVoxelMaterialsEnum material2) { int id = MyVoxelCacheCellRender.GetMultimaterialId(material0, material1, material2); MyMultiMaterialHelper helper = null; m_preallocatedMultiMaterialHelpers.TryGetValue(id, out helper); if (helper == null) { helper = new MyMultiMaterialHelper(); helper.LoadData(); helper.SetMaterials(material0, material1, material2); m_preallocatedMultiMaterialHelpers.Add(id, helper); } return helper; //m_multiMaterialHelper.SetMaterials(material0, material1, material2); //return m_multiMaterialHelper; }