From b7603a8ca134a8cb9452f41054e2ac0c91f7ceca Mon Sep 17 00:00:00 2001 From: William Moorehouse Date: Tue, 24 Nov 2015 12:15:07 -0500 Subject: [PATCH] Fixed multiple issues with lighting --- TrueCraft.Client/Rendering/BlockRenderer.cs | 97 +++++++++++++++++-- .../Rendering/Blocks/CraftingTableRenderer.cs | 9 +- .../Rendering/Blocks/FarmlandRenderer.cs | 9 +- .../Rendering/Blocks/GrassRenderer.cs | 10 +- .../Rendering/Blocks/LeavesRenderer.cs | 13 ++- .../Rendering/Blocks/LogRenderer.cs | 13 ++- .../Rendering/Blocks/TNTRenderer.cs | 9 +- .../Rendering/Blocks/WaterRenderer.cs | 9 +- 8 files changed, 150 insertions(+), 19 deletions(-) diff --git a/TrueCraft.Client/Rendering/BlockRenderer.cs b/TrueCraft.Client/Rendering/BlockRenderer.cs index f6a574c..4223f16 100644 --- a/TrueCraft.Client/Rendering/BlockRenderer.cs +++ b/TrueCraft.Client/Rendering/BlockRenderer.cs @@ -1,9 +1,10 @@ using System; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework; -using TrueCraft.Core.Logic; -using TrueCraft.API.Logic; using System.Linq; +using Microsoft.Xna.Framework; +using TrueCraft.API.Logic; +using TrueCraft.API.World; +using TrueCraft.Core.World; +using Coordinates3D = TrueCraft.API.Coordinates3D; namespace TrueCraft.Client.Rendering { @@ -37,15 +38,26 @@ namespace TrueCraft.Client.Rendering texCoords, texCoords + Vector2.UnitX }; + for (int i = 0; i < texture.Length; i++) texture[i] *= new Vector2(16f / 256f); - return CreateUniformCube(offset, texture, faces, indiciesOffset, out indicies, Color.White, descriptor.BlockLight); + + var lighting = new int[6]; + for (int i = 0; i < 6; i++) + { + var coords = (descriptor.Coordinates + FaceCoords[i]); + lighting[i] = GetLight(descriptor.Chunk, coords); + } + + return CreateUniformCube(offset, texture, faces, indiciesOffset, out indicies, Color.White, lighting); } public static VertexPositionNormalColorTexture[] CreateUniformCube(Vector3 offset, Vector2[] texture, - VisibleFaces faces, int indiciesOffset, out int[] indicies, Color color, int light = 15) + VisibleFaces faces, int indiciesOffset, out int[] indicies, Color color, int[] lighting = null) { faces = VisibleFaces.All; // Temporary + if (lighting == null) + lighting = DefaultLighting; int totalFaces = 0; uint f = (uint)faces; @@ -68,9 +80,11 @@ namespace TrueCraft.Client.Rendering textureIndex += 4; continue; } + var lightColor = LightColor.ToVector3() * CubeBrightness[lighting[_side]]; + var side = (CubeFace)_side; var quad = CreateQuad(side, offset, texture, textureIndex % texture.Length, indiciesOffset, - out _indicies, new Color(color.ToVector3() * CubeBrightness[light])); + out _indicies, new Color(lightColor * color.ToVector3())); Array.Copy(quad, 0, verticies, sidesSoFar * 4, 4); Array.Copy(_indicies, 0, indicies, sidesSoFar * 6, 6); textureIndex += 4; @@ -95,7 +109,29 @@ namespace TrueCraft.Client.Rendering } return quad; } - + + #region Lighting + + /// + /// The per-vertex light color to apply to blocks. + /// + protected static readonly Color LightColor = + new Color(245, 245, 225); + + /// + /// The default lighting information for rendering a block; + /// i.e. when the lighting param to CreateUniformCube == null. + /// + protected static readonly int[] DefaultLighting = + new int[] + { + 0, 0, 0, + 0, 0, 0 + }; + + /// + /// The per-face brightness modifier for lighting. + /// protected static readonly float[] FaceBrightness = new float[] { @@ -103,7 +139,21 @@ namespace TrueCraft.Client.Rendering 0.8f, 0.8f, // East / West 1.0f, 0.5f // Top / Bottom }; + + /// + /// The offset coordinates used to get the position of a block for a face. + /// + protected static readonly Coordinates3D[] FaceCoords = + new Coordinates3D[] + { + Coordinates3D.South, Coordinates3D.North, + Coordinates3D.East, Coordinates3D.West, + Coordinates3D.Up, Coordinates3D.Down + }; + /// + /// Maps a light level [0..15] to a brightness modifier for lighting. + /// protected static readonly float[] CubeBrightness = new float[] { @@ -113,6 +163,37 @@ namespace TrueCraft.Client.Rendering 0.525f, 0.638f, 0.789f, 1.000f // [12..15] }; + /// + /// + /// + /// + /// + /// + protected static int GetLight(IChunk chunk, Coordinates3D coords) + { + // Handle icon renderer. + if (chunk == null) + return 15; + + // Handle top (and bottom) of the world. + if (coords.Y < 0) + return 0; + if (coords.Y >= Chunk.Height) + return 15; + + // Handle coordinates outside the chunk. + if ((coords.X < 0) || (coords.X >= Chunk.Width) || + (coords.Z < 0) || (coords.Z >= Chunk.Depth)) + { + // TODO: Handle chunk boundaries properly. + return 0; + } + + return Math.Min(chunk.GetBlockLight(coords) + chunk.GetSkyLight(coords), 15); + } + + #endregion + protected enum CubeFace { PositiveZ = 0, diff --git a/TrueCraft.Client/Rendering/Blocks/CraftingTableRenderer.cs b/TrueCraft.Client/Rendering/Blocks/CraftingTableRenderer.cs index 6b83f0a..7e595a4 100644 --- a/TrueCraft.Client/Rendering/Blocks/CraftingTableRenderer.cs +++ b/TrueCraft.Client/Rendering/Blocks/CraftingTableRenderer.cs @@ -56,7 +56,14 @@ namespace TrueCraft.Client.Rendering.Blocks public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset, VisibleFaces faces, Tuple textureMap, int indiciesOffset, out int[] indicies) { - return CreateUniformCube(offset, Texture, faces, indiciesOffset, out indicies, Color.White); + var lighting = new int[6]; + for (int i = 0; i < 6; i++) + { + var coords = (descriptor.Coordinates + FaceCoords[i]); + lighting[i] = GetLight(descriptor.Chunk, coords); + } + + return CreateUniformCube(offset, Texture, faces, indiciesOffset, out indicies, Color.White, lighting); } } } \ No newline at end of file diff --git a/TrueCraft.Client/Rendering/Blocks/FarmlandRenderer.cs b/TrueCraft.Client/Rendering/Blocks/FarmlandRenderer.cs index 175476f..41506ad 100644 --- a/TrueCraft.Client/Rendering/Blocks/FarmlandRenderer.cs +++ b/TrueCraft.Client/Rendering/Blocks/FarmlandRenderer.cs @@ -96,9 +96,16 @@ namespace TrueCraft.Client.Rendering.Blocks var texture = DryTexture; if (descriptor.Metadata == (byte)FarmlandBlock.MoistureLevel.Moist) texture = MoistTexture; + + var lighting = new int[6]; + for (int i = 0; i < 6; i++) + { + var coords = (descriptor.Coordinates + FaceCoords[i]); + lighting[i] = GetLight(descriptor.Chunk, coords); + } var overhead = new Vector3(0.5f, 0.5f, 0.5f); - var cube = CreateUniformCube(overhead, texture, faces, indiciesOffset, out indicies, Color.White); + var cube = CreateUniformCube(overhead, texture, faces, indiciesOffset, out indicies, Color.White, lighting); for (int i = 0; i < cube.Length; i++) { if (cube[i].Position.Y > 0) diff --git a/TrueCraft.Client/Rendering/Blocks/GrassRenderer.cs b/TrueCraft.Client/Rendering/Blocks/GrassRenderer.cs index 893052a..72e7fa9 100644 --- a/TrueCraft.Client/Rendering/Blocks/GrassRenderer.cs +++ b/TrueCraft.Client/Rendering/Blocks/GrassRenderer.cs @@ -103,7 +103,15 @@ namespace TrueCraft.Client.Rendering.Blocks texture = SnowTexture; } } - var cube = CreateUniformCube(offset, texture, faces, indiciesOffset, out indicies, Color.White); + + var lighting = new int[6]; + for (int i = 0; i < 6; i++) + { + var coords = (descriptor.Coordinates + FaceCoords[i]); + lighting[i] = GetLight(descriptor.Chunk, coords); + } + + var cube = CreateUniformCube(offset, texture, faces, indiciesOffset, out indicies, Color.White, lighting); // Apply biome colors to top of cube for (int i = (int)(CubeFace.PositiveY) * 4; i < (int)(CubeFace.PositiveY) * 4 + 4; i++) { diff --git a/TrueCraft.Client/Rendering/Blocks/LeavesRenderer.cs b/TrueCraft.Client/Rendering/Blocks/LeavesRenderer.cs index 6004927..02ac6c5 100644 --- a/TrueCraft.Client/Rendering/Blocks/LeavesRenderer.cs +++ b/TrueCraft.Client/Rendering/Blocks/LeavesRenderer.cs @@ -38,18 +38,25 @@ namespace TrueCraft.Client.Rendering.Blocks public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset, VisibleFaces faces, Tuple textureMap, int indiciesOffset, out int[] indicies) { + var lighting = new int[6]; + for (int i = 0; i < 6; i++) + { + var coords = (descriptor.Coordinates + FaceCoords[i]); + lighting[i] = GetLight(descriptor.Chunk, coords); + } + switch ((WoodBlock.WoodType)descriptor.Metadata) { case WoodBlock.WoodType.Spruce: return CreateUniformCube(offset, SpruceTextures, VisibleFaces.All, - indiciesOffset, out indicies, GrassRenderer.BiomeColor); + indiciesOffset, out indicies, GrassRenderer.BiomeColor, lighting); case WoodBlock.WoodType.Birch: return CreateUniformCube(offset, BaseTextures, VisibleFaces.All, - indiciesOffset, out indicies, GrassRenderer.BiomeColor); + indiciesOffset, out indicies, GrassRenderer.BiomeColor, lighting); case WoodBlock.WoodType.Oak: default: return CreateUniformCube(offset, BaseTextures, VisibleFaces.All, - indiciesOffset, out indicies, GrassRenderer.BiomeColor); + indiciesOffset, out indicies, GrassRenderer.BiomeColor, lighting); } } } diff --git a/TrueCraft.Client/Rendering/Blocks/LogRenderer.cs b/TrueCraft.Client/Rendering/Blocks/LogRenderer.cs index 68399c6..35709b0 100644 --- a/TrueCraft.Client/Rendering/Blocks/LogRenderer.cs +++ b/TrueCraft.Client/Rendering/Blocks/LogRenderer.cs @@ -126,15 +126,22 @@ namespace TrueCraft.Client.Rendering.Blocks public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset, VisibleFaces faces, Tuple textureMap, int indiciesOffset, out int[] indicies) { + var lighting = new int[6]; + for (int i = 0; i < 6; i++) + { + var coords = (descriptor.Coordinates + FaceCoords[i]); + lighting[i] = GetLight(descriptor.Chunk, coords); + } + switch ((WoodBlock.WoodType)descriptor.Metadata) { case WoodBlock.WoodType.Spruce: - return CreateUniformCube(offset, SpruceTexture, faces, indiciesOffset, out indicies, Color.White); + return CreateUniformCube(offset, SpruceTexture, faces, indiciesOffset, out indicies, Color.White, lighting); case WoodBlock.WoodType.Birch: - return CreateUniformCube(offset, BirchTexture, faces, indiciesOffset, out indicies, Color.White); + return CreateUniformCube(offset, BirchTexture, faces, indiciesOffset, out indicies, Color.White, lighting); case WoodBlock.WoodType.Oak: default: - return CreateUniformCube(offset, BaseTexture, faces, indiciesOffset, out indicies, Color.White); + return CreateUniformCube(offset, BaseTexture, faces, indiciesOffset, out indicies, Color.White, lighting); } } } diff --git a/TrueCraft.Client/Rendering/Blocks/TNTRenderer.cs b/TrueCraft.Client/Rendering/Blocks/TNTRenderer.cs index cacfc39..080246f 100644 --- a/TrueCraft.Client/Rendering/Blocks/TNTRenderer.cs +++ b/TrueCraft.Client/Rendering/Blocks/TNTRenderer.cs @@ -55,7 +55,14 @@ namespace TrueCraft.Client.Rendering.Blocks public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset, VisibleFaces faces, Tuple textureMap, int indiciesOffset, out int[] indicies) { - return CreateUniformCube(offset, Texture, faces, indiciesOffset, out indicies, Color.White); + var lighting = new int[6]; + for (int i = 0; i < 6; i++) + { + var coords = (descriptor.Coordinates + FaceCoords[i]); + lighting[i] = GetLight(descriptor.Chunk, coords); + } + + return CreateUniformCube(offset, Texture, faces, indiciesOffset, out indicies, Color.White, lighting); } } } \ No newline at end of file diff --git a/TrueCraft.Client/Rendering/Blocks/WaterRenderer.cs b/TrueCraft.Client/Rendering/Blocks/WaterRenderer.cs index 45b47b3..60453ed 100644 --- a/TrueCraft.Client/Rendering/Blocks/WaterRenderer.cs +++ b/TrueCraft.Client/Rendering/Blocks/WaterRenderer.cs @@ -28,9 +28,16 @@ namespace TrueCraft.Client.Rendering.Blocks public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset, VisibleFaces faces, Tuple textureMap, int indiciesOffset, out int[] indicies) { + var lighting = new int[6]; + for (int i = 0; i < 6; i++) + { + var coords = (descriptor.Coordinates + FaceCoords[i]); + lighting[i] = GetLight(descriptor.Chunk, coords); + } + // TODO: Rest of water rendering (shape and level and so on) var overhead = new Vector3(0.5f, 0.5f, 0.5f); - var cube = CreateUniformCube(overhead, Texture, faces, indiciesOffset, out indicies, Color.Blue); + var cube = CreateUniformCube(overhead, Texture, faces, indiciesOffset, out indicies, Color.Blue, lighting); for (int i = 0; i < cube.Length; i++) { if (cube[i].Position.Y > 0)