diff --git a/Map/ChunkMeshBuilder.cs b/Map/ChunkMeshBuilder.cs index ea3035f47..78eccf929 100644 --- a/Map/ChunkMeshBuilder.cs +++ b/Map/ChunkMeshBuilder.cs @@ -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; diff --git a/Map/ChunkMeshBuilderTex2Col4.cs b/Map/ChunkMeshBuilderTex2Col4.cs index 5ca266d99..472189fc2 100644 --- a/Map/ChunkMeshBuilderTex2Col4.cs +++ b/Map/ChunkMeshBuilderTex2Col4.cs @@ -48,14 +48,14 @@ namespace ClassicalSharp { vCount1 = Math.Min( vCount, maxIndices ); iCount1 = ( vCount1 / 4 ) * 6; if( vCount1 > vertices1.Length ) { - vertices1 = new VertexPos3fTex2fCol4b[vCount1]; + vertices1 = new VertexPos3fTex2fCol4b[vCount1]; indices1 = new ushort[iCount1]; } vCount2 = Math.Max( 0, vCount - maxIndices ); iCount2 = ( vCount2 / 4 ) * 6; if( vCount2 > vertices2.Length ) { - vertices2 = new VertexPos3fTex2fCol4b[vCount2]; + vertices2 = new VertexPos3fTex2fCol4b[vCount2]; indices2 = new ushort[iCount2]; } vertices = vertices1; @@ -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; - } + 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; } diff --git a/Rendering/MapRenderer.cs b/Rendering/MapRenderer.cs index 690e23648..10c1486d8 100644 --- a/Rendering/MapRenderer.cs +++ b/Rendering/MapRenderer.cs @@ -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; + DeleteData( ref info.SolidParts ); + DeleteData( ref info.SpriteParts ); + DeleteData( ref info.TranslucentParts ); + } + + void DeleteData( ref ChunkPartInfo[] parts ) { + if( parts == 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 ); + for( int i = 0; i < parts.Length; i++ ) { + Graphics.DeleteVb( parts[i].VbId ); + Graphics.DeleteIb( parts[i].IbId ); } - info.DrawInfo = null; + parts = null; } void CreateChunkCache() { @@ -207,7 +209,7 @@ namespace ClassicalSharp { Graphics.AlphaTest = false; Graphics.Texturing = false; Graphics.EndIndexedVbBatch(); - Window.MapEnvRenderer.RenderMapSides( deltaTime ); + Window.MapEnvRenderer.RenderMapSides( deltaTime ); Window.MapEnvRenderer.RenderMapEdges( deltaTime ); // Render translucent(liquid) blocks. These 'blend' into other blocks. @@ -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 ) { diff --git a/Utils/TerrainAtlas2D.cs b/Utils/TerrainAtlas2D.cs index b7ae06148..9bccecd8b 100644 --- a/Utils/TerrainAtlas2D.cs +++ b/Utils/TerrainAtlas2D.cs @@ -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 ); } }