Fexty12573 / SharpPluginLoader

A C# plugin loader for Monster Hunter World
MIT License
32 stars 2 forks source link

[Bug] ImGui Main Viewport Resolution and HiDPI Issue #24

Open GreenComfyTea opened 6 months ago

GreenComfyTea commented 6 months ago

Describe The Bug

In some game configuration cases ImGui viewport resolution doesn't match the game resolution, causing ImGui to either be cut off in the middle of the screen or go outside of the game.

Little dive into my configuration before showcasing the issue: I have a 1080p 60Hz 96DPI (x1 scale) main display with the game + 2 additional displays on each side (both 1366x768 60Hz x1 scale).

On my Nvidia card to get higher in-game resolution options available than the max display resolution I use DSR (Dynamic Super Resolution). Since the game has awful Anti-Aliasing options, downscaling from super resolution is a recommended way to achieve AA on powerful systems, so I am not discarding this edge case, as other power gamers may be using DSR as well.

Screenshot 1 ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/d480e0a8-bf2c-4dd2-8b90-20aacdb25c98)
Screenshot 2 ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/bc2aae03-d3aa-4cf7-b34c-c606f868abd3)

To better visualize the actual viewport, I draw a giant half-transparent red rectangle with 5000x5000 size.

var backgroundDrawList = ImGui.GetBackgroundDrawList();

var position = new Vector2(0, 0);
var size = new Vector2(5000, 5000);

backgroundDrawList.AddRectFilled(position, position + size, 0xAA0000FF);

On the screenshots pay attention where actual Tea Overlay window is on the screen and where it is on small viewport visualization in the debugger.

Fullscreen works because it actually changes the display resolution:

1) Fullscreen + 1280x720 Game Resolution -> OK;

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/cbb4a0d1-ce62-4a1d-b8de-adab801220ad)

2) Fullscreen + 1920x1080 Game Resolution -> OK;

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/18c6ddf1-59cb-41ca-84f2-b78d386e8073)

3) Fullscreen + 2880x1620 Game Resolution -> OK;

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/236a6075-6437-431b-ad2c-369a0751eb91)

Windowed Mode:

1) Windowed Mode + 1280x720 Game Resolution -> OK;

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/0fbe27c6-d97f-416f-9e47-ea2a4e480be5)

2) Windowed Mode + 1920x1080 Game Resolution -> 19 pixels are cut off from the bottom;

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/fd4a523f-9171-4e9a-90e6-5a4ee956e702)

3) Windowed Mode + 2880x1620 Game Resolution -> ???;

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/c832ba01-5019-41e6-9bbc-ddb3af6127dc)

Borderless Window:

1) Borderless Window + 1280x720 Game Resolution -> ImGui goes beyond the game;

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/136c6d53-56df-497a-98d4-4930158d557c)

2) Borderless Window + 1920x1080 Game Resolution -> OK;

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/7270c640-b026-4cf5-aca3-9f0708577bf8)

3) Borderless Window + 2880x1620 Game Resolution -> ImGui is cut mid-screen;

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/5f85537f-88ec-4c47-9965-560cc15d2509)

Video

I have been able to partially fix the viewport with this code:

ImGui.GetMainViewport().WorkSize = new Vector2(2880f, 1620f);
ImGui.GetMainViewport().Size = new Vector2(2880f, 1620f);

But unfortunately it only affects where ImGui is allowed to draw windows and stuff. Mouse still behaves incorrectly as if the mouse viewport was scaled down and desynchronizes with the actual cursor.

Video

Playing around with ImGui.GetIO().DisplaySize and ImGui.GetIO().DisplayFramebufferScale gave no results. ImGui.GetDrawData().ScaleClipRects() causes a crash.

I don't if it is relevant, but in Borderless Window the game doesn't launch the game window at the target display resolution, but instead launches the window with the game resolution -> then ImGui gets initialized in 1080p -> then GPU driver scales down the whole window to fit into the target display. (In contrast to when Resolution may refer to 3D Rendering Resolution, often present as % Scaling in modern games).

As a result, we end up with target resolution being smaller than the resolution used by the framebuffer. This sounds a lot like how Hi-DPI Retina screens work. where there is a pixel ratio of 2.0 between the size of the framebuffer and the size of the application window. Reference 1 Reference 2

So I assume Hi-DPI display will have a similar issue as well.

As a side note, ImGui looks readable only in 1080p. On higher resolutions (in other words, on higher DPI displays) it will look tiny and on smaller resolutions it will look big. SPL probably should scale it's main ImGui window automatically or provide for end users a way to scale it manually. But going further, perhaps, SPL should automatically handle default scaling for plugins as well?

To Reproduce

1) Launch the game in Borderless Window or Windowed Mode with a resolution that is different from the display resolution.

Expected Behavior

ImGui viewport should match the game resolution.

Priority

Suggested P2 Priority. The issue alters the indented functionality of SPL and plugins under some circumstances.

PC Specs

Show/Hide - `Motherboard`**: Asus ROG Strix Z390-H Gaming** - `CPU`**: Intel Core i9-9900k** - `RAM`**: 32 GB 3200MHz** - `GPU`**: Nvidia GeForce RTX 3090 Ti** - `System and Game SSD`**: Samsung SSD 970 EVO Plus NVMe M.2 1TB** - `Plugin Repo SSD`**: Western Digital Blue SATA M.2 2280 2TB**

Environment

Show/Hide - `OS`: **Window 10 Enterprise Version 22H2 (OS Build 19045.3996)** - `Monster Hunter: World`: **v15.21.00** - `SharpPluginLoader`: **pre-v0.0.4.0 (bea10943ea02b8d3f75d99a328e8012a45595b84)** - `Nvidia Drivers`**: v551.52**

Game Display Settings

Show/Hide - `DirectX 12 API`**: On** - `Screen Mode`**: ~~~** - `Resolution Settings`**: ~~~** - `Aspect Ratio`**: Wide (16:9)** - `Nvidia DLSS`**: Off** - `FidelityFX CAS + Upscaling`**: Off** - `Frame Rate`**: No Limit** - `V-Sync`**: On**

Game Advanced Graphics Settings

Show/Hide - `Image Quality`**: High** - `Texture Quality`**: High Resolution Texture Pack** - `Ambient Occlusion`**: High** - `Volume Rendering Quality`**: Highest** - `Shadow Quality`**: High** - `Capsule AO`**: On** - `Contact Shadows`**: On** - `Anti-Aliasing`**: Off** - `LOD Bias`**: High** - `Max LOD Level`**: No Limit** - `Foliage Sway`**: On** - `Subsurface Scattering`**: On** - `Screen Space Reflection`**: On** - `Anisotropic Filtering`**: Highest** - `Water Reflection`**: On** - `Snow Quality`**: High** - `SH Diffuse Quality`**: High** - `Dynamic Range`**: 64-bit** - `Motion Blur`**: On** - `DOF (Depth of Field)`**: On** - `Vignette Effects`**: Normal** - `Z-Prepass`**: On**

Mods and External Tools:

Show/Hide - [RTSS Overlay v7.3.4](https://www.guru3d.com/page/rivatuner-rtss-homepage/) - [Reshade 6.0.0](https://reshade.me/) with SMAA.fx - [Stracker's Loader v3.0.1](https://www.nexusmods.com/monsterhunterworld/mods/1982) - [Performance Booster and Plugin Extender v1.3](https://www.nexusmods.com/monsterhunterworld/mods/3473) - [HunterPie v2.10.0.134](https://www.nexusmods.com/monsterhunterrise/mods/181) - [HelloWorld (an overlay that shows lots and lots of stuff) v10.4](https://www.nexusmods.com/monsterhunterworld/mods/142) - [Bow Spread Pattern Fix v1.0](https://www.nexusmods.com/monsterhunterworld/mods/6914) - [Tic Rate Fix v1.0](https://www.nexusmods.com/monsterhunterworld/mods/3474) - [Guiding Lands Gathering Indicator v1.12.11.01](https://www.nexusmods.com/monsterhunterworld/mods/1986) - [Gems Sorted by Name (Alphabetized Gems) v1.6.1](https://www.nexusmods.com/monsterhunterworld/mods/2364) - [Reshade Hook v1.0](https://www.nexusmods.com/monsterhunterworld/mods/7015) - [Endemic Quality (Iceborne Edition) v1.4](https://www.nexusmods.com/monsterhunterworld/mods/2137) - [Remove censor bad word banned word filter v1.0](https://www.nexusmods.com/monsterhunterworld/mods/6956) - [Monster Weakness Icon Indicator for Iceborne (Hi-Res) vFinal](https://www.nexusmods.com/monsterhunterworld/mods/1938) - [Cuter Handler Face Model (Post-Iceborne) aka Make Handler Cuter Again v3.0](https://www.nexusmods.com/monsterhunterworld/mods/1914)

Additional Context

Plugin Repo

Fexty12573 commented 6 months ago

The viewport size issue at least should be fixed as of 8025cbaea2c22abdf416a1c453fcd5d2df1d0dd7. Can you check and confirm?

Fexty12573 commented 6 months ago

I suppose I would need to make a release for this.. unless you're willing it compile it locally.

GreenComfyTea commented 6 months ago

i will compile, dw.

GreenComfyTea commented 6 months ago

With Borderless Windowed and Super Resolution (2880x1620) on 1080p display:

The area where ImGui can draw is fixed but not the mouse viewport.

Red = Drawing area

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/0b1b9af2-7995-4711-9e8d-0e21a755a087)

Yellow + Gray = Mouse area, where I can see and move the cursor Yellow = Can interact with ImGui windows Grey = Can't interact

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/d3fc43fa-25dc-4566-b8f5-b0ca3a495306)

ImGui draws it's cursor in different place than the actual cursor.

For example, on the image below there is a blocked zone in the top-right because my actual cursor hits top-right edge of the display, while imgui cursor stays more to the middle of the screen.

And the reason why i can move more to the right if i go lower (grey area) - is because my actual cursor will go onto the 2nd display on the right, while imgui cursor is still being on the main display. And because actual cursor is already on the 2nd display - any mouse input defocuses the game so i cant interact with imgui.

Screenshot ![image](https://github.com/Fexty12573/SharpPluginLoader/assets/30152047/94edff35-667e-473a-b3e1-29d214ea50f4)

The difference between imgui cursor coordinates is 1.5x, which comes from downscaling the resolution (2880x1620) to fit the display (1920x1080).

2880 / 1920 = 1.5
1620 / 1080 = 1.5

imgui cursor viewport before downscaling is 1920x1080 for me. And after downscaling it becomes 1280x720, which is yellow area.

1920 / 1.5 = 1280
1080 / 1.5 = 720

Basically, right now it behaves the same as with my dank fix earlier:

ImGui.GetMainViewport().WorkSize = new Vector2(2880f, 1620f);
ImGui.GetMainViewport().Size = new Vector2(2880f, 1620f);
Fexty12573 commented 5 months ago

Yeah I honestly have no idea how to fix the mouse cursor issue.