Colour pixel-art toolbar icons, 64 px toolbar slots, ViewportCapture: screenshots in sRGB under hdr_2d

This commit is contained in:
cthangover committed 2026-10-23 09:03:53 +02:00
1 parent 7dd97768d9
commit 891c327600
11 files changed
+53 -3

No files matched your search

+7 -3
View File
@@ -22,6 +22,10 @@ namespace Cthangover.Mods.Interface.Tool
/// </summary>
public partial class ToolBox : Control, IToolbarHost, ISaveIconHost
{
/// <summary>Side of a toolbar button and its icon: the icons are 64 px pixel-art sprites (scaled x4), so a
/// 64 px slot shows every sprite pixel; at 60 px the nearest filter dropped rows of them.</summary>
private const int SlotSize = 64;
private HBoxContainer _buttons;
private TextureRect _saveIcon;
@@ -64,14 +68,14 @@ namespace Cthangover.Mods.Interface.Tool
{
var button = new Button
{
CustomMinimumSize = new Vector2(60, 60),
CustomMinimumSize = new Vector2(SlotSize, SlotSize),
SizeFlagsVertical = SizeFlags.ShrinkCenter,
TooltipText = title,
};
if (icon != null)
{
var iconRect = UiKit.Icon(icon, 60);
var iconRect = UiKit.Icon(icon, SlotSize);
button.AddChild(iconRect);
iconRect.SetAnchorsAndOffsetsPreset(LayoutPreset.FullRect);
}
@@ -92,7 +96,7 @@ namespace Cthangover.Mods.Interface.Tool
/// <summary>
/// Adds one "tools" toolbar button whose popup lists every visible
/// <see cref="IToolBoxButton"/>. Tools used to get a text button each,
/// which did not fit the 60×60 icon row and overlapped its icons; a
/// which did not fit the square icon row and overlapped its icons; a
/// single icon keeps the HUD row uniform no matter how many tools are
/// installed. Nothing is added when no tool button is visible.
/// </summary>
+46
View File
@@ -0,0 +1,46 @@
namespace Cthangover.Mods.Interface.View
{
using System;
using System.Runtime.InteropServices;
using Godot;
/// <summary>
/// Takes a screenshot of a viewport the way the player sees it.
/// </summary>
/// <remarks>
/// The project renders 2D in HDR (<c>rendering/viewport/hdr_2d</c>): the viewport texture then holds linear
/// colour, and Godot converts it to sRGB only when it blits to the window. A plain
/// <c>GetTexture().GetImage().SavePng()</c> wrote those linear values, so every screenshot (the site's
/// gallery included) came out much darker than the game, shadows most of all. The conversion runs on
/// float data before the 8-bit quantisation, so dark gradients do not band.
/// </remarks>
public static class ViewportCapture
{
/// <summary>The current frame of <paramref name="viewport"/> as RGBA8 sRGB, or null without a frame.</summary>
public static Image Take(Viewport viewport)
{
var image = viewport.GetTexture()?.GetImage();
if (image == null || !viewport.UseHdr2D)
return image;
image.Convert(Image.Format.Rgbaf);
var floats = MemoryMarshal.Cast<byte, float>(image.GetData());
var bytes = new byte[floats.Length];
for (var i = 0; i < floats.Length; i++)
{
var v = Math.Clamp(floats[i], 0f, 1f);
if (i % 4 != 3)
v = v <= 0.0031308f ? v * 12.92f : 1.055f * MathF.Pow(v, 1f / 2.4f) - 0.055f;
bytes[i] = (byte)MathF.Round(v * 255f);
}
return Image.CreateFromData(image.GetWidth(), image.GetHeight(), false, Image.Format.Rgba8, bytes);
}
/// <summary>Saves the current frame of <paramref name="viewport"/> as a PNG; false without a frame.</summary>
public static bool SavePng(Viewport viewport, string path)
{
var image = Take(viewport);
return image != null && image.SavePng(path) == Error.Ok;
}
}
}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB