public static UniqueRender Store(int[] data, RenderTarget2D target, RenderTarget2D depth) { long hash = GetHash(data); UniqueRenderPair urp; if (m_RenderPairs.Keys.Contains(hash) && m_RenderPairs[hash] == null /* is waiting */) { // Remove before new store. FilteredConsole.WriteLine(FilterCategory.UniqueRendering, "Releasing waiting result."); m_RenderPairs.Remove(hash); } if (m_RenderPairs.Keys.Contains(hash)) { // This is a copy of an existing render, free the passed parameters. target.Dispose(); depth.Dispose(); urp = m_RenderPairs[hash]; urp.ReferenceCount += 1; FilteredConsole.WriteLine(FilterCategory.UniqueRendering, "Storing existing render result (ref+1)."); } else { urp = new UniqueRenderPair(); urp.ReferenceCount = 1; urp.Target = target; urp.DepthMap = depth; m_RenderPairs.Add(hash, urp); FilteredConsole.WriteLine(FilterCategory.UniqueRendering, "Storing new render result (ref=1,mem+1)."); } return(new UniqueRender(urp.Target, urp.DepthMap)); }
public static void DiscardUnneededChunks() { /* Providing chunk data is expensive; there's no need to * do it if the specified chunk isn't actually going to be * rendered onto the screen. */ if (FilteredFeatures.IsEnabled(Feature.OptimizeChunkProviding)) { int discarded = 0; foreach (ProvideTask rt in m_Tasks.ToArray()) { if (!ChunkRenderer.HasNeeded(rt.Chunk)) { m_Skip.Add(rt); discarded++; } } if (discarded > 0) { FilteredConsole.WriteLine(FilterCategory.Optimization, "SKIPPED PROVIDING " + discarded + " UNNEEDED CHUNKS!"); discarded = 0; } } }
public void DiscardTexture() { // Force the graphics texture to be discarded. if (this.m_RenderTask != null) { // The texture was rendered, but not pushed into the unique // render cache so we free it directly. RenderTarget2D target = this.m_RenderTask.Result; RenderTarget2D depth = this.m_RenderTask.DepthMap; this.m_RenderTask = null; if (target != null) { target.Dispose(); } if (depth != null) { depth.Dispose(); } } else if (this.m_UniqueRender != null && (this.m_UniqueRender.Target != null || this.m_UniqueRender.DepthMap != null)) { // Release from the unique render cache. UniqueRenderCache.Release(this.m_RawData); } // Send message about texture being discarded. FilteredConsole.WriteLine(FilterCategory.GraphicsMemoryUsage, "Textures discarded for chunk " + this.X + ", " + this.Y + "."); }
public static void StoreWaiting(int[] data) { long hash = GetHash(data); if (m_RenderPairs.Keys.Contains(hash)) { return; } FilteredConsole.WriteLine(FilterCategory.UniqueRendering, "Storing waiting render result."); m_RenderPairs.Add(hash, null); }
public Chunk(ILevel level, ChunkOctree octree, long x, long y, long z) { this.m_Octree = octree; this.X = x; this.Y = y; this.Z = z; this.m_Octree.Set(this); this.m_Blocks = new Block[Chunk.Width, Chunk.Height, Chunk.Depth]; this.m_RawData = new int[Chunk.Width * Chunk.Height * Chunk.Depth]; this.m_DiskLevel = level; FilteredConsole.WriteLine(FilterCategory.ChunkValidation, "Chunk created for " + x + ", " + y + ", " + z + "."); this.Generate(); }
public override void Update(World world) { //this.X = 0;// (float)(0 + Math.Sin(this.m_RotateCounter) * 100); //this.Y = 0; //this.Z = 32f; //if (this.SearchForTerrain) //{ //this.Z -= 1f; //} this.m_RotateCounter += 0.1; FilteredConsole.WriteLine(FilterCategory.Player, "player x/y/z is " + X + ", " + Y + "," + Z + "."); base.Update(world); }
public static void ReleaseWaiting(int[] data) { long hash = GetHash(data); if (!m_RenderPairs.Keys.Contains(hash)) { throw new InvalidOperationException(); } UniqueRenderPair urp = m_RenderPairs[hash]; if (urp != null) { return; } m_RenderPairs.Remove(hash); FilteredConsole.WriteLine(FilterCategory.UniqueRendering, "Releasing waiting result."); }
public static void DiscardUnusedChunks() { /* If the chunk wasn't in the last used list, we no longer care * to render it to a texture, so discard from there. */ if (FilteredFeatures.IsEnabled(Feature.OptimizeChunkRendering)) { int discarded = 0; foreach (RenderTask rt in m_Tasks.ToArray()) { if (!m_NeededChunks.Contains(rt.Chunk)) { m_Tasks.Remove(rt); discarded++; } } if (discarded > 0) { FilteredConsole.WriteLine(FilterCategory.Optimization, "SKIPPED RENDERING " + discarded + " UNNEEDED CHUNKS!"); discarded = 0; } } /* We can't keep every chunk's texture loaded into memory or * else we quickly run out of graphics RAM to store everything. */ if (FilteredFeatures.IsEnabled(Feature.DiscardChunkTextures)) { int discarded = 0; while (m_LoadedChunks.Count > LastRenderedCountOnScreen + m_LastRenderedBuffer) { m_LoadedChunks[0].DiscardTexture(); m_LoadedChunks.RemoveAt(0); discarded++; } if (discarded > 0) { FilteredConsole.WriteLine(FilterCategory.Optimization, "DISCARDED " + discarded + " TEXTURES FROM MEMORY!"); } } }
public static UniqueRender Grab(int[] data) { long hash = GetHash(data); if (!m_RenderPairs.Keys.Contains(hash)) { throw new InvalidOperationException(); } UniqueRenderPair urp = m_RenderPairs[hash]; if (urp == null) { throw new InvalidOperationException(); } urp.ReferenceCount += 1; FilteredConsole.WriteLine(FilterCategory.UniqueRendering, "Grabbing existing render result (ref+1)."); return(new UniqueRender(urp.Target, urp.DepthMap)); }
public static void Release(int[] data) { long hash = GetHash(data); if (!m_RenderPairs.Keys.Contains(hash)) { throw new InvalidOperationException(); } UniqueRenderPair urp = m_RenderPairs[hash]; urp.ReferenceCount -= 1; if (urp.ReferenceCount == 0) { urp.Target.Dispose(); urp.DepthMap.Dispose(); m_RenderPairs.Remove(hash); FilteredConsole.WriteLine(FilterCategory.UniqueRendering, "Releasing and freeing render result (ref-1,mem-1)."); } else { FilteredConsole.WriteLine(FilterCategory.UniqueRendering, "Releasing render result (ref-1)."); } }
private static void ProvideBlocksToChunk(ProvideTask task) { if (m_ResultLayer == null) { throw new InvalidOperationException("No 3D store result layer was found in the world configuration."); } if (task == null) { return; } DateTime start = DateTime.Now; FilteredConsole.WriteLine(FilterCategory.OptimizationTiming, "Started with 0ms."); if (m_CurrentProvideState == null) { ProvideState ps = new ProvideState(); ps.Blocks = task.Blocks; ps.RawData = task.RawData; ps.Info = task.Info; //ps.Z = task.Chunk.GlobalZ; ps.ProvideTask = task; ps.OnSkipCallback = task.OnSkipCallback; ps.OnGenerationCallback = task.OnGenerationCallback; m_CurrentProvideState = ps; } // Generate or load data. int[] data = null; int computations; if (m_CurrentProvideState.ProvideTask.Info.LevelDisk == null || !m_CurrentProvideState.ProvideTask.Info.LevelDisk.HasRegion( m_CurrentProvideState.Info.Bounds.X, m_CurrentProvideState.Info.Bounds.Y, m_CurrentProvideState.Info.Bounds.Z, m_CurrentProvideState.Info.Bounds.Width, m_CurrentProvideState.Info.Bounds.Height, m_CurrentProvideState.Info.Bounds.Depth)) { data = m_ResultLayer.GenerateData( m_CurrentProvideState.Info.Bounds.X, m_CurrentProvideState.Info.Bounds.Y, m_CurrentProvideState.Info.Bounds.Z, (int)m_CurrentProvideState.Info.Bounds.Width, (int)m_CurrentProvideState.Info.Bounds.Height, (int)m_CurrentProvideState.Info.Bounds.Depth, out computations); } else { data = m_CurrentProvideState.ProvideTask.Info.LevelDisk.ProvideRegion( m_CurrentProvideState.Info.Bounds.X, m_CurrentProvideState.Info.Bounds.Y, m_CurrentProvideState.Info.Bounds.Z, m_CurrentProvideState.Info.Bounds.Width, m_CurrentProvideState.Info.Bounds.Height, m_CurrentProvideState.Info.Bounds.Depth); } // Set up block mappings. for (int i = 0; i < m_CurrentProvideState.Info.Bounds.Width; i++) { for (int j = 0; j < m_CurrentProvideState.Info.Bounds.Height; j++) { for (int k = 0; k < m_CurrentProvideState.Info.Bounds.Depth; k++) { int id = data[i + j * m_CurrentProvideState.Info.Bounds.Width + k * m_CurrentProvideState.Info.Bounds.Width * m_CurrentProvideState.Info.Bounds.Height]; m_CurrentProvideState.RawData[i + j * m_CurrentProvideState.Info.Bounds.Width + k * m_CurrentProvideState.Info.Bounds.Width * m_CurrentProvideState.Info.Bounds.Height] = id; if (id == -1) { m_CurrentProvideState.Blocks[i, j, k] = null; } else { try { m_CurrentProvideState.Blocks[i, j, k] = Block.BlockIDMapping[data[i + j * m_CurrentProvideState.Info.Bounds.Width + k * m_CurrentProvideState.Info.Bounds.Width * m_CurrentProvideState.Info.Bounds.Height]]; } catch (KeyNotFoundException) { m_CurrentProvideState.Blocks[i, j, k] = null; } } } } } FilteredConsole.WriteLine(FilterCategory.OptimizationTiming, "Provided " + /*zcount +*/ " levels to chunk in " + (DateTime.Now - start).TotalMilliseconds + "ms."); // Signal finish. m_CurrentProvideState.OnGenerationCallback(); m_CurrentProvideState = null; }
private static void RenderTilesToTexture(RenderTask task, GameTime gt, GameContext context) { /* Our world is laid out in memory in terms of X / Y, but * we are rendering isometric, which means that the rendering * order for tiles must be like so: * * North * 1 3 5 9 13 19 25 * 2 6 10 14 20 26 32 * 4 8 15 21 27 33 37 * East 7 12 18 28 34 38 42 West * 11 17 24 31 39 43 45 * 16 23 30 36 41 46 48 * 22 29 35 40 44 47 49 * South * * We also need to account for situations where the user rotates * the isometric view. */ /* * North * 0 0.5 1 1.5 2 2.5 3 * -0.5 0 0.5 1 1.5 2 2.5 * -1 -0.5 0 0.5 1 1.5 2 * East -1.5 -1 -0.5 0 0.5 1 1.5 West * -2 -1.5 -1 -0.5 0 0.5 1 * -2.5 -2 -1.5 -1 -0.5 0 0.5 * -3 -2.5 -2 -1.5 -1 -0.5 0 * South * * v = (x - y) / 2.0 */ int DEBUG_ZOFFSET = 0;//TileIsometricifier.TILE_CUBE_HEIGHT * Settings.ChunkDepth - 200; if (m_CurrentRenderState == null) { RenderState rs = new RenderState(); rs.ZTop = Chunk.Depth; rs.ZBottom = 0; rs.ChunkTarget = RenderTargetFactory.Create( m_GraphicsDevice, TileIsometricifier.TILE_TOP_WIDTH * Chunk.Width, TileIsometricifier.TILE_TOP_HEIGHT * Chunk.Width + TileIsometricifier.TILE_CUBE_HEIGHT * Chunk.Depth + TileIsometricifier.CHUNK_HEIGHT_ALLOWANCE, true, SurfaceFormat.Bgra5551, DepthFormat.None); rs.ChunkDepthMap = RenderTargetFactory.Create( m_GraphicsDevice, TileIsometricifier.TILE_TOP_WIDTH * Chunk.Width, TileIsometricifier.TILE_TOP_HEIGHT * Chunk.Width + TileIsometricifier.TILE_CUBE_HEIGHT * Chunk.Depth + TileIsometricifier.CHUNK_HEIGHT_ALLOWANCE, true, SurfaceFormat.Bgra5551, DepthFormat.None); FilteredConsole.WriteLine(FilterCategory.GraphicsMemoryUsage, "Allocated textures for chunk " + task.Chunk.X + ", " + task.Chunk.Y + ", " + task.Chunk.Z + "."); m_GraphicsDevice.SetRenderTarget(rs.ChunkTarget); if (FilteredFeatures.IsEnabled(Feature.DebugChunkBackground)) { Color c = new Color( (float)m_DebugRandomizer.NextDouble(), (float)m_DebugRandomizer.NextDouble(), (float)m_DebugRandomizer.NextDouble() ); m_GraphicsDevice.Clear(ClearOptions.Target, c, 1.0f, 0); } else { m_GraphicsDevice.Clear(ClearOptions.Target, Color.Transparent, 1.0f, 0); } rs.ChunkDepthMapCleared = false; rs.SpriteBatch = new SpriteBatch(m_GraphicsDevice); rs.CurrentZ = rs.ZBottom; rs.RenderTask = task; rs.CellRenderOrder = GetCellRenderOrder(RenderToNE); rs.RenderMode = 0; m_CurrentRenderState = rs; } if (m_CurrentRenderState.RenderMode == 0 /* chunk texture */) { m_GraphicsDevice.SetRenderTarget(m_CurrentRenderState.ChunkTarget); m_CurrentRenderState.SpriteBatch.Begin(SpriteSortMode.Immediate, null); int count = 0; int zcount = 0; while (m_CurrentRenderState.CurrentZ < m_CurrentRenderState.ZTop && gt.ElapsedGameTime.TotalMilliseconds < Performance.RENDERING_MILLISECONDS) { int z = m_CurrentRenderState.CurrentZ; int rcx = TileIsometricifier.TILE_TOP_WIDTH * Chunk.Width / 2 - TileIsometricifier.TILE_TOP_WIDTH / 2; int rcy = TileIsometricifier.TILE_CUBE_HEIGHT * Chunk.Depth + TileIsometricifier.TILE_TOP_HEIGHT * Chunk.Width / 2 - DEBUG_ZOFFSET; int rw = TileIsometricifier.TILE_TOP_WIDTH; int rh = TileIsometricifier.TILE_TOP_HEIGHT / 2; for (int i = 0; i < m_CurrentRenderState.CellRenderOrder.Length; i++) { // Calculate the X / Y of the tile in the grid. int x = m_CurrentRenderState.CellRenderOrder[i] % RenderWidth; int y = m_CurrentRenderState.CellRenderOrder[i] / RenderWidth; // Calculate the render position on screen. int rx = rcx + (int)((x - y) / 2.0 * rw); int ry = rcy + (x + y) * rh - (rh / 2 * (RenderWidth + RenderHeight)) - (z * TileIsometricifier.TILE_CUBE_HEIGHT); Block b = task.Chunk.m_Blocks[x, y, z]; if (b == null) { if (FilteredFeatures.IsEnabled(Feature.DebugChunkTiles)) { m_CurrentRenderState.SpriteBatch.Draw( task.Textures["tiles.grass"], new Vector2(rx, ry), Color.White ); } continue; } Tile t = b.Tile; if (t.Image == null) { if (FilteredFeatures.IsEnabled(Feature.DebugChunkTiles)) { m_CurrentRenderState.SpriteBatch.Draw( task.Textures["tiles.dirt"], new Vector2(rx, ry), Color.White ); } continue; } Color col = new Color(1f, 1f, 1f, 1f).ToPremultiplied(); if (task.Chunk.X == 0 && task.Chunk.Y == 0 && x == 0 && y == 0) { col = new Color(1f, 0f, 0f, 1f).ToPremultiplied(); } if (FilteredFeatures.IsEnabled(Feature.DebugChunkTiles)) { m_CurrentRenderState.SpriteBatch.Draw( task.Textures[t.Image], new Vector2(rx, ry), col ); } if (FilteredFeatures.IsEnabled(Feature.RenderCellTops)) { m_CurrentRenderState.SpriteBatch.Draw( task.Textures[t.Image + ".isometric.top"], new Rectangle(rx, ry, TileIsometricifier.TILE_TOP_WIDTH, TileIsometricifier.TILE_TOP_HEIGHT), null, col, 0, new Vector2(0, 0), SpriteEffects.None, 0 // TODO: Use this to correct rendering artifacts. ); } if (FilteredFeatures.IsEnabled(Feature.RenderCellSides)) { m_CurrentRenderState.SpriteBatch.Draw( task.Textures[t.Image + ".isometric.sideL"], new Rectangle(rx, ry + TileIsometricifier.TILE_TOP_HEIGHT / 2, TileIsometricifier.TILE_SIDE_WIDTH, TileIsometricifier.TILE_SIDE_HEIGHT), null, col, 0, new Vector2(0, 0), SpriteEffects.None, 0 // TODO: Use this to correct rendering artifacts. ); m_CurrentRenderState.SpriteBatch.Draw( task.Textures[t.Image + ".isometric.sideR"], new Rectangle(rx + TileIsometricifier.TILE_TOP_WIDTH / 2, ry + TileIsometricifier.TILE_TOP_HEIGHT / 2, TileIsometricifier.TILE_SIDE_WIDTH, TileIsometricifier.TILE_SIDE_HEIGHT), null, col, 0, new Vector2(0, 0), SpriteEffects.None, 0 // TODO: Use this to correct rendering artifacts. ); } count++; } m_CurrentRenderState.CurrentZ++; zcount++; } FilteredConsole.WriteLine(FilterCategory.OptimizationTiming, "Rendered " + zcount + " levels, " + count + " cells to texture target in " + gt.ElapsedGameTime.Milliseconds + "ms."); m_CurrentRenderState.SpriteBatch.End(); m_GraphicsDevice.SetRenderTarget(null); } else if (m_CurrentRenderState.RenderMode == 1 /* depth map */ && FilteredFeatures.IsEnabled(Feature.IsometricOcclusion)) { m_GraphicsDevice.SetRenderTarget(m_CurrentRenderState.ChunkDepthMap); if (!m_CurrentRenderState.ChunkDepthMapCleared) { m_CurrentRenderState.SpriteBatch.Begin(SpriteSortMode.Immediate, null); m_GraphicsDevice.Clear(ClearOptions.Target, Color.Transparent, 1.0f, 0); m_CurrentRenderState.SpriteBatch.End(); m_CurrentRenderState.ChunkDepthMapCleared = true; } BlendState bs = new BlendState(); bs.AlphaBlendFunction = BlendFunction.Max; bs.AlphaSourceBlend = Blend.One; bs.AlphaDestinationBlend = Blend.One; bs.ColorBlendFunction = BlendFunction.Max; bs.ColorSourceBlend = Blend.One; bs.ColorDestinationBlend = Blend.One; m_CurrentRenderState.SpriteBatch.Begin(SpriteSortMode.Immediate, bs, null, null, null, context.Effects["IsometricDepthMap"]); context.Effects["IsometricDepthMap"].Parameters["RotationMode"].SetValue(RenderToNE); context.Effects["IsometricDepthMap"].CurrentTechnique.Passes[0].Apply(); int count = 0; int zcount = 0; while (m_CurrentRenderState.CurrentZ < m_CurrentRenderState.ZTop && gt.ElapsedGameTime.TotalMilliseconds < Performance.RENDERING_MILLISECONDS) { int z = m_CurrentRenderState.CurrentZ; int rcx = TileIsometricifier.TILE_TOP_WIDTH * Chunk.Width / 2 - TileIsometricifier.TILE_TOP_WIDTH / 2; int rcy = TileIsometricifier.TILE_CUBE_HEIGHT * Chunk.Depth + TileIsometricifier.TILE_TOP_HEIGHT * Chunk.Width / 2 - DEBUG_ZOFFSET; int rw = TileIsometricifier.TILE_TOP_WIDTH; int rh = TileIsometricifier.TILE_TOP_HEIGHT / 2; for (int i = 0; i < m_CurrentRenderState.CellRenderOrder.Length; i++) { // Calculate the X / Y of the tile in the grid. int x = m_CurrentRenderState.CellRenderOrder[i] % RenderWidth; int y = m_CurrentRenderState.CellRenderOrder[i] / RenderWidth; // Calculate the "depth" of the tile. int depth = x + y + z; // Calculate the render position on screen. int rx = rcx + (int)((x - y) / 2.0 * rw); int ry = rcy + (x + y) * rh - (rh / 2 * (RenderWidth + RenderHeight)) - (z * TileIsometricifier.TILE_CUBE_HEIGHT); Block b = task.Chunk.m_Blocks[x, y, z]; if (b == null) { continue; } Tile t = b.Tile; if (t.Image == null) { continue; } context.Effects["IsometricDepthMap"].Parameters["CellDepth"].SetValue((float)Math.Min(depth / 255f, 1.0f)); context.Effects["IsometricDepthMap"].CurrentTechnique.Passes[0].Apply(); m_CurrentRenderState.SpriteBatch.Draw( task.Textures[t.Image + ".isometric.top"], new Rectangle(rx, ry, TileIsometricifier.TILE_TOP_WIDTH, TileIsometricifier.TILE_TOP_HEIGHT), null, Color.White, 0, new Vector2(0, 0), SpriteEffects.None, 0 ); m_CurrentRenderState.SpriteBatch.Draw( task.Textures[t.Image + ".isometric.sideL"], new Rectangle(rx, ry + 12, TileIsometricifier.TILE_SIDE_WIDTH, TileIsometricifier.TILE_SIDE_HEIGHT), null, Color.White, 0, new Vector2(0, 0), SpriteEffects.None, 0 ); m_CurrentRenderState.SpriteBatch.Draw( task.Textures[t.Image + ".isometric.sideR"], new Rectangle(rx + 16, ry + 12, TileIsometricifier.TILE_SIDE_WIDTH, TileIsometricifier.TILE_SIDE_HEIGHT), null, Color.White, 0, new Vector2(0, 0), SpriteEffects.None, 0 ); count++; } m_CurrentRenderState.CurrentZ++; zcount++; } FilteredConsole.WriteLine(FilterCategory.OptimizationTiming, "Rendered " + zcount + " levels, " + count + " cells to texture target in " + gt.ElapsedGameTime.TotalMilliseconds + "ms."); m_CurrentRenderState.SpriteBatch.End(); m_GraphicsDevice.SetRenderTarget(null); } if (m_CurrentRenderState.CurrentZ == m_CurrentRenderState.ZTop) { if (m_CurrentRenderState.RenderMode < 1) { m_CurrentRenderState.CurrentZ = m_CurrentRenderState.ZBottom; m_CurrentRenderState.RenderMode++; } else { m_CurrentRenderState.RenderTask.Result = m_CurrentRenderState.ChunkTarget; m_CurrentRenderState.RenderTask.DepthMap = m_CurrentRenderState.ChunkDepthMap; m_CurrentRenderState.RenderTask.HasResult = true; m_CurrentRenderState = null; } } }
public T Get(long x, long y, long z) { FilteredConsole.Write(FilterCategory.OctreeGetTracing, "GET " + x + ", " + y + ", " + z + ""); PositionOctreeNode <T> current = this; while (current != null && current.m_CurrentDepth != current.m_MaximalDepth) { if ((x & current.GetMaskAtDepth()) == 0) { if ((y & current.GetMaskAtDepth()) == 0) { if ((z & current.GetMaskAtDepth()) == 0) { current = current.m_Nodes[0] ?? null; FilteredConsole.Write(FilterCategory.OctreeGetTracing, "0 - "); } else { current = current.m_Nodes[1] ?? null; FilteredConsole.Write(FilterCategory.OctreeGetTracing, "1 - "); } } else { if ((z & current.GetMaskAtDepth()) == 0) { current = current.m_Nodes[2] ?? null; FilteredConsole.Write(FilterCategory.OctreeGetTracing, "2 - "); } else { current = current.m_Nodes[3] ?? null; FilteredConsole.Write(FilterCategory.OctreeGetTracing, "3 - "); } } } else { if ((y & current.GetMaskAtDepth()) == 0) { if ((z & current.GetMaskAtDepth()) == 0) { current = current.m_Nodes[4] ?? null; FilteredConsole.Write(FilterCategory.OctreeGetTracing, "4 - "); } else { current = current.m_Nodes[5] ?? null; FilteredConsole.Write(FilterCategory.OctreeGetTracing, "5 - "); } } else { if ((z & current.GetMaskAtDepth()) == 0) { current = current.m_Nodes[6] ?? null; FilteredConsole.Write(FilterCategory.OctreeGetTracing, "6 - "); } else { current = current.m_Nodes[7] ?? null; FilteredConsole.Write(FilterCategory.OctreeGetTracing, "7 - "); } } } if (current != null && current.m_CurrentDepth % 8 == 0) { FilteredConsole.WriteLine(FilterCategory.OctreeGetTracing, ""); } } FilteredConsole.WriteLine(FilterCategory.OctreeGetTracing, ""); if (current == null) { return(null); } return(current.m_Value); }
public void Set(T value, long x, long y, long z) { FilteredConsole.Write(FilterCategory.OctreeSetTracing, "SET " + x + ", " + y + ", " + z + ""); PositionOctreeNode <T> current = this; while (current != null && current.m_CurrentDepth != current.m_MaximalDepth) { if ((x & current.GetMaskAtDepth()) == 0) { if ((y & current.GetMaskAtDepth()) == 0) { if ((z & current.GetMaskAtDepth()) == 0) { if (current.m_Nodes[0] == null) { current.m_Nodes[0] = current.CreateSubnode(-1, -1, -1); } current = current.m_Nodes[0]; FilteredConsole.Write(FilterCategory.OctreeSetTracing, "0 - "); } else { if (current.m_Nodes[1] == null) { current.m_Nodes[1] = current.CreateSubnode(-1, -1, 1); } current = current.m_Nodes[1]; FilteredConsole.Write(FilterCategory.OctreeSetTracing, "1 - "); } } else { if ((z & current.GetMaskAtDepth()) == 0) { if (current.m_Nodes[2] == null) { current.m_Nodes[2] = current.CreateSubnode(-1, 1, -1); } current = current.m_Nodes[2]; FilteredConsole.Write(FilterCategory.OctreeSetTracing, "2 - "); } else { if (current.m_Nodes[3] == null) { current.m_Nodes[3] = current.CreateSubnode(-1, 1, 1); } current = current.m_Nodes[3]; FilteredConsole.Write(FilterCategory.OctreeSetTracing, "3 - "); } } } else { if ((y & current.GetMaskAtDepth()) == 0) { if ((z & current.GetMaskAtDepth()) == 0) { if (current.m_Nodes[4] == null) { current.m_Nodes[4] = current.CreateSubnode(1, -1, -1); } current = current.m_Nodes[4]; FilteredConsole.Write(FilterCategory.OctreeSetTracing, "4 - "); } else { if (current.m_Nodes[5] == null) { current.m_Nodes[5] = current.CreateSubnode(1, -1, 1); } current = current.m_Nodes[5]; FilteredConsole.Write(FilterCategory.OctreeSetTracing, "5 - "); } } else { if ((z & current.GetMaskAtDepth()) == 0) { if (current.m_Nodes[6] == null) { current.m_Nodes[6] = current.CreateSubnode(1, 1, -1); } current = current.m_Nodes[6]; FilteredConsole.Write(FilterCategory.OctreeSetTracing, "6 - "); } else { if (current.m_Nodes[7] == null) { current.m_Nodes[7] = current.CreateSubnode(1, 1, 1); } current = current.m_Nodes[7]; FilteredConsole.Write(FilterCategory.OctreeSetTracing, "7 - "); } } } } FilteredConsole.WriteLine(FilterCategory.OctreeSetTracing, ""); current.m_Value = value; }
protected override void DrawTilesBelow(GameContext context) { // Ensure we have a chunk manager to source chunks from. if (!(context.World is RPGWorld)) { return; } this.Octree = (context.World as RPGWorld).ChunkOctree; if (this.Octree == null) { return; } if (this.Chunk == null) { this.Chunk = this.Octree.Get(0, 0, 0); } // Determine our Z offset. int zoffset = -(Chunk.Depth - this.ZLevel) * TileIsometricifier.TILE_CUBE_HEIGHT; // Get rendering information. ChunkRenderer.ResetNeeded(); IEnumerable <RelativeRenderInformation> renders = this.GetRelativeRenderInformation(context, this.Chunk); ChunkRenderer.LastRenderedCountOnScreen = renders.Count(); // Render chunks. if (FilteredFeatures.IsEnabled(Feature.DepthBuffer)) { context.EndSpriteBatch(); context.Graphics.GraphicsDevice.SetRenderTarget(RenderingBuffers.ScreenBuffer); context.StartSpriteBatch(); } foreach (RelativeRenderInformation ri in renders) { if (ri.Target == this.Chunk) { this.m_ChunkCenterX = ri.X + TileIsometricifier.CHUNK_TOP_WIDTH / 2; this.m_ChunkCenterY = ri.Y; } Texture2D tex = ri.Target.Texture; ChunkRenderer.MarkNeeded(ri.Target); if (tex != null) { ChunkRenderer.MarkUsed(ri.Target); if (FilteredFeatures.IsEnabled(Feature.DepthBuffer)) { context.SpriteBatch.Draw(tex, new Vector2(ri.X, ri.Y + zoffset), Color.White); } else { if (FilteredFeatures.IsEnabled(Feature.RenderingBuffers)) { context.Graphics.GraphicsDevice.SetRenderTarget(RenderingBuffers.ScreenBuffer); } context.SpriteBatch.Draw(tex, new Vector2(ri.X, ri.Y + zoffset), Color.White); } FilteredConsole.WriteLine(FilterCategory.RenderingActive, "Rendering chunk at " + ri.X + ", " + ri.Y + "."); } else { FilteredConsole.WriteLine(FilterCategory.Rendering, "No texture yet for chunk to render at " + ri.X + ", " + ri.Y + "."); } } // Render depth maps. if (FilteredFeatures.IsEnabled(Feature.DepthBuffer)) { context.EndSpriteBatch(); context.Graphics.GraphicsDevice.SetRenderTarget(RenderingBuffers.DepthBuffer); context.StartSpriteBatch(); foreach (RelativeRenderInformation ri in renders) { Texture2D depth = ri.Target.DepthMap; if (depth != null) { ChunkRenderer.MarkUsed(ri.Target); if (FilteredFeatures.IsEnabled(Feature.DepthBuffer)) { context.SpriteBatch.Draw(depth, new Vector2(ri.X, ri.Y + zoffset), Color.White); } } } } // Finish drawing. context.EndSpriteBatch(); context.Graphics.GraphicsDevice.SetRenderTarget(null); context.StartSpriteBatch(); }