Optimise map rendering slightly. (memory side)

This commit is contained in:
UnknownShadow200 2015-06-15 19:15:58 +10:00
parent 32b37262b7
commit 274b742a25
4 changed files with 60 additions and 58 deletions

View File

@ -29,7 +29,7 @@ namespace ClassicalSharp {
bool BuildChunk( int x1, int y1, int z1 ) {
PreStretchTiles( x1, y1, z1 );
if( ReadChunkData( x1, y1, z1 ) ) return true;
if( ReadChunkData( x1, y1, z1 ) ) return false;
Stretch( x1, y1, z1 );
PostStretchTiles( x1, y1, z1 );
@ -47,7 +47,7 @@ namespace ClassicalSharp {
}
}
}
return false;
return true;
}
unsafe bool ReadChunkData( int x1, int y1, int z1 ) {
@ -92,8 +92,13 @@ namespace ClassicalSharp {
return allAir || allSolid;
}
public ChunkDrawInfo GetDrawInfo( int x, int y, int z ) {
return BuildChunk( x, y, z ) ? null : GetChunkInfo( x, y, z );
public bool GetDrawInfo( int x, int y, int z, ref ChunkPartInfo[] solidParts,
ref ChunkPartInfo[] spriteParts, ref ChunkPartInfo[] translucentParts ) {
if( !BuildChunk( x, y, z ) )
return false;
GetChunkInfo( x, y, z, ref solidParts, ref spriteParts, ref translucentParts );
return true;
}
public void RenderTile( int chunkIndex, int xx, int yy, int zz, int x, int y, int z ) {
@ -329,19 +334,6 @@ namespace ClassicalSharp {
}
}
public class ChunkDrawInfo {
public ChunkPartInfo[] SolidParts;
public ChunkPartInfo[] TranslucentParts;
public ChunkPartInfo[] SpriteParts;
public ChunkDrawInfo( int partsCount ) {
SolidParts = new ChunkPartInfo[partsCount];
TranslucentParts = new ChunkPartInfo[partsCount];
SpriteParts = new ChunkPartInfo[partsCount];
}
}
public struct ChunkPartInfo {
public int VbId, IbId;

View File

@ -127,29 +127,32 @@ namespace ClassicalSharp {
( BlockInfo.BlockHeight( map.GetBlock( x, y, z ) ) == 1 ? y : y - 1 );
}
ChunkDrawInfo GetChunkInfo( int x, int y, int z ) {
ChunkDrawInfo info = new ChunkDrawInfo( arraysCount );
void GetChunkInfo( int x, int y, int z, ref ChunkPartInfo[] solidParts,
ref ChunkPartInfo[] spriteParts, ref ChunkPartInfo[] translucentParts ) {
for( int i = 0; i < arraysCount; i++ ) {
DrawInfo1D drawInfo = drawInfoBuffer[i];
SetPartInfo( drawInfo.Solid, i, info.SolidParts );
SetPartInfo( drawInfo.Translucent, i, info.TranslucentParts );
SetPartInfo( drawInfo.Sprite, i, info.SpriteParts );
DrawInfo1D info = drawInfoBuffer[i];
SetPartInfo( info.Solid, i, ref solidParts );
SetPartInfo( info.Sprite, i, ref spriteParts );
SetPartInfo( info.Translucent, i, ref translucentParts );
}
return info;
}
void SetPartInfo( DrawInfo1DPart part, int i, ChunkPartInfo[] parts ) {
void SetPartInfo( DrawInfo1DPart part, int i, ref ChunkPartInfo[] parts ) {
if( part.iCount1 == 0 ) return;
ChunkPartInfo info = default( ChunkPartInfo );
if( part.iCount1 > 0 ) {
info.VbId = Graphics.InitVb( part.vertices1, VertexFormat.Pos3fTex2fCol4b, part.vCount1 );
info.IbId = Graphics.InitIb( part.indices1, part.iCount1 );
info.IndicesCount = part.iCount1;
}
if( part.iCount2 > 0 ) {
info.VbId2 = Graphics.InitVb( part.vertices2, VertexFormat.Pos3fTex2fCol4b, part.vCount2 );
info.IbId2 = Graphics.InitIb( part.indices2, part.iCount2 );
info.IndicesCount2 = part.iCount2;
}
// Lazy initalize part arrays so we can save time in MapRenderer for chunks that only contain 1 or 2 part types.
if( parts == null )
parts = new ChunkPartInfo[arraysCount];
parts[i] = info;
}

View File

@ -11,11 +11,12 @@ namespace ClassicalSharp {
class ChunkInfo {
public short CentreX, CentreY, CentreZ;
public bool Visible = true;
public bool Empty = false;
public ChunkDrawInfo DrawInfo;
public ChunkPartInfo[] SolidParts;
public ChunkPartInfo[] SpriteParts;
public ChunkPartInfo[] TranslucentParts;
public ChunkInfo( int x, int y, int z ) {
CentreX = (short)( x + 8 );
@ -111,19 +112,20 @@ namespace ClassicalSharp {
}
void DeleteChunk( ChunkInfo info ) {
ChunkDrawInfo drawInfo = info.DrawInfo;
info.Empty = false;
if( drawInfo == null ) return;
for( int i = 0; i < drawInfo.SolidParts.Length; i++ ) {
Graphics.DeleteVb( drawInfo.SpriteParts[i].VbId );
Graphics.DeleteIb( drawInfo.SpriteParts[i].IbId );
Graphics.DeleteVb( drawInfo.TranslucentParts[i].VbId );
Graphics.DeleteIb( drawInfo.TranslucentParts[i].IbId );
Graphics.DeleteVb( drawInfo.SolidParts[i].VbId );
Graphics.DeleteIb( drawInfo.SolidParts[i].IbId );
DeleteData( ref info.SolidParts );
DeleteData( ref info.SpriteParts );
DeleteData( ref info.TranslucentParts );
}
info.DrawInfo = null;
void DeleteData( ref ChunkPartInfo[] parts ) {
if( parts == null ) return;
for( int i = 0; i < parts.Length; i++ ) {
Graphics.DeleteVb( parts[i].VbId );
Graphics.DeleteIb( parts[i].IbId );
}
parts = null;
}
void CreateChunkCache() {
@ -262,14 +264,14 @@ namespace ClassicalSharp {
int distSqr = distances[i];
bool inRange = distSqr <= adjViewDistSqr;
if( info.DrawInfo == null ) {
if( info.SolidParts == null && info.SpriteParts == null && info.TranslucentParts == null ) {
if( inRange && chunksUpdatedThisFrame < 4 ) {
Window.ChunkUpdates++;
info.DrawInfo = builder.GetDrawInfo( info.CentreX - 8, info.CentreY - 8, info.CentreZ - 8 );
if( info.DrawInfo == null ) {
if( !builder.GetDrawInfo( info.CentreX - 8, info.CentreY - 8, info.CentreZ - 8,
ref info.SolidParts, ref info.SpriteParts, ref info.TranslucentParts ) ) {
info.Empty = true;
}
chunksUpdatedThisFrame++;
chunksThisFrame++;
}
}
info.Visible = inRange &&
@ -277,14 +279,13 @@ namespace ClassicalSharp {
}
}
// TODO: there's probably a better way of doing this.
const DrawMode mode = DrawMode.Triangles;
void RenderSolidBatch( int batch ) {
for( int i = 0; i < chunks.Length; i++ ) {
ChunkInfo info = chunks[i];
if( info.DrawInfo == null || !info.Visible ) continue;
if( info.SolidParts == null || !info.Visible ) continue;
ChunkPartInfo drawInfo = info.DrawInfo.SolidParts[batch];
ChunkPartInfo drawInfo = info.SolidParts[batch];
if( drawInfo.IndicesCount > 0 ) {
Graphics.DrawIndexedVbBatch( mode, drawInfo.VbId, drawInfo.IbId, drawInfo.IndicesCount );
Window.Vertices += drawInfo.IndicesCount;
@ -299,9 +300,9 @@ namespace ClassicalSharp {
void RenderSpriteBatch( int batch ) {
for( int i = 0; i < chunks.Length; i++ ) {
ChunkInfo info = chunks[i];
if( info.DrawInfo == null || !info.Visible ) continue;
if( info.SpriteParts == null || !info.Visible ) continue;
ChunkPartInfo drawInfo = info.DrawInfo.SpriteParts[batch];
ChunkPartInfo drawInfo = info.SpriteParts[batch];
if( drawInfo.IndicesCount > 0 ) {
Graphics.DrawIndexedVbBatch( mode, drawInfo.VbId, drawInfo.IbId, drawInfo.IndicesCount );
Window.Vertices += drawInfo.IndicesCount;
@ -312,9 +313,9 @@ namespace ClassicalSharp {
void RenderTranslucentBatch( int batch ) {
for( int i = 0; i < chunks.Length; i++ ) {
ChunkInfo info = chunks[i];
if( info.DrawInfo == null || !info.Visible ) continue;
if( info.TranslucentParts == null || !info.Visible ) continue;
ChunkPartInfo drawInfo = info.DrawInfo.TranslucentParts[batch];
ChunkPartInfo drawInfo = info.TranslucentParts[batch];
if( drawInfo.IndicesCount > 0 ) {
Graphics.DrawIndexedVbBatch( mode, drawInfo.VbId, drawInfo.IbId, drawInfo.IndicesCount );
Window.Vertices += drawInfo.IndicesCount;
@ -329,9 +330,9 @@ namespace ClassicalSharp {
void RenderTranslucentBatchNoAdd( int batch ) {
for( int i = 0; i < chunks.Length; i++ ) {
ChunkInfo info = chunks[i];
if( info.DrawInfo == null || !info.Visible ) continue;
if( info.TranslucentParts == null || !info.Visible ) continue;
ChunkPartInfo drawInfo = info.DrawInfo.TranslucentParts[batch];
ChunkPartInfo drawInfo = info.TranslucentParts[batch];
if( drawInfo.IndicesCount > 0 ) {
Graphics.DrawIndexedVbBatch( mode, drawInfo.VbId, drawInfo.IbId, drawInfo.IndicesCount );
if( drawInfo.IndicesCount2 > 0 ) {

View File

@ -43,6 +43,12 @@ namespace ClassicalSharp {
using( Bitmap bmp = new Bitmap( elementSize, elementSize ) ) {
using( FastBitmap dst = new FastBitmap( bmp, true ) ) {
Utils.MovePortion( x * elementSize, y * elementSize, 0, 0, atlas, dst, elementSize );
for( int xxx = 0; xxx < 2; xxx++ ) {
for( int yyy = 0; yyy < 2; yyy++ ) {
Console.WriteLine( dst.GetPixel( xxx, yyy ) & 0xFF );
}
}
return graphics.LoadTexture( dst );
}
}