/// <summary> /// Initializes the VBO but does not modify graphics state /// </summary> public void Prerender(Structure structure, BlockAtlas blockAtlas) { _vbi.Reset(); for (var pass = 0; pass <= 1; pass++) { for (var x = X * 16; x < X * 16 + 16; x++) { for (var y = 0; y < 256; y++) { for (var z = Z * 16; z < Z * 16 + 16; z++) { if (!structure.Contains(x, y, z)) { continue; } var block = structure[x, y, z]; if (block == null) { continue; } var blockData = blockAtlas[block.Id]; if (blockData == null || blockData.Properties.Render == "none" || blockData.Textures.Count == 0) { continue; } ChunkRenderer.Render(structure, x, y, z, blockAtlas, _vbi, pass); } } } } }
protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); GraphicsDevice.BlendState = BlendState.Opaque; GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.RasterizerState = rasterizerState; chunkRenderer.Render(Camera.View, Camera.Projection, Matrix.Identity); var deltaTime = (float)gameTime.ElapsedGameTime.TotalSeconds; _frameCounter.Update(deltaTime); var fps = string.Format("FPS: {0}" + Environment.NewLine + "Position: {1}" + Environment.NewLine + "Allocated_Memory: " + ((GC.GetTotalMemory(false) / 1024f) / 1024f) + "MB", _frameCounter.AbnormalFramesPerSecond, Camera.CameraPosition); if (currentChunk != null) { for (int j = 0; j < currentChunk.BoundingBoxes.Count; j++) { BoundingBoxRenderer.Render(currentChunk.BoundingBoxes[j], GraphicsDevice, Camera.View, Camera.Projection, Color.Red); } } spriteBatch.Begin(); spriteBatch.DrawString(_spriteFont, fps, new Vector2(1, 1), Color.Red); if (!chunkRenderer.IsReady) { spriteBatch.DrawString(_spriteFont, "Loading...", new Vector2(1920 / 2 - 50, 1080 / 2), Color.Black); } spriteBatch.End(); base.Draw(gameTime); }
// Create a chunk public void CreateChunkMesh(int x, int y, int z, ChunkObject chunkObject) { chunkObject.ChunkMesh.mesh = ChunkRenderer.Render(_chunks[x, y, z]); chunkObject.ChunkCollider.sharedMesh = chunkObject.ChunkMesh.mesh; _chunks[x, y, z].ChunkObject = chunkObject; }
public void Render() { Camera.Apply(); _chunkRenderer.Render(Camera, Player, Level); }
public void RefreshChunkMesh() { _chunkObject.ChunkMesh.mesh.Clear(); _chunkObject.ChunkMesh.mesh = ChunkRenderer.Render(this); _chunkObject.ChunkCollider.sharedMesh = _chunkObject.ChunkMesh.mesh; }
// Load all chunks defined in loadedChunks[] array // true = load chunks smoothly in a spiral order // false = load all chunks at once. This causes high lag. IEnumerator LoadChunks(bool async) { // Debug System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); Debug.Log("Loading chunks. (Total: " + loadDimension * loadDimension + ")"); foreach (ChunkTransform chunkTransform in loadedChunks) { Chunk chunk; // Create gameObject if not exists if (GetChunk(chunkTransform) == null) { // Blocks GameObject obj = new GameObject(chunkTransform.ToString()); obj.transform.parent = parentOfChunks; obj.transform.position = chunkTransform.GetBlockPosition(); obj.AddComponent <MeshFilter>(); obj.AddComponent <MeshRenderer>(); obj.AddComponent <MeshCollider>(); chunk = obj.AddComponent <Chunk>(); chunk.SetTransform(chunkTransform); // Liquids GameObject chunkLiquids = new GameObject("Liquids"); chunkLiquids.transform.position = chunk.transform.position; chunkLiquids.transform.SetParent(chunk.transform); chunkLiquids.AddComponent <MeshFilter>(); chunkLiquids.AddComponent <MeshRenderer>(); // Customs GameObject chunkCustoms = new GameObject("Customs"); chunkCustoms.transform.position = chunk.transform.position; chunkCustoms.transform.SetParent(chunk.transform); chunkCustoms.SetActive(false); } else { chunk = GetChunk(chunkTransform); } // Generate / load from file if (!chunk.generated) { // Check if file exists if (save.ChunkFileExists(chunkTransform)) { // Load chunk from file chunk.chunkData = save.LoadChunk(chunkTransform); chunk.decorated = true; } else { // Generate terrainGenerator.Generate(chunk); } chunk.generated = true; } // Destroy chunks that are too far away if (Config.UNLOAD_FAR_CHUNKS) { for (int i = 0; i < parentOfChunks.childCount; ++i) { // Chunk's world position Vector3 t = parentOfChunks.GetChild(i).position; if (Vector2Int.Distance(playerChunk * 16, new Vector2Int((int)t.x, (int)t.z)) > unloadDistance * 16) { Chunk unload = parentOfChunks.GetChild(i).gameObject.GetComponent <Chunk>(); // Save if there are unsaved changes if (chunk.unsaved) { save.SaveChunk(unload); } // Unload Destroy(unload.gameObject); } } } // If true, load one chunk and continue at next frame if (async) { yield return(null); } } // Link chunks foreach (ChunkTransform chunkTransform in renderedChunks) { Chunk chunk = GetChunk(chunkTransform); chunk.SetNext( GetChunk(chunkTransform.GetRight()), GetChunk(chunkTransform.GetLeft()), GetChunk(chunkTransform.GetFront()), GetChunk(chunkTransform.GetBack()) ); } // Decorate chunks for (int i = 0; i < renderedChunks.Length; i++) { if (GetChunk(renderedChunks[i]) != null) { Chunk chunk = GetChunk(renderedChunks[i]); if (!chunk.decorated && !chunk.rendered) { terrainGenerator.Decorate(chunk); chunk.decorated = true; } } // If true, decorate only one chunk and continue on next frame if (async) { yield return(null); } } // Render chunks for (int i = 0; i < parentOfChunks.childCount; ++i) { Chunk chunk = parentOfChunks.GetChild(i).gameObject.GetComponent <Chunk>(); // Render if chunk has been modified or it is not rendered yet if (chunk.pendingRefresh || !chunk.rendered && chunk.generated && chunk.decorated) { chunkRenderer.Render(chunk); chunk.rendered = true; chunk.pendingRefresh = false; } // If true, render only one chunk and continue on next frame if (async) { yield return(null); } } // Debug stopwatch.Stop(); long minutes = (stopwatch.ElapsedMilliseconds / 1000) / 60; int seconds = (int)((stopwatch.ElapsedMilliseconds / 1000) % 60); Debug.Log("Chunks rendered. (" + minutes + "m " + seconds + "s)"); }