Kagamia / WzComparerR2

Maplestory online Extractor
MIT License
406 stars 132 forks source link

MapRenderer: transparency not applied to background color (argb) selection #236

Closed nanochromatic closed 11 months ago

nanochromatic commented 11 months ago

When exporting a map render, alpha transparency is not applied if the background color selection (UIOptionsDataModel.ScreenshotBackgroundColor) includes an alpha channel (eg. ffffffff). Instead, the color is applied without the alpha transparency in the output png file.

Kagamia commented 11 months ago

Yes, this is a known issue that tracked in #203

Still need more investigation.

Kagamia commented 11 months ago

Fixed in https://github.com/Kagamia/WzComparerR2/commit/8978193e41df63ffc43b3d27987070f1efa4348c.

It should have been some kind of design behavior, actually the backbuffer is always in RGB format so I force reset the alpha to 255 before encoding to png file.

Now we can clear the backbuffer with an PMA color and convert it back to non-PMA color with PngEffect.

nanochromatic commented 11 months ago

~Tested the latest CI build, but still seeing the issue. I'm using ffffffff as the arbg color.~ User error: the correct color for transparent white should be 00ffffff. The fix is working as intended.

Separately, I've also noticed an error thrown intermittently after I press Scroll Lock to export a map render (uncertain if related to the recent argb fix). However, the png file is still written.

image

[Error][MapRender] MapRender error:System.InvalidOperationException: Object is currently in use elsewhere.
   at System.Drawing.Graphics.MeasureString(String text, Font font, SizeF layoutArea, StringFormat stringFormat)
   at System.Drawing.Graphics.MeasureString(String text, Font font, Int32 width, StringFormat format)
   at WzComparerR2.Rendering.XnaFont.CreateCharBuffer(Char c)
   at WzComparerR2.Rendering.XnaFont.TryGetRect(Char c)
   at WzComparerR2.Rendering.XnaFont.MeasureString(IEnumerable`1 text, Vector2 layoutSize)
   at WzComparerR2.MapRender.XnaFontAdapter.MeasureString(String text)
   at WzComparerR2.MapRender.UI.WcR2Font.MeasureString(String text, Single dpiScaleX, Single dpiScaleY)
   at EmptyKeys.UserInterface.Controls.TextBlock.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.UIElement./*ȓ(Size 00214*/)
   at EmptyKeys.UserInterface.UIElement.Measure(Size availableSize)
   at EmptyKeys.UserInterface.Controls.Border.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.UIElement./*ȓ(Size 00214*/)
   at EmptyKeys.UserInterface.UIElement.Measure(Size availableSize)
   at EmptyKeys.UserInterface.Controls.StackPanel.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.UIElement./*ȓ(Size 00214*/)
   at EmptyKeys.UserInterface.UIElement.Measure(Size availableSize)
   at EmptyKeys.UserInterface.Controls.ContentPresenter.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.Controls.ScrollContentPresenter.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.UIElement./*ȓ(Size 00214*/)
   at EmptyKeys.UserInterface.UIElement.Measure(Size availableSize)
   at EmptyKeys.UserInterface.Controls.Grid./*࠽(/\*߻ 0083E*/, UIElement 0083F*/, Boolean 00840*/)
   at EmptyKeys.UserInterface.Controls.Grid./*ࠟ(Int32 00820*/, Boolean 00821*/, Boolean 00822*/, Boolean& 00823*/)
   at EmptyKeys.UserInterface.Controls.Grid.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.UIElement./*ȓ(Size 00214*/)
   at EmptyKeys.UserInterface.UIElement.Measure(Size availableSize)
   at EmptyKeys.UserInterface.Controls.Border.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.UIElement./*ȓ(Size 00214*/)
   at EmptyKeys.UserInterface.UIElement.Measure(Size availableSize)
   at EmptyKeys.UserInterface.Controls.ScrollViewer.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.UIElement./*ȓ(Size 00214*/)
   at EmptyKeys.UserInterface.UIElement.Measure(Size availableSize)
   at EmptyKeys.UserInterface.Controls.Border.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.UIElement./*ȓ(Size 00214*/)
   at EmptyKeys.UserInterface.UIElement.Measure(Size availableSize)
   at EmptyKeys.UserInterface.Controls.Grid./*࠽(/\*߻ 0083E*/, UIElement 0083F*/, Boolean 00840*/)
   at EmptyKeys.UserInterface.Controls.Grid./*ࠟ(Int32 00820*/, Boolean 00821*/, Boolean 00822*/, Boolean& 00823*/)
   at EmptyKeys.UserInterface.Controls.Grid.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.UIElement./*ȓ(Size 00214*/)
   at EmptyKeys.UserInterface.UIElement.Measure(Size availableSize)
   at EmptyKeys.UserInterface.Controls.ContentPresenter.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.UIElement./*ȓ(Size 00214*/)
   at EmptyKeys.UserInterface.UIElement.Measure(Size availableSize)
   at EmptyKeys.UserInterface.Controls.Control.MeasureOverride(Size availableSize)
   at EmptyKeys.UserInterface.UIElement./*ȓ(Size 00214*/)
   at EmptyKeys.UserInterface.UIElement.Measure(Size availableSize)
   at EmptyKeys.UserInterface.Controls.UIRoot.UpdateLayout(Double elapsedGameTime)
   at WzComparerR2.MapRender.FrmMapRender2.SceneUpdate()
   at WzComparerR2.MapRender.FrmMapRender2.<OnSceneRunning>d__79.MoveNext()
   at WzComparerR2.MapRender.CoroutineManager.Update(GameTime gameTime)
   at Microsoft.Xna.Framework.Game.<>c.<.cctor>b__115_1(IUpdateable updateable, GameTime gameTime)
   at Microsoft.Xna.Framework.Game.SortingFilteringCollection`1.ForEachFilteredItem[TUserData](Action`2 action, TUserData userData)
   at WzComparerR2.MapRender.FrmMapRender2.Update(GameTime gameTime)
   at Microsoft.Xna.Framework.Game.DoUpdate(GameTime gameTime)
   at Microsoft.Xna.Framework.Game.Tick()
   at MonoGame.Framework.WinFormsGameWindow.TickOnIdle(Object sender, EventArgs e)
   at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at MonoGame.Framework.WinFormsGameWindow.RunLoop()
   at MonoGame.Framework.WinFormsGamePlatform.RunLoop()
   at Microsoft.Xna.Framework.Game.Run(GameRunBehavior runBehavior)
   at WzComparerR2.MapRender.Entry.<>c__DisplayClass5_0.<btnItem_Click>b__0()
Kagamia commented 11 months ago

@nanochromatic Never seen it before, interesting. Would you like to provide a more detailed stable repro steps?

PirateIzzy commented 11 months ago

@Kagamia I was able to reproduce it with your latest CMS build by opening MapRender and pressing Scroll Lock to take a screenshot.

https://github.com/Kagamia/WzComparerR2/assets/34289651/d9ffc627-bd5f-4d37-a56c-65af2c65e75e

nanochromatic commented 11 months ago

It appears to impact all maps very consistently for me.

Steps to reproduce:

  1. Open any map in MapRender (I'll choose 001000000 here)
  2. Press Scroll Lock a few seconds after MapRender comes up
  3. You should see the error pop up

Here's a dump file produced with VS2022, in case it helps: link

Kagamia commented 11 months ago

It should be a bug caused by UI updates triggerred from a non-main thread.

plz checkout the latest release. Thank you both :)

nanochromatic commented 11 months ago

Tested the latest release and can confirm it's been fixed. 😄

nanochromatic commented 11 months ago

@Kagamia #203 can be closed as well.