public void MeshRects(int level, GraphicsDevice device) { var data = MeshRectData(level); if (data == null) { return; } if (Drawgroups[level - 2] != null && Drawgroups[level - 2].NumPrimitives > 0) { Drawgroups[level - 2].VertexBuffer.Dispose(); Drawgroups[level - 2].IndexBuffer.Dispose(); Drawgroups[level - 2].AdvVertexBuffer?.Dispose(); Drawgroups[level - 2].AdvIndexBuffer?.Dispose(); } var result = new RoofDrawGroup(); if (data.NumPrimitives > 0) { result.VertexBuffer = new VertexBuffer(device, typeof(TerrainParallaxVertex), data.Vertices.Length, BufferUsage.None); if (data.Vertices.Length > 0) { result.VertexBuffer.SetData(data.Vertices); } result.IndexBuffer = new IndexBuffer(device, IndexElementSize.ThirtyTwoBits, sizeof(int) * data.Indices.Length, BufferUsage.None); if (data.Vertices.Length > 0) { result.IndexBuffer.SetData(data.Indices); } } if (data.AdvNumPrimitives > 0) { result.AdvVertexBuffer = new VertexBuffer(device, typeof(TerrainParallaxVertex), data.AdvVertices.Length, BufferUsage.None); if (data.AdvVertices.Length > 0) { result.AdvVertexBuffer.SetData(data.AdvVertices); } result.AdvIndexBuffer = new IndexBuffer(device, IndexElementSize.ThirtyTwoBits, sizeof(int) * data.AdvIndices.Length, BufferUsage.None); if (data.AdvVertices.Length > 0) { result.AdvIndexBuffer.SetData(data.AdvIndices); } } result.NumPrimitives = data.NumPrimitives; result.AdvNumPrimitives = data.AdvNumPrimitives; Drawgroups[level - 2] = result; }
public void MeshRects(int level, GraphicsDevice device) { var data = MeshRectData(level); if (data == null) { return; } var Geom = data.Item1; var Indexes = data.Item2; var numPrimitives = data.Item3; if (Drawgroups[level - 2] != null && Drawgroups[level - 2].NumPrimitives > 0) { Drawgroups[level - 2].VertexBuffer.Dispose(); Drawgroups[level - 2].IndexBuffer.Dispose(); } var result = new RoofDrawGroup(); if (numPrimitives > 0) { result.VertexBuffer = new VertexBuffer(device, typeof(TerrainVertex), Geom.Length, BufferUsage.None); if (Geom.Length > 0) { result.VertexBuffer.SetData(Geom); } result.IndexBuffer = new IndexBuffer(device, IndexElementSize.ThirtyTwoBits, sizeof(int) * Indexes.Length, BufferUsage.None); if (Geom.Length > 0) { result.IndexBuffer.SetData(Indexes); } } result.NumPrimitives = numPrimitives; Drawgroups[level - 2] = result; }
public void MeshRects(int level, GraphicsDevice device) { var rects = RoofRects[level - 2]; if (rects == null) { return; } if (Drawgroups[level - 2] != null && Drawgroups[level - 2].NumPrimitives > 0) { Drawgroups[level - 2].VertexBuffer.Dispose(); Drawgroups[level - 2].IndexBuffer.Dispose(); } var numQuads = rects.Count * 4; //4 sides for each roof rectangle TerrainVertex[] Geom = new TerrainVertex[numQuads * 4]; int[] Indexes = new int[numQuads * 6]; var numPrimitives = (numQuads * 2); int geomOffset = 0; int indexOffset = 0; foreach (var rect in rects) { //determine roof height of the smallest edge. This height will be used on all edges var height = Math.Min(rect.x2 - rect.x1, rect.y2 - rect.y1) / 2; // / \ // / \ // /________\ Draw 4 segments like this. two segments will have the top middle section so short it will not appear. var heightMod = height / 400f; var pitch = RoofPitch; var tl = ToWorldPos(rect.x1, rect.y1, 0, level, pitch) + new Vector3(0, heightMod, 0); var tr = ToWorldPos(rect.x2, rect.y1, 0, level, pitch) + new Vector3(0, heightMod, 0); var bl = ToWorldPos(rect.x1, rect.y2, 0, level, pitch) + new Vector3(0, heightMod, 0); var br = ToWorldPos(rect.x2, rect.y2, 0, level, pitch) + new Vector3(0, heightMod, 0); //middle vertices. todo: height modifier (not hard) var m_tl = ToWorldPos(rect.x1 + height, rect.y1 + height, height, level, pitch) + new Vector3(0, heightMod, 0); var m_tr = ToWorldPos(rect.x2 - height, rect.y1 + height, height, level, pitch) + new Vector3(0, heightMod, 0); var m_bl = ToWorldPos(rect.x1 + height, rect.y2 - height, height, level, pitch) + new Vector3(0, heightMod, 0); var m_br = ToWorldPos(rect.x2 - height, rect.y2 - height, height, level, pitch) + new Vector3(0, heightMod, 0); Color topCol = Color.Lerp(Color.White, new Color(175, 175, 175), pitch); Color rightCol = Color.White; Color btmCol = Color.Lerp(Color.White, new Color(200, 200, 200), pitch); Color leftCol = Color.Lerp(Color.White, new Color(150, 150, 150), pitch); Vector4 darken = new Vector4(0.8f, 0.8f, 0.8f, 1.0f); //quad as two tris for (int j = 0; j < 16; j += 4) { Indexes[indexOffset++] = geomOffset + j; Indexes[indexOffset++] = (geomOffset + 1) + j; Indexes[indexOffset++] = (geomOffset + 2) + j; Indexes[indexOffset++] = (geomOffset + 2) + j; Indexes[indexOffset++] = (geomOffset + 3) + j; Indexes[indexOffset++] = geomOffset + j; } Vector2 texScale = new Vector2(2 / 3f, 1f); Geom[geomOffset++] = new TerrainVertex(tl, topCol.ToVector4() * darken, new Vector2(tl.X, tl.Z * -1) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(tr, topCol.ToVector4() * darken, new Vector2(tr.X, tr.Z * -1) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(m_tr, topCol.ToVector4(), new Vector2(m_tr.X, m_tr.Z * -1) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(m_tl, topCol.ToVector4(), new Vector2(m_tl.X, m_tl.Z * -1) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(tr, rightCol.ToVector4() * darken, new Vector2(tr.Z, tr.X) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(br, rightCol.ToVector4() * darken, new Vector2(br.Z, br.X) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(m_br, rightCol.ToVector4(), new Vector2(m_br.Z, m_br.X) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(m_tr, rightCol.ToVector4(), new Vector2(m_tr.Z, m_tr.X) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(br, btmCol.ToVector4() * darken, new Vector2(br.X, br.Z) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(bl, btmCol.ToVector4() * darken, new Vector2(bl.X, bl.Z) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(m_bl, btmCol.ToVector4(), new Vector2(m_bl.X, m_bl.Z) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(m_br, btmCol.ToVector4(), new Vector2(m_br.X, m_br.Z) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(bl, leftCol.ToVector4() * darken, new Vector2(bl.Z, bl.X * -1) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(tl, leftCol.ToVector4() * darken, new Vector2(tl.Z, tl.X * -1) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(m_tl, leftCol.ToVector4(), new Vector2(m_tl.Z, m_tl.X * -1) * texScale, 0); Geom[geomOffset++] = new TerrainVertex(m_bl, leftCol.ToVector4(), new Vector2(m_bl.Z, m_bl.X * -1) * texScale, 0); } var result = new RoofDrawGroup(); if (numPrimitives > 0) { result.VertexBuffer = new VertexBuffer(device, typeof(TerrainVertex), Geom.Length, BufferUsage.None); if (Geom.Length > 0) { result.VertexBuffer.SetData(Geom); } result.IndexBuffer = new IndexBuffer(device, IndexElementSize.ThirtyTwoBits, sizeof(int) * Indexes.Length, BufferUsage.None); if (Geom.Length > 0) { result.IndexBuffer.SetData(Indexes); } } result.NumPrimitives = numPrimitives; Drawgroups[level - 2] = result; }