From 4dca01a6192b7832559f3f348f80e5fc8e75fdf5 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 13 Apr 2016 17:40:09 +1000 Subject: [PATCH] Optimise map rendering - we keep track of which 1D texture atlases actually have any chunks in the world using them at all (in addition to the test on visible chunks), thus we can skip entire rows. --- ClassicalSharp/2D/Drawing/IDrawer2D.TextMC.cs | 15 +++---- .../Rendering/MapRenderer.Rendering.cs | 3 ++ ClassicalSharp/Rendering/MapRenderer.cs | 41 +++++++++++++++---- .../Gui/TableWidget/LauncherTableWidget.cs | 2 +- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/ClassicalSharp/2D/Drawing/IDrawer2D.TextMC.cs b/ClassicalSharp/2D/Drawing/IDrawer2D.TextMC.cs index 80091cbf8..73c1eb4af 100644 --- a/ClassicalSharp/2D/Drawing/IDrawer2D.TextMC.cs +++ b/ClassicalSharp/2D/Drawing/IDrawer2D.TextMC.cs @@ -52,20 +52,15 @@ namespace ClassicalSharp { bool underline = args.Font.Style == FontStyle.Underline; if( args.UseShadow ) { int offset = ShadowOffset( args.Font.Size ); - int shadowX = x + offset, shadowY = y + offset; - - DrawPart( dst, ref args, ref shadowX, shadowY, true ); - if( underline ) - DrawUnderline( dst, x + offset, 0, ref args, true ); + DrawPart( dst, ref args, x + offset, y + offset, true ); + if( underline ) DrawUnderline( dst, x + offset, 0, ref args, true ); } - int orignX = x; - DrawPart( dst, ref args, ref x, y, false ); - if( underline ) - DrawUnderline( dst, orignX, -2, ref args, false ); + DrawPart( dst, ref args, x, y, false ); + if( underline ) DrawUnderline( dst, x, -2, ref args, false ); } - void DrawPart( FastBitmap dst, ref DrawTextArgs args, ref int x, int y, bool shadowCol ) { + void DrawPart( FastBitmap dst, ref DrawTextArgs args, int x, int y, bool shadowCol ) { FastColour col = shadowCol ? FastColour.Black : FastColour.White; FastColour lastCol = col; int xMul = args.Font.Style == FontStyle.Italic ? 1 : 0; diff --git a/ClassicalSharp/Rendering/MapRenderer.Rendering.cs b/ClassicalSharp/Rendering/MapRenderer.Rendering.cs index 93ff85b71..69397186b 100644 --- a/ClassicalSharp/Rendering/MapRenderer.Rendering.cs +++ b/ClassicalSharp/Rendering/MapRenderer.Rendering.cs @@ -16,6 +16,7 @@ namespace ClassicalSharp.Renderers { api.AlphaTest = true; for( int batch = 0; batch < _1DUsed; batch++ ) { + if( totalUsed[batch] <= 0 ) continue; if( pendingNormal[batch] || usedNormal[batch] ) { api.BindTexture( texIds[batch] ); RenderNormalBatch( batch ); @@ -38,6 +39,7 @@ namespace ClassicalSharp.Renderers { api.AlphaBlending = false; api.ColourWrite = false; for( int batch = 0; batch < _1DUsed; batch++ ) { + if( totalUsed[batch] <= 0 ) continue; if( pendingTranslucent[batch] || usedTranslucent[batch] ) { RenderTranslucentBatchDepthPass( batch ); pendingTranslucent[batch] = false; @@ -51,6 +53,7 @@ namespace ClassicalSharp.Renderers { api.DepthWrite = false; // we already calculated depth values in depth pass for( int batch = 0; batch < _1DUsed; batch++ ) { + if( totalUsed[batch] <= 0 ) continue; if( !usedTranslucent[batch] ) continue; api.BindTexture( texIds[batch] ); RenderTranslucentBatch( batch ); diff --git a/ClassicalSharp/Rendering/MapRenderer.cs b/ClassicalSharp/Rendering/MapRenderer.cs index 841e8719e..c7e7a4274 100644 --- a/ClassicalSharp/Rendering/MapRenderer.cs +++ b/ClassicalSharp/Rendering/MapRenderer.cs @@ -41,10 +41,12 @@ namespace ClassicalSharp.Renderers { Vector3I chunkPos = new Vector3I( int.MaxValue, int.MaxValue, int.MaxValue ); int elementsPerBitmap = 0; bool[] usedTranslucent, usedNormal, pendingTranslucent, pendingNormal; + int[] totalUsed; public MapRenderer( Game game ) { this.game = game; _1DUsed = game.TerrainAtlas1D.CalcMaxUsedRow( game.TerrainAtlas, game.BlockInfo ); + totalUsed = new int[game.TerrainAtlas1D.TexIds.Length]; RecalcBooleans( true ); builder = new ChunkMeshBuilder( game ); @@ -74,8 +76,8 @@ namespace ClassicalSharp.Renderers { } public void Refresh() { - chunkPos = new Vector3I( int.MaxValue ); - if( chunks == null || game.World.IsNotLoaded ) return; + chunkPos = new Vector3I( int.MaxValue ); + if( chunks == null || game.World.IsNotLoaded ) return; ClearChunkCache(); CreateChunkCache(); } @@ -108,11 +110,10 @@ namespace ClassicalSharp.Renderers { void TerrainAtlasChanged( object sender, EventArgs e ) { bool refreshRequired = elementsPerBitmap != game.TerrainAtlas1D.elementsPerBitmap; - if( refreshRequired ) - Refresh(); - elementsPerBitmap = game.TerrainAtlas1D.elementsPerBitmap; _1DUsed = game.TerrainAtlas1D.CalcMaxUsedRow( game.TerrainAtlas, game.BlockInfo ); + + if( refreshRequired ) Refresh(); RecalcBooleans( true ); } @@ -125,6 +126,9 @@ namespace ClassicalSharp.Renderers { void OnNewMap( object sender, EventArgs e ) { game.ChunkUpdates = 0; ClearChunkCache(); + for( int i = 0; i < totalUsed.Length; i++ ) + totalUsed[i] = 0; + chunks = null; unsortedChunks = null; chunkPos = new Vector3I( int.MaxValue, int.MaxValue, int.MaxValue ); @@ -174,6 +178,7 @@ namespace ClassicalSharp.Renderers { if( chunks == null ) return; for( int i = 0; i < chunks.Length; i++ ) DeleteChunk( chunks[i] ); + totalUsed = new int[game.TerrainAtlas1D.TexIds.Length]; } void DeleteChunk( ChunkInfo info ) { @@ -185,11 +190,11 @@ namespace ClassicalSharp.Renderers { } void DeleteData( ref ChunkPartInfo[] parts ) { + DecrementUsed( parts ); if( parts == null ) return; - for( int i = 0; i < parts.Length; i++ ) { + for( int i = 0; i < parts.Length; i++ ) api.DeleteVb( parts[i].VbId ); - } parts = null; } @@ -334,9 +339,29 @@ namespace ClassicalSharp.Renderers { builder.GetDrawInfo( info.CentreX - 8, info.CentreY - 8, info.CentreZ - 8, ref info.NormalParts, ref info.TranslucentParts, ref info.OcclusionFlags ); - if( info.NormalParts == null && info.TranslucentParts == null ) + if( info.NormalParts == null && info.TranslucentParts == null ) { info.Empty = true; + } else { + IncrementUsed( info.NormalParts ); + IncrementUsed( info.TranslucentParts ); + } chunkUpdates++; } + + void IncrementUsed( ChunkPartInfo[] parts ) { + if( parts == null ) return; + for( int i = 0; i < parts.Length; i++ ) { + if( parts[i].IndicesCount == 0 ) continue; + totalUsed[i]++; + } + } + + void DecrementUsed( ChunkPartInfo[] parts ) { + if( parts == null ) return; + for( int i = 0; i < parts.Length; i++ ) { + if( parts[i].IndicesCount == 0 ) continue; + totalUsed[i]--; + } + } } } \ No newline at end of file diff --git a/Launcher2/Gui/TableWidget/LauncherTableWidget.cs b/Launcher2/Gui/TableWidget/LauncherTableWidget.cs index bb6dbaec1..2a5dcead7 100644 --- a/Launcher2/Gui/TableWidget/LauncherTableWidget.cs +++ b/Launcher2/Gui/TableWidget/LauncherTableWidget.cs @@ -26,7 +26,7 @@ namespace Launcher { int index = 0; foreach( ServerListEntry e in servers ) { - TableEntry tableEntry = default( TableEntry ); + TableEntry tableEntry = default(TableEntry); tableEntry.Hash = e.Hash; tableEntry.Name = e.Name; tableEntry.Players = e.Players + "/" + e.MaximumPlayers;