public void InitBuffers() { BufferStreamer.QueueTask((a) => { if (vArray == null) { vArray = new VertexArray(); } if (vBuf != null) { vBuf.Dispose(); } vBuf = new GPUBuffer(OpenTK.Graphics.OpenGL4.BufferTarget.ArrayBuffer, Side * Side * Side * 16, false); //vBuf = new GPUBuffer(OpenTK.Graphics.OpenGL4.BufferTarget.ArrayBuffer); //vBuf.BufferData(0, vertex.ToArray(), OpenTK.Graphics.OpenGL4.BufferUsageHint.StaticDraw); vArray.SetBufferObject(0, vBuf, 4, OpenTK.Graphics.OpenGL4.VertexAttribPointerType.Int2101010Rev); if (vMat != null) { vMat.Dispose(); } vMat = new GPUBuffer(OpenTK.Graphics.OpenGL4.BufferTarget.ArrayBuffer, Side * Side * Side * 8, false); //vMat = new GPUBuffer(OpenTK.Graphics.OpenGL4.BufferTarget.ArrayBuffer); //vMat.BufferData(0, mat.ToArray(), OpenTK.Graphics.OpenGL4.BufferUsageHint.StaticDraw); vArray.SetBufferObject(1, vMat, 1, OpenTK.Graphics.OpenGL4.VertexAttribPointerType.Short); }, null); }
public void GenerateMesh() { #region Naive Mesher /* * List<int>[] nverts = new List<int>[6]; * List<short>[] nMaterials = new List<short>[6]; * for (int i = 0; i < 6; i++) * { * nverts[i] = new List<int>(); * nMaterials[i] = new List<short>(); * } * * int baseX = 0; * int baseY = 0; * int baseZ = 0; * * float s = 1; * * Func<float, float, float, int> packVerts = (x, y, z) => * { * byte x0 = (byte)((int)x & ((1 << 10) - 1)); * byte y0 = (byte)((int)y & ((1 << 10) - 1)); * byte z0 = (byte)((int)z & ((1 << 10) - 1)); * * int packed = x0 | (y0 << 10) | (z0 << 20); * * return packed; * }; * * Parallel.For(0, Side, (x) => * { * List<int>[] verts = new List<int>[6]; * List<short>[] Materials = new List<short>[6]; * for (int i = 0; i < 6; i++) * { * verts[i] = new List<int>(); * Materials[i] = new List<short>(); * } * for (int y = 0; y < Side; y++) * { * for (int z = 0; z < Side; z++) * { * * float x0 = baseX + x * s; * float y0 = baseY + y * s; * float z0 = baseZ + z * s; * * if (!VoxelMap[MaterialMap[this[(int)x, y, z]]].Visible) continue; * * if (z == 0 | !VoxelMap[MaterialMap[this[(int)x, y, z - 1]]].Visible) * { * verts[0].Add(packVerts(x0, y0, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[0].Add(packVerts(x0 + s, y0 + s, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[0].Add(packVerts(x0 + s, y0, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[0].Add(packVerts(x0 + s, y0 + s, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[0].Add(packVerts(x0, y0, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[0].Add(packVerts(x0, y0 + s, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * } * * if (z == Side - 1 | !VoxelMap[MaterialMap[this[(int)x, y, z + 1]]].Visible) * { * verts[3].Add(packVerts(x0, y0, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[3].Add(packVerts(x0 + s, y0, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[3].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[3].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[3].Add(packVerts(x0, y0 + s, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[3].Add(packVerts(x0, y0, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * } * * if (y == 0 | !VoxelMap[MaterialMap[this[(int)x, y - 1, z]]].Visible) * { * verts[1].Add(packVerts(x0 + s, y0, z0 + s)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[1].Add(packVerts(x0, y0, z0 + s)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[1].Add(packVerts(x0, y0, z0)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[1].Add(packVerts(x0, y0, z0)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[1].Add(packVerts(x0 + s, y0, z0)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[1].Add(packVerts(x0 + s, y0, z0 + s)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * } * * if (y == Side - 1 | !VoxelMap[MaterialMap[this[(int)x, y + 1, z]]].Visible) * { * verts[4].Add(packVerts(x0, y0 + s, z0)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[4].Add(packVerts(x0, y0 + s, z0 + s)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[4].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[4].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[4].Add(packVerts(x0 + s, y0 + s, z0)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[4].Add(packVerts(x0, y0 + s, z0)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * } * * if (x == 0 | !VoxelMap[MaterialMap[this[x - 1, y, z]]].Visible) * { * verts[2].Add(packVerts(x0, y0 + s, z0 + s)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[2].Add(packVerts(x0, y0 + s, z0)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[2].Add(packVerts(x0, y0, z0)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[2].Add(packVerts(x0, y0, z0)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[2].Add(packVerts(x0, y0, z0 + s)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[2].Add(packVerts(x0, y0 + s, z0 + s)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * } * * if (x == Side - 1 | !VoxelMap[MaterialMap[this[x + 1, y, z]]].Visible) * { * verts[5].Add(packVerts(x0 + s, y0, z0)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[5].Add(packVerts(x0 + s, y0 + s, z0)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[5].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[5].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[5].Add(packVerts(x0 + s, y0, z0 + s)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[5].Add(packVerts(x0 + s, y0, z0)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * } * } * } * * lock (nverts) * { * for (int i = 0; i < 6; i++) * { * nverts[i].AddRange(verts[i]); * nMaterials[i].AddRange(Materials[i]); * } * } * }); * * List<int> netVerts = new List<int>(); * List<short> netMats = new List<short>(); * * NormalOffsets = new int[6]; * NormalGroupSizes = new int[7]; * * for (int i = 0; i < 6; i++) * { * NormalOffsets[i] = netVerts.Count; * NormalGroupSizes[i] = nverts[i].Count; * NormalGroupSizes[6] += NormalGroupSizes[i]; * netVerts.AddRange(nverts[i]); * netMats.AddRange(nMaterials[i]); * } * vArray = new VertexArray(); * vMat = new GPUBuffer(OpenTK.Graphics.OpenGL4.BufferTarget.ArrayBuffer); * vMat.BufferData(0, netMats.ToArray(), OpenTK.Graphics.OpenGL4.BufferUsageHint.StaticDraw); * vArray.SetBufferObject(1, vMat, 1, OpenTK.Graphics.OpenGL4.VertexAttribPointerType.Short); * * vBuf = new GPUBuffer(OpenTK.Graphics.OpenGL4.BufferTarget.ArrayBuffer); * vBuf.BufferData(0, netVerts.ToArray(), OpenTK.Graphics.OpenGL4.BufferUsageHint.StaticDraw); * vArray.SetBufferObject(0, vBuf, 4, OpenTK.Graphics.OpenGL4.VertexAttribPointerType.Int2101010Rev); */ #endregion Func <float, float, float, int> packVerts = (x, y, z) => { byte x0 = (byte)((int)x & ((1 << 10) - 1)); byte y0 = (byte)((int)y & ((1 << 10) - 1)); byte z0 = (byte)((int)z & ((1 << 10) - 1)); int packed = x0 | (y0 << 10) | (z0 << 20); return(packed); }; #region Naive Mesher Asynchronous /* * ChunkReady = false; * * int baseX = 0; * int baseY = 0; * int baseZ = 0; * * float s = 1; * * * BufferStreamer.QueueTask((a) => * { * Fence f = new Fence(); * * vArray = new VertexArray(); * vMat = new GPUBuffer(OpenTK.Graphics.OpenGL4.BufferTarget.ArrayBuffer); * //vMat.BufferData(0, netMats.ToArray(), OpenTK.Graphics.OpenGL4.BufferUsageHint.StaticDraw); * vArray.SetBufferObject(1, vMat, 1, OpenTK.Graphics.OpenGL4.VertexAttribPointerType.Short); * * vBuf = new GPUBuffer(OpenTK.Graphics.OpenGL4.BufferTarget.ArrayBuffer); * //vBuf.BufferData(0, netVerts.ToArray(), OpenTK.Graphics.OpenGL4.BufferUsageHint.StaticDraw); * vArray.SetBufferObject(0, vBuf, 4, OpenTK.Graphics.OpenGL4.VertexAttribPointerType.Int2101010Rev); * f.PlaceFence(); * * Action<object> runner = (q0) => * { * List<int>[] verts = new List<int>[6]; * List<short>[] Materials = new List<short>[6]; * for (int i = 0; i < 6; i++) * { * verts[i] = new List<int>(); * Materials[i] = new List<short>(); * } * * for (int x = 0; x < Side; x++) * { * for (int y = 0; y < Side; y++) * { * for (int z = 0; z < Side; z++) * { * * float x0 = baseX + x * s; * float y0 = baseY + y * s; * float z0 = baseZ + z * s; * * if (!VoxelMap[MaterialMap[this[(int)x, y, z]]].Visible) continue; * * if (z == 0 | !VoxelMap[MaterialMap[this[(int)x, y, z - 1]]].Visible) * { * verts[0].Add(packVerts(x0, y0, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[0].Add(packVerts(x0 + s, y0 + s, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[0].Add(packVerts(x0 + s, y0, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[0].Add(packVerts(x0 + s, y0 + s, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[0].Add(packVerts(x0, y0, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[0].Add(packVerts(x0, y0 + s, z0)); * Materials[0].Add((short)MaterialMap[this[(int)x, y, z]]); * } * * if (z == Side - 1 | !VoxelMap[MaterialMap[this[(int)x, y, z + 1]]].Visible) * { * verts[3].Add(packVerts(x0, y0, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[3].Add(packVerts(x0 + s, y0, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[3].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[3].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[3].Add(packVerts(x0, y0 + s, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[3].Add(packVerts(x0, y0, z0 + s)); * Materials[3].Add((short)MaterialMap[this[(int)x, y, z]]); * } * * if (y == 0 | !VoxelMap[MaterialMap[this[(int)x, y - 1, z]]].Visible) * { * verts[1].Add(packVerts(x0 + s, y0, z0 + s)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[1].Add(packVerts(x0, y0, z0 + s)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[1].Add(packVerts(x0, y0, z0)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[1].Add(packVerts(x0, y0, z0)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[1].Add(packVerts(x0 + s, y0, z0)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[1].Add(packVerts(x0 + s, y0, z0 + s)); * Materials[1].Add((short)MaterialMap[this[(int)x, y, z]]); * } * * if (y == Side - 1 | !VoxelMap[MaterialMap[this[(int)x, y + 1, z]]].Visible) * { * verts[4].Add(packVerts(x0, y0 + s, z0)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[4].Add(packVerts(x0, y0 + s, z0 + s)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[4].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[4].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[4].Add(packVerts(x0 + s, y0 + s, z0)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[4].Add(packVerts(x0, y0 + s, z0)); * Materials[4].Add((short)MaterialMap[this[(int)x, y, z]]); * } * * if (x == 0 | !VoxelMap[MaterialMap[this[x - 1, y, z]]].Visible) * { * verts[2].Add(packVerts(x0, y0 + s, z0 + s)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[2].Add(packVerts(x0, y0 + s, z0)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[2].Add(packVerts(x0, y0, z0)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[2].Add(packVerts(x0, y0, z0)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[2].Add(packVerts(x0, y0, z0 + s)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[2].Add(packVerts(x0, y0 + s, z0 + s)); * Materials[2].Add((short)MaterialMap[this[(int)x, y, z]]); * } * * if (x == Side - 1 | !VoxelMap[MaterialMap[this[x + 1, y, z]]].Visible) * { * verts[5].Add(packVerts(x0 + s, y0, z0)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[5].Add(packVerts(x0 + s, y0 + s, z0)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[5].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[5].Add(packVerts(x0 + s, y0 + s, z0 + s)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[5].Add(packVerts(x0 + s, y0, z0 + s)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * * verts[5].Add(packVerts(x0 + s, y0, z0)); * Materials[5].Add((short)MaterialMap[this[(int)x, y, z]]); * } * } * } * } * * object[] ptrs = (object[])q0; * * List<int> sV = new List<int>(); * List<short> sM = new List<short>(); * * NormalOffsets = new int[6]; * NormalGroupSizes = new int[7]; * * for (int i = 0; i < 6; i++) * { * NormalOffsets[i] = sV.Count; * NormalGroupSizes[i] = verts[i].Count; * NormalGroupSizes[6] += NormalGroupSizes[i]; * sV.AddRange(verts[i]); * sM.AddRange(Materials[i]); * } * * BufferStreamer.QueueTask((o0) => * { * object[] o1 = (object[])o0; * GPUBuffer p0 = (GPUBuffer)o1[0]; * GPUBuffer p1 = (GPUBuffer)o1[1]; * * Fence f0 = (Fence)o1[4]; * * f0.Raised(0); * short[] v1 = (short[])o1[3]; * p0.BufferData(0, v1, OpenTK.Graphics.OpenGL4.BufferUsageHint.StaticDraw); * * int[] v0 = (int[])o1[2]; * p1.BufferData(0, v0, OpenTK.Graphics.OpenGL4.BufferUsageHint.StaticDraw); * * //VertexArray v2 = (VertexArray)o1[5]; * //v2.SetBufferObject(1, p0, 1, OpenTK.Graphics.OpenGL4.VertexAttribPointerType.Short); * //v2.SetBufferObject(0, p1, 4, OpenTK.Graphics.OpenGL4.VertexAttribPointerType.Int2101010Rev); * * ChunkReady = true; * * }, new object[] { ptrs[0], ptrs[1], sV.ToArray(), sM.ToArray(), f, ptrs[2] }); * * }; //Delegate end * * ThreadPool.QueueUserWorkItem(new WaitCallback(runner), new object[] { vMat, vBuf, vArray }); * }, null); */ #endregion #region Advanced Greedy Mesher ChunkReady = false; List <int>[] rV = new List <int> [6]; List <short>[] rM = new List <short> [6]; for (int i = 0; i < 6; i++) { rV[i] = new List <int>(); rM[i] = new List <short>(); } List <short> ValidMats = new List <short>(); for (int i = 0; i < MaterialMap.Length; i++) { if (VoxelMap[MaterialMap[i]].Visible && !ValidMats.Contains((short)MaterialMap[i])) { ValidMats.Add((short)MaterialMap[i]); } } for (int m = 0; m < ValidMats.Count; m++) { for (int d = 0; d < 3; d++) { Vector3 norm = Vector3.Zero; norm[d] = 1; int u = (d + 1) % 3; int v = (d + 2) % 3; Vector3 x = Vector3.Zero; bool empty = true; for (x[d] = -1; x[d] < Side;) { norm = Vector3.Zero; norm[d] = 1; bool[] mask2 = new bool[Side]; bool[,] mask = new bool[Side, Side]; for (x[u] = 0; x[u] < Side; x[u]++) { bool sum = false; for (x[v] = 0; x[v] < Side; x[v]++) { //Compute a mask if ((!VoxelMap[MaterialMap[this[x + norm]]].Visible | !VoxelMap[MaterialMap[this[x - norm]]].Visible)) { mask[(int)x[u], (int)x[v]] = (0 <= x[d] ? MaterialMap[this[x]] == ValidMats[m] : false) != (x[d] < Side - 1 ? MaterialMap[this[x + norm]] == ValidMats[m] : false); empty = false; sum = true; } } mask2[(int)x[u]] = sum; } x[d]++; if (empty) { continue; } //Now determine the edges from the mask for (int i = 0; i < Side; i++) { if (!mask2[i]) { continue; } int minW = Side; for (int j = 0; j < Side;) { if (!mask[i, j]) { j++; continue; } int w = 1, h = 1; for (; i + w < Side && mask[i + w, j]; w++) { ; } if (w < minW) { minW = w; } bool done = false; for (; j + h < Side; h++) { for (int i0 = 0; i0 < w; i0++) { if (!mask[i + i0, j + h]) { done = true; break; } } if (done) { break; } } Vector3 tL = Vector3.Zero; Vector3 tR = Vector3.Zero; Vector3 bL = Vector3.Zero; Vector3 bR = Vector3.Zero; x[u] = i; x[v] = j; tL[d] = x[d]; tR[d] = x[d]; bL[d] = x[d]; bR[d] = x[d]; tL[u] = i; tL[v] = j; tR[u] = i + w; tR[v] = j; bL[u] = i; bL[v] = j + h; bR[u] = i + w; bR[v] = j + h; norm = Vector3.Zero; norm[d] = 1; Vector3 cPos = Vector3.Zero; cPos[u] = i; cPos[v] = j; cPos[d] = x[d] - 1; if (!VoxelMap[MaterialMap[this[cPos]]].Visible) { norm[d] = -norm[d]; } else { norm[d] = 1; } int normIndex = 0; for (; normIndex < Normals.Length && Normals[normIndex] != norm; normIndex++) { ; } if (normIndex <= 2) { rV[normIndex].Add(packVerts(tR.X, tR.Y, tR.Z)); rV[normIndex].Add(packVerts(tL.X, tL.Y, tL.Z)); rV[normIndex].Add(packVerts(bL.X, bL.Y, bL.Z)); rV[normIndex].Add(packVerts(bL.X, bL.Y, bL.Z)); rV[normIndex].Add(packVerts(bR.X, bR.Y, bR.Z)); rV[normIndex].Add(packVerts(tR.X, tR.Y, tR.Z)); } else { rV[normIndex].Add(packVerts(tL.X, tL.Y, tL.Z)); rV[normIndex].Add(packVerts(tR.X, tR.Y, tR.Z)); rV[normIndex].Add(packVerts(bL.X, bL.Y, bL.Z)); rV[normIndex].Add(packVerts(bL.X, bL.Y, bL.Z)); rV[normIndex].Add(packVerts(tR.X, tR.Y, tR.Z)); rV[normIndex].Add(packVerts(bR.X, bR.Y, bR.Z)); } rM[normIndex].Add(ValidMats[m]); rM[normIndex].Add(ValidMats[m]); rM[normIndex].Add(ValidMats[m]); rM[normIndex].Add(ValidMats[m]); rM[normIndex].Add(ValidMats[m]); rM[normIndex].Add(ValidMats[m]); for (int w0 = i; w0 < i + w; w0++) { for (int j0 = j; j0 < j + h; j0++) { mask[w0, j0] = false; } } j += h; } } } } } //d loop NormalOffsets = new int[6]; NormalGroupSizes = new int[7]; List <int> vertex = new List <int>(); List <short> mat = new List <short>(); for (int i = 0; i < 6; i++) { NormalOffsets[i] = vertex.Count; NormalGroupSizes[i] = rV[i].Count; NormalGroupSizes[6] += NormalGroupSizes[i]; vertex.AddRange(rV[i]); mat.AddRange(rM[i]); } ThreadPool.QueueUserWorkItem(new WaitCallback((a0) => { while (vBuf == null | vMat == null) { Thread.Yield(); } Marshal.Copy(vertex.ToArray(), 0, vBuf.GetPtr(), vertex.Count); Marshal.Copy(mat.ToArray(), 0, vMat.GetPtr(), mat.Count); BufferStreamer.QueueTask((a1) => { //GPUBuffer.FlushAll(); vMat.UnMapBuffer(); vBuf.UnMapBuffer(); ChunkReady = true; }, null); })); #endregion #region Greedy Mesher /* * ChunkReady = false; * * List<int>[] rVerts = new List<int>[6]; * List<short>[] rMats = new List<short>[6]; * for (int i = 0; i < 6; i++) * { * rVerts[i] = new List<int>(); * rMats[i] = new List<short>(); * } * for (int d = 0; d < 3; d++) * { * List<int>[] normalVerts = new List<int>[6]; * List<short>[] mats = new List<short>[6]; * * for (int i0 = 0; i0 < 6; i0++) * { * mats[i0] = new List<short>(); * normalVerts[i0] = new List<int>(); * } * * for (int q9 = 0; q9 < MaterialMap.Length; q9++) * { * curMaterial = q9; * * int i, j, k, l, w, h, u = (d + 1) % 3, v = (d + 2) % 3; * int[] x = new int[3]; * int[] q = new int[3]; * bool[] mask = new bool[Side * Side]; * * q[d] = 1; * * for (x[d] = -1; x[d] < Side;) * { * // Compute the mask * int n = 0; * for (x[v] = 0; x[v] < Side; ++x[v]) * { * for (x[u] = 0; x[u] < Side; ++x[u]) * { * mask[n++] = (0 <= x[d] ? data(x[0], x[1], x[2]) : false) != * (x[d] < Side - 1 ? data(x[0] + q[0], x[1] + q[1], x[2] + q[2]) : false); * } * } * * // Increment x[d] ++x[d]; * * // Generate mesh for mask using lexicographic ordering * n = 0; * for (j = 0; j < Side; ++j) * { * for (i = 0; i < Side;) * { * if (mask[n]) * { * // Compute width * for (w = 1; i + w < Side && mask[n + w]; ++w) ; * * // Compute height (this is slightly awkward * var done = false; * for (h = 1; j + h < Side; ++h) * { * for (k = 0; k < w; ++k) * { * if (!mask[n + k + h * Side]) * { * done = true; * break; * } * } * if (done) break; * } * * // Add quad * x[u] = i; x[v] = j; * int[] du = new int[3]; * int[] dv = new int[3]; * du[u] = w; * dv[v] = h; * * Vector3[] v0 = new Vector3[] { * new Vector3(x[0], x[1], x[2]), * new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]), * new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]), * new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]), * new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]), * new Vector3(x[0], x[1], x[2]) * }; * * Vector3 curVoxel = Vector3.Zero; * curVoxel[u] = i; * curVoxel[v] = j; * curVoxel[d] = x[d] - 1; * * Vector3 nNorm = Vector3.Zero; * * if (data((int)curVoxel.X, (int)curVoxel.Y, (int)curVoxel.Z)) * { * nNorm[d] = -1; * } * else * { * nNorm[d] = 1; * } * * nNorm.X = (float)Math.Round(nNorm.X); * nNorm.Y = (float)Math.Round(nNorm.Y); * nNorm.Z = (float)Math.Round(nNorm.Z); * * curVoxel = new Vector3(x[0], x[1], x[2]) + nNorm; * * if (nNorm.X > 0 | nNorm.Y > 0 | nNorm.Z > 0) * { * Vector3 tmp0 = v0[1]; * Vector3 tmp1 = v0[2]; * * v0[1] = tmp1; * v0[2] = tmp0; * * tmp0 = v0[3]; * tmp1 = v0[4]; * * v0[3] = tmp1; * v0[4] = tmp0; * * } * * int[] v1 = new int[v0.Length]; * for (int q0 = 0; q0 < v1.Length; q0++) * { * v1[q0] = packVerts(v0[q0].X, v0[q0].Y, v0[q0].Z); * * } * * if (nNorm == Vector3.UnitX) * { * normalVerts[0].AddRange(v1); * for (int i0 = 0; i0 < v1.Length; i0++) mats[0].Add((short)MaterialMap[this[curVoxel]]); * } * else if (nNorm == Vector3.UnitY) * { * normalVerts[1].AddRange(v1); * for (int i0 = 0; i0 < v1.Length; i0++) mats[1].Add((short)MaterialMap[this[curVoxel]]); * } * else if (nNorm == Vector3.UnitZ) * { * normalVerts[5].AddRange(v1); * for (int i0 = 0; i0 < v1.Length; i0++) mats[5].Add((short)MaterialMap[this[curVoxel]]); * } * else if (nNorm == -Vector3.UnitX) * { * normalVerts[3].AddRange(v1); * for (int i0 = 0; i0 < v1.Length; i0++) mats[3].Add((short)MaterialMap[this[curVoxel]]); * } * else if (nNorm == -Vector3.UnitY) * { * normalVerts[4].AddRange(v1); * for (int i0 = 0; i0 < v1.Length; i0++) mats[4].Add((short)MaterialMap[this[curVoxel]]); * } * else if (nNorm == -Vector3.UnitZ) * { * normalVerts[2].AddRange(v1); //Switched around to make the normal array cleaner * for (int i0 = 0; i0 < v1.Length; i0++) mats[2].Add((short)MaterialMap[this[curVoxel]]); * } * else throw new Exception("Invalid Face!"); * * // Zero-out mask * for (l = 0; l < h; ++l) * { * for (k = 0; k < w; ++k) * { * mask[n + k + l * Side] = false; * } * } * * // Increment counters and continue * i += w; n += w; * } * else * { ++i; ++n; * } * } * } * } * * lock (rVerts) * { * for (int i0 = 0; i0 < 6; i0++) * { * rMats[i0].AddRange(mats[i0]); * rVerts[i0].AddRange(normalVerts[i0]); * } * } * } * } * * NormalOffsets = new int[6]; * NormalGroupSizes = new int[7]; * * List<int> vertex = new List<int>(); * List<short> mat = new List<short>(); * for (int i = 0; i < 6; i++) * { * NormalOffsets[i] = vertex.Count; * NormalGroupSizes[i] = rVerts[i].Count; * NormalGroupSizes[6] += NormalGroupSizes[i]; * vertex.AddRange(rVerts[i]); * mat.AddRange(rMats[i]); * } * * BufferStreamer.QueueTask((a) => * { * vArray = new VertexArray(); * vBuf = new GPUBuffer(OpenTK.Graphics.OpenGL4.BufferTarget.ArrayBuffer); * vBuf.BufferData(0, vertex.ToArray(), OpenTK.Graphics.OpenGL4.BufferUsageHint.StaticDraw); * vArray.SetBufferObject(0, vBuf, 4, OpenTK.Graphics.OpenGL4.VertexAttribPointerType.Int2101010Rev); * * vMat = new GPUBuffer(OpenTK.Graphics.OpenGL4.BufferTarget.ArrayBuffer); * vMat.BufferData(0, mat.ToArray(), OpenTK.Graphics.OpenGL4.BufferUsageHint.StaticDraw); * vArray.SetBufferObject(1, vMat, 1, OpenTK.Graphics.OpenGL4.VertexAttribPointerType.Short); * ChunkReady = true; * }, null); */ #endregion }