void UpdateVertexBuffer() { if (m_env == null) { RemoveAndDispose(ref m_vertexBuffer); m_vertexList = null; return; } var envContents = m_env.Contents; if (m_vertexList != null && envContents.Count > m_vertexList.Count) { m_vertexList = null; } if (m_vertexList == null) { m_vertexList = new VertexList <SceneryVertex>(envContents.Count * 2); } IntGrid3 viewGrid = m_viewGridProvider.ViewGrid; m_vertexList.Clear(); foreach (var ob in envContents.OfType <ConcreteObject>()) { if (viewGrid.Contains(ob.Location) == false) { continue; } var c = ob.Color; if (c == GameColor.None) { c = ob.Material.Color; } m_vertexList.Add(new SceneryVertex(ob.Location.ToVector3(), ToColor(c), (uint)ob.SymbolID)); } if (m_vertexList.Count > 0) { if (m_vertexBuffer == null || m_vertexBuffer.ElementCount < m_vertexList.Count) { RemoveAndDispose(ref m_vertexBuffer); m_vertexBuffer = ToDispose(SharpDX.Toolkit.Graphics.Buffer.Vertex.New <SceneryVertex>(this.GraphicsDevice, m_vertexList.Count)); } m_vertexBuffer.SetData(m_vertexList.Data, 0, m_vertexList.Count); } }
public void UpdateSceneryVertexBuffer(GraphicsDevice device, VertexList <SceneryVertex> vertexList) { if (vertexList.Count == 0) { return; } if (m_sceneryVertexBuffer == null || m_sceneryVertexBuffer.ElementCount < vertexList.Count) { Utilities.Dispose(ref m_sceneryVertexBuffer); m_sceneryVertexBuffer = Buffer.Vertex.New <SceneryVertex>(device, vertexList.Data.Length); } m_sceneryVertexBuffer.SetData(vertexList.Data, 0, vertexList.Count); }
void CreateCube(IntVector3 p, Direction visibleFaces, ref FaceTexture baseTexture, ref FaceTexture topTexture, VertexList <TerrainVertex> vertexList, Direction sliceFaces) { var offset = p - this.ChunkOffset; int sides = (int)visibleFaces; for (int side = 0; side < 6 && sides != 0; ++side, sides >>= 1) { if ((sides & 1) == 0) { continue; } var vertices = s_cubeFaceInfo[side].Vertices; IntVector3 v0, v1, v2, v3; v0 = vertices[0] + offset; v1 = vertices[1] + offset; v2 = vertices[2] + offset; v3 = vertices[3] + offset; Direction dir = (Direction)(1 << side); bool isSliceFace = (sliceFaces & dir) != 0; int occ0, occ1, occ2, occ3; if (isSliceFace) { occ0 = occ1 = occ2 = occ3 = 0; } else { GetOcclusionsForFace(p, (DirectionOrdinal)side, out occ0, out occ1, out occ2, out occ3); } var tex = side == (int)DirectionOrdinal.PositiveZ ? topTexture : baseTexture; byte sliceHack = isSliceFace ? (byte)1 : (byte)0; var vd = new TerrainVertex(v0, v1, v2, v3, occ0, occ1, occ2, occ3, tex, sliceHack); vertexList.Add(vd); } }
void HandleVoxel(IntVector3 p, ref Voxel vox, ref IntGrid3 viewGrid, Direction visibleChunkFaces, VertexList <TerrainVertex> vertexList) { // Faces that are visible due to viewgrid Direction sliceFaces = GetVoxelSliceDirections(p, ref viewGrid) & visibleChunkFaces; // Faces that are drawn (if there's something to draw) Direction visibleFaces = (vox.VisibleFaces | sliceFaces) & visibleChunkFaces; if (visibleFaces == 0) { return; } FaceTexture baseTexture, topTexture; GetTextures(p, ref vox, out baseTexture, out topTexture, sliceFaces); CreateCube(p, visibleFaces, ref baseTexture, ref topTexture, vertexList, sliceFaces); }
public void GenerateVertices(ref IntGrid3 viewGrid, IntVector3 cameraChunkPos, VertexList <TerrainVertex> terrainVertexList, VertexList <SceneryVertex> sceneryVertexList) { terrainVertexList.Clear(); sceneryVertexList.Clear(); var diff = cameraChunkPos - this.ChunkPosition; Direction visibleChunkFaces = 0; if (diff.X >= 0) { visibleChunkFaces |= Direction.PositiveX; } if (diff.X <= 0) { visibleChunkFaces |= Direction.NegativeX; } if (diff.Y >= 0) { visibleChunkFaces |= Direction.PositiveY; } if (diff.Y <= 0) { visibleChunkFaces |= Direction.NegativeY; } if (diff.Z >= 0) { visibleChunkFaces |= Direction.PositiveZ; } if (diff.Z <= 0) { visibleChunkFaces |= Direction.NegativeZ; } GenerateVertices(ref viewGrid, visibleChunkFaces, terrainVertexList, sceneryVertexList); this.VertexCount = terrainVertexList.Count; this.SceneryVertexCount = sceneryVertexList.Count; }
public void UpdateVertexBuffer(GraphicsDevice device, VertexList <TerrainVertex> vertexList) { if (vertexList.Count == 0) { return; } if (m_vertexBuffer == null || m_vertexBuffer.ElementCount < vertexList.Count) { if (vertexList.Count > m_maxVertices) { m_maxVertices = vertexList.Count; } //System.Diagnostics.Trace.TraceError("Alloc {0}: {1} verts", this.ChunkOffset, m_maxVertices); Utilities.Dispose(ref m_vertexBuffer); m_vertexBuffer = Buffer.Vertex.New <TerrainVertex>(device, m_maxVertices); } m_vertexBuffer.SetData(vertexList.Data, 0, vertexList.Count); }
void CreateUndefinedChunk(ref IntGrid3 viewGrid, ref IntGrid3 chunkGrid, VertexList <TerrainVertex> vertexList, Direction visibleChunkFaces) { // Faces that are visible due to viewgrid Direction sliceFaces = GetGridSliceDirections(ref chunkGrid, ref viewGrid) & visibleChunkFaces; // Only faces revealed by viewgrid are visible Direction visibleFaces = sliceFaces; if (visibleFaces == 0) { return; } int sides = (int)visibleFaces; FaceTexture tex = Chunk.UndefinedFaceTexture; const int occlusion = 0; var offset = chunkGrid.Corner1 - this.ChunkOffset; var size = new IntVector3(chunkGrid.Size.Width, chunkGrid.Size.Height, chunkGrid.Size.Depth); // All faces are revealed by viewgrid byte sliceHack = (byte)1; if (Chunk.UseBigUnknownChunk) { /* Note: Using chunk sized quads causes t-junction problems */ for (int side = 0; side < 6 && sides != 0; ++side, sides >>= 1) { if ((sides & 1) == 0) { continue; } var vertices = s_cubeFaceInfo[side].Vertices; IntVector3 v0 = vertices[0] * size + offset; IntVector3 v1 = vertices[1] * size + offset; IntVector3 v2 = vertices[2] * size + offset; IntVector3 v3 = vertices[3] * size + offset; var vd = new TerrainVertex(v0, v1, v2, v3, occlusion, occlusion, occlusion, occlusion, tex, sliceHack); vertexList.Add(vd); } } else { for (int side = 0; side < 6 && sides != 0; ++side, sides >>= 1) { if ((sides & 1) == 0) { continue; } int d0 = side / 2; int d1 = (d0 + 1) % 3; int d2 = (d0 + 2) % 3; bool posFace = (side & 1) == 1; var vertices = s_cubeFaceInfo[side].Vertices; IntVector3 v0 = vertices[0] + offset; IntVector3 v1 = vertices[1] + offset; IntVector3 v2 = vertices[2] + offset; IntVector3 v3 = vertices[3] + offset; var vec1 = new IntVector3(); vec1[d1] = 1; var vec2 = new IntVector3(); vec2[d2] = 1; for (int v = 0; v < size[d1]; ++v) { for (int u = 0; u < size[d2]; ++u) { var off = vec1 * v + vec2 * u; if (posFace) { off[d0] = size[d0] - 1; } var vd = new TerrainVertex(v0 + off, v1 + off, v2 + off, v3 + off, occlusion, occlusion, occlusion, occlusion, tex, sliceHack); vertexList.Add(vd); } } } } }
static void HandleTree(VertexList <SceneryVertex> sceneryVertexList, TileData td, ref IntVector3 pos) { SymbolID symbol; Color color; switch (td.ID) { case TileID.Tree: switch (td.MaterialID) { case MaterialID.Fir: symbol = SymbolID.ConiferousTree; break; case MaterialID.Pine: symbol = SymbolID.ConiferousTree2; break; case MaterialID.Birch: symbol = SymbolID.DeciduousTree; break; case MaterialID.Oak: symbol = SymbolID.DeciduousTree2; break; default: throw new Exception(); } break; case TileID.Sapling: switch (td.MaterialID) { case MaterialID.Fir: symbol = SymbolID.ConiferousSapling; break; case MaterialID.Pine: symbol = SymbolID.ConiferousSapling2; break; case MaterialID.Birch: symbol = SymbolID.DeciduousSapling; break; case MaterialID.Oak: symbol = SymbolID.DeciduousSapling2; break; default: throw new Exception(); } break; case TileID.DeadTree: symbol = SymbolID.DeadTree; break; default: throw new Exception(); } color = Color.ForestGreen; sceneryVertexList.Add(new SceneryVertex(pos.ToVector3(), Color.LightGreen, (uint)symbol)); }
void GenerateVertices(ref IntGrid3 viewGrid, Direction visibleChunkFaces, VertexList <TerrainVertex> terrainVertexList, VertexList <SceneryVertex> sceneryVertexList) { IntGrid3 chunkGrid = viewGrid.Intersect(new IntGrid3(this.ChunkOffset, Chunk.ChunkSize)); // is the chunk inside frustum, but outside the viewgrid? if (chunkGrid.IsNull) { return; } if (m_scanned == false) { ScanForAllEmptyOrUndefined(); } if (this.IsAllEmpty) { return; } if (this.IsAllUndefined) { CreateUndefinedChunk(ref viewGrid, ref chunkGrid, terrainVertexList, visibleChunkFaces); return; } if (m_voxelMap == null) { FillVoxelMap(); } // Draw from up to down to avoid overdraw for (int z = chunkGrid.Z2; z >= chunkGrid.Z1; --z) { for (int y = chunkGrid.Y1; y <= chunkGrid.Y2; ++y) { for (int x = chunkGrid.X1; x <= chunkGrid.X2; ++x) { var p = new IntVector3(x, y, z); var td = m_map.GetTileData(p); if (td.WaterLevel == 0) { if (td.IsEmpty) { continue; } } var pos = p - this.ChunkOffset; if (td.HasTree) { // Add tree as scenery vertex HandleTree(sceneryVertexList, td, ref pos); continue; } if (td.IsGreen) // XXX { continue; } var vox = m_voxelMap.Grid[pos.Z, pos.Y, pos.X]; HandleVoxel(p, ref vox, ref viewGrid, visibleChunkFaces, terrainVertexList); } } } }