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.

This commit is contained in:
UnknownShadow200 2016-04-13 17:40:09 +10:00
parent 19af48ca3a
commit 4dca01a619
4 changed files with 42 additions and 19 deletions

View file

@ -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;

View file

@ -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 );

View file

@ -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]--;
}
}
}
}

View file

@ -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;