Slightly optimise ChunkMeshBuilder, fix lava not being fully lit on all tile sides.

This commit is contained in:
UnknownShadow200 2015-09-01 16:33:05 +10:00
parent d9166bbf93
commit db800f3b32
3 changed files with 58 additions and 79 deletions

View File

@ -12,6 +12,7 @@ namespace ClassicalSharp {
internal bool[] isLiquid = new bool[BlocksCount];
internal float[] heights = new float[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;
}
}
/// <summary> Gets whether the given block id is opaque/not see through. </summary>
public bool IsOpaque( byte id ) {
return isOpaque[id];
}
/// <summary> Gets whether the given block id is opaque/not see through,
/// and occupies a full block. </summary>
/// <summary> Gets whether the given block id is opaque/not see through, and occupies a full block. </summary>
public bool IsFullAndOpaque( byte id ) {
return isOpaque[id] && heights[id] == 1;
}
/// <summary> Gets whether the given block id is transparent/fully see through. </summary>
/// <remarks> Note that these blocks's alpha values are treated as either 'fully see through'
/// or 'fully solid'. </remarks>
/// <remarks> Alpha values are treated as either 'fully see through' or 'fully solid'. </remarks>
public bool IsTransparent( byte id ) {
return isTransparent[id];
}
@ -125,8 +131,7 @@ namespace ClassicalSharp {
}
/// <summary> Gets whether the given block id is translucent/partially see through. </summary>
/// <remarks> Note that these blocks's colour values are blended into both
/// the transparent and opaque blocks behind them. </remarks>
/// <remarks>Colour values are blended into both the transparent and opaque blocks behind them. </remarks>
public bool IsTranslucent( byte id ) {
return isTranslucent[id];
}
@ -136,16 +141,18 @@ namespace ClassicalSharp {
return blocksLight[id];
}
/// <summary> Gets whether the given block id is a sprite. <br/>
/// (flowers, saplings, fire, etc) </summary>
/// <summary> Gets whether the given block id is a sprite. (flowers, saplings, fire, etc) </summary>
public bool IsSprite( byte id ) {
return isSprite[id];
}
/// <summary> Gets whether the given block id is a liquid. <br/>
/// (water or lava) </summary>
/// <summary> Gets whether the given block id is a liquid. (water or lava) </summary>
public bool IsLiquid( byte id ) {
return isLiquid[id];
}
public bool EmitsLight( byte id ) {
return emitsLight[id];
}
}
}

View File

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

View File

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