Skip to content

Commit

Permalink
Fix transforms not rendering (#1771)
Browse files Browse the repository at this point in the history
Co-authored-by: amylizzle <[email protected]>
  • Loading branch information
amylizzle and amylizzle authored May 18, 2024
1 parent e4971cc commit 18ba23b
Showing 1 changed file with 31 additions and 13 deletions.
44 changes: 31 additions & 13 deletions OpenDreamClient/Rendering/DreamViewOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -415,12 +415,15 @@ public void DrawIcon(DrawingHandleWorld handle, Vector2i renderTargetSize, Rende
//KEEP_TOGETHER groups
if (iconMetaData.KeepTogetherGroup?.Count > 0) {
// TODO: Use something better than a hardcoded 64x64 fallback
iconMetaData.TextureOverride = ProcessKeepTogether(handle, iconMetaData, iconMetaData.Texture?.Size ?? (64,64));
Vector2i ktSize = iconMetaData.Texture?.Size ?? (64,64);
iconMetaData.TextureOverride = ProcessKeepTogether(handle, iconMetaData, ktSize);
positionOffset -= ((ktSize/EyeManager.PixelsPerMeter) - Vector2.One) * new Vector2(0.5f); //correct for KT group texture offset
}

var pixelPosition = (iconMetaData.Position + positionOffset) * EyeManager.PixelsPerMeter;
var frame = iconMetaData.Texture;


//if frame is null, this doesn't require a draw, so return NOP
if (frame == null)
return;
Expand All @@ -437,10 +440,10 @@ public void DrawIcon(DrawingHandleWorld handle, Vector2i renderTargetSize, Rende

if (goFastOverride || icon.Appearance == null || icon.Appearance.Filters.Count == 0) {
//faster path for rendering unfiltered sprites
DrawIconFast(handle, renderTargetSize, frame, pixelPosition, GetBlendAndColorShader(iconMetaData));
DrawIconFast(handle, renderTargetSize, frame, pixelPosition, iconMetaData.TransformToApply, GetBlendAndColorShader(iconMetaData));
} else {
//Slower path for filtered icons
DrawIconSlow(handle, frame, iconMetaData, renderTargetSize, pixelPosition);
DrawIconSlow(handle, frame, iconMetaData, renderTargetSize, pixelPosition, iconMetaData.TransformToApply);
}
}

Expand Down Expand Up @@ -748,8 +751,9 @@ private Texture ProcessKeepTogether(DrawingHandleWorld handle, RendererMetaData
iconMetaData.AlphaToApply = 1f;
iconMetaData.BlendMode = BlendMode.Default;

List<RendererMetaData> ktItems = new List<RendererMetaData>(iconMetaData.KeepTogetherGroup!.Count+1);
ktItems.Add(iconMetaData);
List<RendererMetaData> ktItems = new List<RendererMetaData>(iconMetaData.KeepTogetherGroup!.Count + 1) {
iconMetaData
};
ktItems.AddRange(iconMetaData.KeepTogetherGroup);
iconMetaData.KeepTogetherGroup.Clear();

Expand All @@ -760,7 +764,7 @@ private Texture ProcessKeepTogether(DrawingHandleWorld handle, RendererMetaData

handle.RenderInRenderTarget(tempTexture, () => {
foreach (RendererMetaData ktItem in ktItems) {
DrawIcon(handle, tempTexture.Size, ktItem, -ktItem.Position);
DrawIcon(handle, tempTexture.Size, ktItem, -ktItem.Position+((tempTexture.Size/EyeManager.PixelsPerMeter) - Vector2.One) * new Vector2(0.5f)); //draw the icon in the centre of the KT render target
}
}, null);

Expand All @@ -787,17 +791,33 @@ private Texture ProcessKeepTogether(DrawingHandleWorld handle, RendererMetaData
/// Render a texture without applying any filters, making this faster and cheaper.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void DrawIconFast(DrawingHandleWorld handle, Vector2i renderTargetSize, Texture texture, Vector2 pos, ShaderInstance? shader) {
private static void DrawIconFast(DrawingHandleWorld handle, Vector2i renderTargetSize, Texture texture, Vector2 pos, Matrix3 transform, ShaderInstance? shader) {
handle.UseShader(shader);
handle.SetTransform(CreateRenderTargetFlipMatrix(renderTargetSize, pos));

//extract scale component of transform
Vector2 scaleFactors = new Vector2(
MathF.Sqrt(MathF.Pow(transform.R0C0,2) + MathF.Pow(transform.R0C1,2)),
MathF.Sqrt(MathF.Pow(transform.R1C0,2) + MathF.Pow(transform.R1C1,2))
);
transform.R0C0 /= scaleFactors.X;
transform.R0C1 /= scaleFactors.X;
transform.R1C0 /= scaleFactors.Y;
transform.R1C1 /= scaleFactors.Y;

handle.SetTransform(
Matrix3.CreateTranslation(-texture.Size/2) //translate to origin
* transform //rotate and translate
* Matrix3.CreateTranslation(texture.Size/2) //translate back to original position
* Matrix3.CreateScale(scaleFactors) //scale
* CreateRenderTargetFlipMatrix(renderTargetSize, pos-((scaleFactors-Vector2.One)*texture.Size/2))); //flip and apply scale-corrected translation
handle.DrawTextureRect(texture, Box2.FromDimensions(Vector2.Zero, texture.Size));
}

/// <summary>
/// A slower method of drawing an icon. This one renders an atom's filters.
/// Use <see cref="DrawIconFast"/> instead if the icon has no special rendering needs.
/// </summary>
private void DrawIconSlow(DrawingHandleWorld handle, Texture frame, RendererMetaData iconMetaData, Vector2i renderTargetSize, Vector2 pos) {
private void DrawIconSlow(DrawingHandleWorld handle, Texture frame, RendererMetaData iconMetaData, Vector2i renderTargetSize, Vector2 pos, Matrix3 transform) {
//first we do ping pong rendering for the multiple filters
// TODO: This should determine the size from the filters and their settings, not just double the original
IRenderTexture ping = RentRenderTarget(frame.Size * 2);
Expand Down Expand Up @@ -827,17 +847,15 @@ private void DrawIconSlow(DrawingHandleWorld handle, Texture frame, RendererMeta
handle.UseShader(s);

// Technically this should be ping.Size, but they are the same size so avoid the extra closure alloc
var transform = CreateRenderTargetFlipMatrix(pong.Size, Vector2.Zero);

handle.SetTransform(transform);
handle.SetTransform(CreateRenderTargetFlipMatrix(pong.Size, Vector2.Zero));
handle.DrawTextureRect(pong.Texture, new Box2(Vector2.Zero, pong.Size));
}, Color.Black.WithAlpha(0));

(ping, pong) = (pong, ping);
}

//then we draw the actual icon with filters applied
DrawIconFast(handle, renderTargetSize, pong.Texture, pos - frame.Size / 2,
DrawIconFast(handle, renderTargetSize, pong.Texture, pos - frame.Size / 2, transform,
//note we apply the color *before* the filters, so we ignore color here
GetBlendAndColorShader(iconMetaData, ignoreColor: true)
);
Expand Down

0 comments on commit 18ba23b

Please sign in to comment.