From c4aab0d686f5aa1d3f631c8c5f1c5ec7fceaa2a4 Mon Sep 17 00:00:00 2001 From: gmriggs Date: Tue, 23 Jan 2024 18:09:55 -0500 Subject: [PATCH] add support for surface translucency in texture loader / cache (#82) * add support for surface translucency in texture loader / cache * null checks --- ACViewer/Render/TextureCache.cs | 26 ++++++++++++------- .../{TexturePalette.cs => TextureChanges.cs} | 13 +++++++--- 2 files changed, 27 insertions(+), 12 deletions(-) rename ACViewer/Render/{TexturePalette.cs => TextureChanges.cs} (69%) diff --git a/ACViewer/Render/TextureCache.cs b/ACViewer/Render/TextureCache.cs index 1f55c7e..145c0d7 100644 --- a/ACViewer/Render/TextureCache.cs +++ b/ACViewer/Render/TextureCache.cs @@ -23,7 +23,7 @@ public class TextureCache public static GraphicsDevice GraphicsDevice => GameView.Instance.GraphicsDevice; public static SpriteBatch SpriteBatch => GameView.Instance.SpriteBatch; - public static Dictionary Textures { get; set; } + public static Dictionary Textures { get; set; } public static List Uncached { get; set; } @@ -54,7 +54,7 @@ public static void Init(bool dispose = true) GfxObjCache.Init(); SetupCache.Init(); - Textures = new Dictionary(); + Textures = new Dictionary(); Uncached = new List(); } @@ -138,7 +138,9 @@ private static Texture2D LoadTexture(uint textureID, bool useDummy = false, Surf return _tex; case SurfacePixelFormat.PFID_A8R8G8B8: - ConvertToABGR(data); + ConvertToBGRA(data); + if (surface != null && surface.Translucency > 0) + PremultiplyAlpha(data, 1.0f - surface.Translucency); break; } } @@ -291,16 +293,22 @@ private static byte[] AddAlpha(byte[] rgb) return rgba; } - private static void ConvertToABGR(byte[] argb) + private static void ConvertToBGRA(byte[] rgba) { - for (var i = 0; i < argb.Length; i += 4) + for (var i = 0; i < rgba.Length; i += 4) { - var tmp = argb[i]; - argb[i] = argb[i + 2]; - argb[i + 2] = tmp; + var tmp = rgba[i]; + rgba[i] = rgba[i + 2]; + rgba[i + 2] = tmp; } } + private static void PremultiplyAlpha(byte[] bgra, float alpha) + { + for (var i = 3; i < bgra.Length; i += 4) + bgra[i] = (byte)(bgra[i] * alpha); + } + private static byte[] IndexToColor(ACE.DatLoader.FileTypes.Texture texture, bool isClipMap = false, PaletteChanges paletteChanges = null) { var colors = GetColors(texture); @@ -492,7 +500,7 @@ private static Texture2D GetTexture(uint textureID, Surface surface = null, Pale { //Console.WriteLine($"-> GetTexture({textureID:X8})"); - var texturePalette = new TexturePalette(textureID, paletteChanges); + var texturePalette = new TextureChanges(textureID, surface?.Translucency ?? 0.0f, paletteChanges); if (useCache && Textures.TryGetValue(texturePalette, out var cached)) return cached; diff --git a/ACViewer/Render/TexturePalette.cs b/ACViewer/Render/TextureChanges.cs similarity index 69% rename from ACViewer/Render/TexturePalette.cs rename to ACViewer/Render/TextureChanges.cs index dc50d22..ea8ac05 100644 --- a/ACViewer/Render/TexturePalette.cs +++ b/ACViewer/Render/TextureChanges.cs @@ -4,22 +4,27 @@ namespace ACViewer.Render { - public class TexturePalette: IEquatable + public class TextureChanges: IEquatable { public uint TextureId { get; set; } // 0x6 texture file id + public float Translucency { get; set; } public PaletteChanges PaletteChanges { get; set; } - public TexturePalette(uint textureId, PaletteChanges paletteChanges = null) + public TextureChanges(uint textureId, float translucency = 0.0f, PaletteChanges paletteChanges = null) { TextureId = textureId; + Translucency = translucency; PaletteChanges = paletteChanges; } - public bool Equals(TexturePalette tp) + public bool Equals(TextureChanges tp) { if (TextureId != tp.TextureId) return false; + if (Translucency != tp.Translucency) + return false; + if (PaletteChanges == null && tp.PaletteChanges == null) return true; @@ -37,6 +42,8 @@ public override int GetHashCode() int hash = 0; hash = (hash * 397) ^ TextureId.GetHashCode(); + + hash = (hash * 397) ^ Translucency.GetHashCode(); if (PaletteChanges != null) hash = (hash * 397) ^ PaletteChanges.GetHashCode();