From bb617ffc52ddbdd31d5a5279aed1ca3502cbbfc8 Mon Sep 17 00:00:00 2001 From: Jarrod Doyle Date: Tue, 27 Aug 2024 07:46:44 +0100 Subject: [PATCH] Get lightmap data as bytes and blit to atlas --- project/code/LGS/Database/Chunks/WorldRep.cs | 58 ++++++++++++++++++++ project/code/TMV/Mission.cs | 19 +------ 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/project/code/LGS/Database/Chunks/WorldRep.cs b/project/code/LGS/Database/Chunks/WorldRep.cs index 9423b35..74ca946 100644 --- a/project/code/LGS/Database/Chunks/WorldRep.cs +++ b/project/code/LGS/Database/Chunks/WorldRep.cs @@ -1,3 +1,4 @@ +using System; using System.IO; using System.Numerics; @@ -137,6 +138,63 @@ public class WorldRep : IChunk return Vector4.Zero; } } + + public readonly byte[] AsBytesRgba() + { + var length = Width * Height * 4; + var bytes = new byte[length]; + for (var i = 0; i < length; i++) + { + bytes[i] = 0; + } + + // TODO: might be faster to do these fors in the switch? + for (var z = 0; z < Layers; z++) + { + for (var y = 0; y < Height; y++) + { + for (var x = 0; x < Width; x++) + { + var pIdx = 0 + x * Bpp + y * Bpp * Width + z * Bpp * Width * Height; + var r = 0; + var g = 0; + var b = 0; + var a = 0; + switch (Bpp) + { + case 1: + var raw1 = Pixels[pIdx]; + r = raw1; + g = raw1; + b = raw1; + a = 255; + break; + case 2: + var raw2 = Pixels[pIdx] + (Pixels[pIdx + 1] << 8); + r = (int)(255 * (raw2 & 31) / 31.0f); + g = (int)(255 * ((raw2 >> 5) & 31) / 31.0f); + b = (int)(255 * ((raw2 >> 10) & 31) / 31.0f); + a = 255; + break; + case 4: + r = Pixels[pIdx + 2]; + g = Pixels[pIdx + 1]; + b = Pixels[pIdx]; + a = Pixels[pIdx + 3]; + break; + } + + var bIdx = x * 4 + y * 4 * Width; + bytes[bIdx] = (byte)Math.Min(255, bytes[bIdx] + r); + bytes[bIdx + 1] = (byte)Math.Min(255, bytes[bIdx + 1] + g); + bytes[bIdx + 2] = (byte)Math.Min(255, bytes[bIdx + 2] + b); + bytes[bIdx + 3] = (byte)Math.Min(255, bytes[bIdx + 3] + a); + } + } + } + + return bytes; + } } public byte VertexCount { get; set; } diff --git a/project/code/TMV/Mission.cs b/project/code/TMV/Mission.cs index 0fc508a..7b78975 100644 --- a/project/code/TMV/Mission.cs +++ b/project/code/TMV/Mission.cs @@ -299,23 +299,8 @@ public partial class Mission : Node3D if (info.cellIndex >= cells.Length) GD.Print($"CellIndex too big: {info.cellIndex}/{cells.Length}"); if (info.lightmapIndex >= cells[info.cellIndex].Lightmaps.Length) GD.Print($"LightmapIndex too big: {info.lightmapIndex}/{cells[info.cellIndex].Lightmaps.Length}"); var lightmap = cells[info.cellIndex].Lightmaps[info.lightmapIndex]; - var layers = (uint)lightmap.Layers; - var height = (uint)lightmap.Height; - var width = (uint)lightmap.Width; - for (uint y = 0; y < height; y++) - { - for (uint x = 0; x < width; x++) - { - var rawColour = System.Numerics.Vector4.Zero; - for (uint l = 0; l < layers; l++) - { - rawColour += lightmap.GetPixel(l, x, y); - } - - var colour = new Color(MathF.Min(rawColour.X, 1.0f), MathF.Min(rawColour.Y, 1.0f), MathF.Min(rawColour.Z, 1.0f), MathF.Min(rawColour.W, 1.0f)); - image.SetPixel((int)(rect.X + x), (int)(rect.Y + y), colour); - } - } + var cellLm = Image.CreateFromData(lightmap.Width, lightmap.Height, false, Image.Format.Rgba8, lightmap.AsBytesRgba()); + image.BlitRect(cellLm, new Rect2I(0, 0, lightmap.Width, lightmap.Height), new Vector2I((int)rect.X, (int)rect.Y)); if (!surfaceDataMap.ContainsKey(info.textureId)) GD.Print("Invalid SurfaceDataMap key"); surfaceDataMap[info.textureId].TransformUv2s(info.uvStart, info.uvEnd, (uv) =>