using System.IO; using UnityEngine; namespace Luneraria.UI { /// /// Screenshots of the scene with the HUD on top, also in batch mode: the camera renders into /// one texture, the HUD panel into its own (premultiplied alpha), and both are composed on the /// CPU. Used by the U3 tests and captures; the player can also capture the real screen. /// public static class LuneHudCapture { public static Texture2D Read(RenderTexture texture) { RenderTexture previous = RenderTexture.active; RenderTexture.active = texture; var image = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false); image.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0); image.Apply(); RenderTexture.active = previous; return image; } public static Texture2D RenderScene(Camera camera, int width, int height) { var target = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32) { antiAliasing = 4 }; RenderTexture previous = camera.targetTexture; float aspect = camera.aspect; camera.aspect = (float)width / height; camera.targetTexture = target; camera.Render(); camera.targetTexture = previous; camera.aspect = aspect; Texture2D image = Read(target); target.Release(); Object.Destroy(target); return image; } /// HUD (premultiplied alpha) over the scene: out = hud + scene · (1 − hud alpha). public static Texture2D Compose(Texture2D scene, Texture2D hud) { Color32[] under = scene.GetPixels32(); Color32[] over = hud.GetPixels32(); var result = new Color32[under.Length]; for (int index = 0; index < under.Length; index++) { Color32 a = over[index]; Color32 b = under[index]; int keep = 255 - a.a; result[index] = new Color32((byte)Mathf.Min(255, a.r + b.r * keep / 255), (byte)Mathf.Min(255, a.g + b.g * keep / 255), (byte)Mathf.Min(255, a.b + b.b * keep / 255), 255); } var image = new Texture2D(scene.width, scene.height, TextureFormat.RGBA32, false); image.SetPixels32(result); image.Apply(); return image; } /// PNG, or JPEG (quality 90) for a .jpg file. public static void Save(Texture2D image, string file) { Directory.CreateDirectory(Path.GetDirectoryName(file)); bool jpeg = file.EndsWith(".jpg", System.StringComparison.OrdinalIgnoreCase); File.WriteAllBytes(file, jpeg ? image.EncodeToJPG(90) : image.EncodeToPNG()); } } }