Skip to content

Instantly share code, notes, and snippets.

@pardeike
Last active May 8, 2020 18:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pardeike/62e456fed1c5ce7a5dea17c9412026ac to your computer and use it in GitHub Desktop.
Save pardeike/62e456fed1c5ce7a5dea17c9412026ac to your computer and use it in GitHub Desktop.
Bug rendering Gizmo's from RimWorld into a rendertexture [https://youtu.be/ZKcFkbCPYts]
// this code works "most of the time"
// sometimes, without any idea why, it generates a transparent image
// as if the drawing calls are not working, leaving the image empty
// Video showing this behaviour: https://youtu.be/ZKcFkbCPYts
public static byte[] GetCommandsMatrix(List<Command> commands)
{
var count = commands.Count;
if (count == 0) return null;
var size = 75;
var renderTexture = RenderTexture.GetTemporary(count * size, size, 0, RenderTextureFormat.ARGB32);
var active = RenderTexture.active;
RenderTexture.active = renderTexture;
GL.PushMatrix();
GL.LoadPixelMatrix(0, count * size, size, 0);
var rect = new Rect(0, 0, size, size);
for (var i = 0; i < count; i++)
{
_ = commands[i].GizmoOnGUI(new Vector2(i * size, 0), 100000);
rect.x += size;
}
GL.PopMatrix();
var result = new Texture2D(count * size, size, TextureFormat.ARGB32, false);
result.ReadPixels(new Rect(0, 0, count * size, size), 0, 0, false);
RenderTexture.active = active;
RenderTexture.ReleaseTemporary(renderTexture);
var data = result.EncodeToPNG();
File.WriteAllBytes(@"C:\Users\andre\Desktop\Icons\gizmo.png", data);
UnityEngine.Object.Destroy(result);
return data;
}
// called from
var commands = GizmosHandler.GetCommands(obj);
OperationQueue.Add(OperationType.Select, () =>
{
var bracketLocs = new Vector3[4];
var atlas = Renderer.GetCommandsMatrix(commands);
// ... sending and saving to debug png
}
// which is called from
[HarmonyPatch(typeof(WindowStack))]
[HarmonyPatch(nameof(WindowStack.WindowStackOnGUI))]
static class WindowStack_WindowStackOnGUI_Patch
{
public static void Postfix()
{
OperationQueue.Process(OperationType.Select);
}
}
// OperationQueue
using System;
using System.Collections.Concurrent;
namespace Puppeteer
{
public enum OperationType
{
Portrait,
SetState,
Job,
Log,
Select
}
public static class OperationQueue
{
static readonly ConcurrentDictionary<OperationType, ConcurrentQueue<Action>> state = new ConcurrentDictionary<OperationType, ConcurrentQueue<Action>>();
public static void Add(OperationType type, Action action)
{
if (state.TryGetValue(type, out var queue) == false)
{
queue = new ConcurrentQueue<Action>();
_ = state.TryAdd(type, queue);
}
queue.Enqueue(action);
}
public static void Process(OperationType type)
{
if (state.TryGetValue(type, out var queue))
{
try
{
if (queue.TryDequeue(out var item))
item.Invoke();
}
catch (Exception e)
{
Tools.LogWarning($"While dequeuing {type}: {e}");
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment