Colour pixel-art toolbar icons, 64 px toolbar slots, ViewportCapture: screenshots in sRGB under hdr_2d
No files matched your search
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 390 B After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 5.7 KiB |