diff --git a/ClassicalSharp/Blocks/BlockInfo.cs b/ClassicalSharp/Blocks/BlockInfo.cs index 65aeeace9..4638c4d7e 100644 --- a/ClassicalSharp/Blocks/BlockInfo.cs +++ b/ClassicalSharp/Blocks/BlockInfo.cs @@ -11,7 +11,8 @@ namespace ClassicalSharp { internal bool[] isSprite = new bool[BlocksCount]; internal bool[] isLiquid = new bool[BlocksCount]; internal float[] heights = new float[BlocksCount]; - internal bool[] blocksLight = new bool[BlocksCount]; + internal bool[] blocksLight = new bool[BlocksCount]; + internal bool[] emitsLight = new bool[BlocksCount]; public const byte MaxDefinedBlock = (byte)Block.StoneBrick; public const byte BlocksCount = MaxDefinedBlock + 1; @@ -41,6 +42,7 @@ namespace ClassicalSharp { SetIsSprite( Block.Rope, Block.Fire ); SetBlockHeight( 8 / 16f, Block.CobblestoneSlab ); SetBlockHeight( 2 / 16f, Block.Snow ); + SetEmitsLight( true, Block.Lava, Block.StillLava ); SetupCullingCache(); } @@ -101,20 +103,24 @@ namespace ClassicalSharp { } } + void SetEmitsLight( bool emits, params Block[] ids ) { + for( int i = 0; i < ids.Length; i++ ) { + emitsLight[(int)ids[i]] = emits; + } + } + /// Gets whether the given block id is opaque/not see through. public bool IsOpaque( byte id ) { return isOpaque[id]; } - /// Gets whether the given block id is opaque/not see through, - /// and occupies a full block. + /// Gets whether the given block id is opaque/not see through, and occupies a full block. public bool IsFullAndOpaque( byte id ) { return isOpaque[id] && heights[id] == 1; } /// Gets whether the given block id is transparent/fully see through. - /// Note that these blocks's alpha values are treated as either 'fully see through' - /// or 'fully solid'. + /// Alpha values are treated as either 'fully see through' or 'fully solid'. public bool IsTransparent( byte id ) { return isTransparent[id]; } @@ -125,8 +131,7 @@ namespace ClassicalSharp { } /// Gets whether the given block id is translucent/partially see through. - /// Note that these blocks's colour values are blended into both - /// the transparent and opaque blocks behind them. + /// Colour values are blended into both the transparent and opaque blocks behind them. public bool IsTranslucent( byte id ) { return isTranslucent[id]; } @@ -136,16 +141,18 @@ namespace ClassicalSharp { return blocksLight[id]; } - /// Gets whether the given block id is a sprite.
- /// (flowers, saplings, fire, etc)
+ /// Gets whether the given block id is a sprite. (flowers, saplings, fire, etc) public bool IsSprite( byte id ) { return isSprite[id]; } - /// Gets whether the given block id is a liquid.
- /// (water or lava)
+ /// Gets whether the given block id is a liquid. (water or lava) public bool IsLiquid( byte id ) { return isLiquid[id]; } + + public bool EmitsLight( byte id ) { + return emitsLight[id]; + } } } \ No newline at end of file diff --git a/ClassicalSharp/Map/ChunkMeshBuilder.cs b/ClassicalSharp/Map/ChunkMeshBuilder.cs index a54cb2b5b..c8f79d717 100644 --- a/ClassicalSharp/Map/ChunkMeshBuilder.cs +++ b/ClassicalSharp/Map/ChunkMeshBuilder.cs @@ -111,42 +111,39 @@ namespace ClassicalSharp { public void RenderTile( int chunkIndex, int xx, int yy, int zz, int x, int y, int z ) { X = x; Y = y; Z = z; - blockHeight = -1; int index = ( ( yy << 8 ) + ( zz << 4 ) + xx ) * TileSide.Sides; - int count = 0; - if( BlockInfo.IsSprite( tile ) ) { - count = counts[index]; + if( BlockInfo.isSprite[tile] ) { + int count = counts[index]; if( count != 0 ) { + blockHeight = BlockInfo.heights[tile]; DrawSprite( count ); } return; } - count = counts[index + TileSide.Left]; - if( count != 0 ) { - DrawLeftFace( count ); - } - count = counts[index + TileSide.Right]; - if( count != 0 ) { - DrawRightFace( count ); - } - count = counts[index + TileSide.Front]; - if( count != 0 ) { - DrawFrontFace( count ); - } - count = counts[index + TileSide.Back]; - if( count != 0 ) { - DrawBackFace( count ); - } - count = counts[index + TileSide.Bottom]; - if( count != 0 ) { - DrawBottomFace( count ); - } - count = counts[index + TileSide.Top]; - if( count != 0 ) { - DrawTopFace( count ); - } + int leftCount = counts[index++], rightCount = counts[index++], + frontCount = counts[index++], backCount = counts[index++], + bottomCount = counts[index++], topCount = counts[index++]; + if( leftCount == 0 && rightCount == 0 && frontCount == 0 && + backCount == 0 && bottomCount == 0 && topCount == 0 ) return; + + emitsLight = BlockInfo.emitsLight[tile]; + blockHeight = BlockInfo.heights[tile]; + isTranslucent = BlockInfo.isTranslucent[tile]; + + if( leftCount != 0 ) + DrawLeftFace( leftCount ); + if( rightCount != 0 ) + DrawRightFace( rightCount ); + if( frontCount != 0 ) + DrawFrontFace( frontCount ); + if( backCount != 0 ) + DrawBackFace( backCount ); + if( bottomCount != 0 ) + DrawBottomFace( bottomCount ); + if( topCount != 0 ) + DrawTopFace( topCount ); } void Stretch( int x1, int y1, int z1 ) { @@ -178,6 +175,7 @@ namespace ClassicalSharp { } } else { X = x; Y = y; Z = z; + emitsLight = BlockInfo.emitsLight[tile]; TestAndStretchZ( zz, countIndex, tile, chunkIndex, x, 0, TileSide.Left, -1 ); TestAndStretchZ( zz, countIndex, tile, chunkIndex, x, maxX, TileSide.Right, 1 ); TestAndStretchX( xx, countIndex, tile, chunkIndex, z, 0, TileSide.Front, -extChunkSize ); diff --git a/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs b/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs index a6569dcb1..240387530 100644 --- a/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs +++ b/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs @@ -9,6 +9,7 @@ namespace ClassicalSharp { DrawInfo[] drawInfoNormal, drawInfoTranslucent; TerrainAtlas1D atlas; int arraysCount = 0; + bool emitsLight; void TerrainAtlasChanged( object sender, EventArgs e ) { int newArraysCount = Window.TerrainAtlas1D.TexIds.Length; @@ -70,22 +71,22 @@ namespace ClassicalSharp { bool IsLit( int x, int y, int z, int face ) { switch( face ) { case TileSide.Left: - return x <= 0 || y > map.heightmap[( z * width ) + (x - 1)]; + return emitsLight || x <= 0 || y > map.heightmap[( z * width ) + (x - 1)]; case TileSide.Right: - return x >= maxX || y > map.heightmap[( z * width ) + (x + 1)]; + return emitsLight || x >= maxX || y > map.heightmap[( z * width ) + (x + 1)]; case TileSide.Front: - return z <= 0 || y > map.heightmap[( (z - 1) * width ) + x]; + return emitsLight || z <= 0 || y > map.heightmap[( (z - 1) * width ) + x]; case TileSide.Back: - return z >= maxZ || y > map.heightmap[( (z + 1) * width ) + x]; + return emitsLight || z >= maxZ || y > map.heightmap[( (z + 1) * width ) + x]; case TileSide.Bottom: - return y <= 0 || (y - 1) > map.heightmap[( z * width ) + x]; + return emitsLight || y <= 0 || (y - 1) > map.heightmap[( z * width ) + x]; case TileSide.Top: - return y >= maxY || (y + 1) > map.heightmap[( z * width ) + x]; + return emitsLight || y >= maxY || (y + 1) > map.heightmap[( z * width ) + x]; } return true; } @@ -166,12 +167,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Left ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = X > 0 ? ( Y > map.heightmap[( Z * width ) + (X - 1)] ? map.SunlightXSide : map.ShadowlightXSide ) + FastColour col = X > 0 ? ( emitsLight || Y > map.heightmap[( Z * width ) + (X - 1)] ? map.SunlightXSide : map.ShadowlightXSide ) : map.SunlightXSide; - if( blockHeight == -1 ) { - blockHeight = BlockInfo.BlockHeight( tile ); - isTranslucent = BlockInfo.IsTranslucent( tile ); - } if( blockHeight != 1 ) { rec.V2 = rec.V1 + blockHeight * invVerElementSize; } @@ -187,12 +184,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Right ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = X < maxX ? ( Y > map.heightmap[( Z * width ) + (X + 1)] ? map.SunlightXSide : map.ShadowlightXSide ) + FastColour col = X < maxX ? ( emitsLight || Y > map.heightmap[( Z * width ) + (X + 1)] ? map.SunlightXSide : map.ShadowlightXSide ) : map.SunlightXSide; - if( blockHeight == -1 ) { - blockHeight = BlockInfo.BlockHeight( tile ); - isTranslucent = BlockInfo.IsTranslucent( tile ); - } if( blockHeight != 1 ) { rec.V2 = rec.V1 + blockHeight * invVerElementSize; } @@ -208,12 +201,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Back ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = Z < maxZ ? ( Y > map.heightmap[( (Z + 1) * width ) + X] ? map.SunlightZSide : map.ShadowlightZSide ) + FastColour col = Z < maxZ ? ( emitsLight || Y > map.heightmap[( (Z + 1) * width ) + X] ? map.SunlightZSide : map.ShadowlightZSide ) : map.SunlightZSide; - if( blockHeight == -1 ) { - blockHeight = BlockInfo.BlockHeight( tile ); - isTranslucent = BlockInfo.IsTranslucent( tile ); - } if( blockHeight != 1 ) { rec.V2 = rec.V1 + blockHeight * invVerElementSize; } @@ -229,12 +218,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Front ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = Z > 0 ? ( Y > map.heightmap[( (Z - 1) * width ) + X] ? map.SunlightZSide : map.ShadowlightZSide ) + FastColour col = Z > 0 ? ( emitsLight || Y > map.heightmap[( (Z - 1) * width ) + X] ? map.SunlightZSide : map.ShadowlightZSide ) : map.SunlightZSide; - if( blockHeight == -1 ) { - blockHeight = BlockInfo.BlockHeight( tile ); - isTranslucent = BlockInfo.IsTranslucent( tile ); - } if( blockHeight != 1 ) { rec.V2 = rec.V1 + blockHeight * invVerElementSize; } @@ -250,12 +235,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Bottom ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = Y > 0 ? ( (Y - 1) > map.heightmap[( Z * width ) + X] ? map.SunlightYBottom : map.ShadowlightYBottom ) + FastColour col = Y > 0 ? ( emitsLight || (Y - 1) > map.heightmap[( Z * width ) + X] ? map.SunlightYBottom : map.ShadowlightYBottom ) : map.SunlightYBottom; - if( blockHeight == -1 ) { - blockHeight = BlockInfo.BlockHeight( tile ); - isTranslucent = BlockInfo.IsTranslucent( tile ); - } DrawInfo part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i]; part.vertices[part.vIndex.bottom++] = new VertexPos3fTex2fCol4b( X + count, Y, Z + 1, rec.U2, rec.V2, col ); @@ -268,12 +249,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Top ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = Y < maxY ? ( (Y + 1) > map.heightmap[( Z * width ) + X] ? map.Sunlight : map.Shadowlight ) + FastColour col = Y < maxY ? ( emitsLight || (Y + 1) > map.heightmap[( Z * width ) + X] ? map.Sunlight : map.Shadowlight ) : map.Sunlight; - if( blockHeight == -1 ) { - blockHeight = BlockInfo.BlockHeight( tile ); - isTranslucent = BlockInfo.IsTranslucent( tile ); - } DrawInfo part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i]; part.vertices[part.vIndex.top++] = new VertexPos3fTex2fCol4b( X + count, Y + blockHeight, Z, rec.U2, rec.V1, col ); @@ -286,11 +263,8 @@ namespace ClassicalSharp { int texId = BlockInfo.GetOptimTextureLoc( tile, TileSide.Right ); int i; TextureRectangle rec = atlas.GetTexRec( texId, count, out i ); - FastColour col = Y < maxY ? ( (Y + 1) > map.heightmap[( Z * width ) + X] ? map.Sunlight : map.Shadowlight ) + FastColour col = Y < maxY ? ( emitsLight || (Y + 1) > map.heightmap[( Z * width ) + X] ? map.Sunlight : map.Shadowlight ) : map.Sunlight; - if( blockHeight == -1 ) { - blockHeight = BlockInfo.BlockHeight( tile ); - } DrawInfo part = drawInfoNormal[i]; // Draw stretched Z axis