private static void AddVertexToBuffer(MySingleMaterialHelper materialHelper, ref MyVoxelVertex vertex0, int matIndex, short vertexIndex0) { if (MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].CalcCounter != MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[matIndex]) { int nextVertexIndex = materialHelper.VertexCount; // Short overflow check System.Diagnostics.Debug.Assert(nextVertexIndex <= short.MaxValue); // copy position and ambient materialHelper.Vertices[nextVertexIndex].m_positionAndAmbient = vertex0.m_positionAndAmbient; materialHelper.Vertices[nextVertexIndex].Ambient = vertex0.Ambient; // Copy normal #if PACKED_VERTEX_FORMAT materialHelper.Vertices[nextVertexIndex].m_normal = vertex0.m_normal; #else materialHelper.Vertices[nextVertexIndex].Normal = vertex0.Normal; #endif MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].CalcCounter = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[matIndex]; MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].VertexIndex = (short)nextVertexIndex; materialHelper.VertexCount++; } }
public static MySingleMaterialHelper GetForMaterial(MyMwcVoxelMaterialsEnum material) { if (m_preallocatedSingleMaterialHelpers[(int)material] == null) { m_preallocatedSingleMaterialHelpers[(int)material] = new MySingleMaterialHelper(); m_preallocatedSingleMaterialHelpers[(int)material].LoadData(); m_preallocatedSingleMaterialHelpers[(int)material].SetMaterial(material); } return(m_preallocatedSingleMaterialHelpers[(int)material]); //m_singleMaterialHelper.SetMaterial(material); //return m_singleMaterialHelper; }
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]++; }
// 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 MySingleMaterialHelper GetForMaterial(MyMwcVoxelMaterialsEnum material) { if (m_preallocatedSingleMaterialHelpers[(int)material] == null) { m_preallocatedSingleMaterialHelpers[(int)material] = new MySingleMaterialHelper(); m_preallocatedSingleMaterialHelpers[(int)material].LoadData(); m_preallocatedSingleMaterialHelpers[(int)material].SetMaterial(material); } return m_preallocatedSingleMaterialHelpers[(int)material]; //m_singleMaterialHelper.SetMaterial(material); //return m_singleMaterialHelper; }