godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.81k stars 20.14k forks source link

Rendering error: When setting screen stretch, black bars remain even when not enabling stretching or fullscreen #89626

Open POWERUPT opened 5 months ago

POWERUPT commented 5 months ago

Tested versions

-Reproducable in v3.5.3.stable.official [6c814135b]

System information

Windows 10, Nvidia GTX 1060, Ryzen 5 2600

Issue description

I was attempting to make my project in Godot have the option to either stretch the image, or keep the pixels 1 to 1 and use a border. Both of these modes work perfectly fine on their own, however, there is something wrong when switching between them programmatically. The integer scaling mode starts off fine, but when switching to a stretch scaling mode back to integer scaling, then switching to fullscreen, black bars will then be on the sides of the full screen, even when the aspect is set to keep. Going outside of fullscreen, the black bars will still be present in a minimized window, enveloping most of the screen.

I tried for hours to figure out if something specific was causing the issue in my code, but it doesn't seem to be anything specific. I ran it by a user on the Godot forums, and they said it's most likely an engine issue.

Integer scaling enabled (Maximized) image_2024-03-17_200802649

Integer scaling fullscreen enabled after enabling and disabling stretch + fullscreen, then enabling fullscreen image

After disabling fullscreen image

Steps to reproduce

  1. The project starts fine. If you maximize or press the fullscreen button, the border expands to the appropriate size, and there are no black bars.
  2. Switch to stretch mode by clicking the integer scaling button (Disabled). Stretch mode is now on.
  3. Press the fullscreen button. It works normally. Press it again to disable it.
  4. Press the integer scaling button again (Integer scaling is on). It looks normal at first.
  5. Maximize the window or click fullscreen. There are now black bars around the border, even though the aspect mode is on "keep"
  6. Minimize the window or click fullscreen again. There are now back bars on a normal, minimized window that cover up the whole screen.

Minimal reproduction project (MRP)

This file has only the necessary components. It's a bit over 10mb (10.5) since a texture is needed for the border. https://drive.google.com/file/d/1LeEdl_bnLN5ZJ25cw62o6NsN-042Hbw8/view?usp=sharing

lawnjelly commented 5 months ago

Possibly one for @Calinou , I have no idea how these are supposed to work, so no idea whether this is actually a bug or not. :grin:

Calinou commented 5 months ago

@lawnjelly I don't know either how these are supposed to be rendered correctly. (This API to use a tiling texture in the black area also no longer exists in 4.x to my knowledge.[^1])

[^1]: With the rise of OLED displays which are prone to burn-in, it's debatable whether this API even a good idea in 2024 🙂 Pure black borders are far more suited to those displays, also because of their infinite contrast ratio.

Haskellered commented 5 months ago

I am having the same issue I believe, I'm working on a game but I had to use a custom solution zooming the camera to get scaling to work correctly.

Setting stretch mode to canvas_items, aspect to expand, and scale mode to integer results in black borders.

Calinou commented 5 months ago

I am having the same issue I believe, I'm working on a game but I had to use a custom solution zooming the camera to get scaling to work correctly.

If you don't want black borders, use the disabled stretch mode and set the stretch scale dynamically depending on resolution. This can mimic the canvas_items stretch mode behavior, but without the visible area being reduced when using the integer scaling policy. You can test this in the multiple resolutions demo project.

Haskellered commented 5 months ago

If you don't want black borders, use the disabled stretch mode and set the stretch scale dynamically depending on resolution.

Oh thanks I didn't even think about setting the scale at runtime.

POWERUPT commented 5 months ago

I am having the same issue I believe, I'm working on a game but I had to use a custom solution zooming the camera to get scaling to work correctly.

If you don't want black borders, use the disabled stretch mode and set the stretch scale dynamically depending on resolution. This can mimic the canvas_items stretch mode behavior, but without the visible area being reduced when using the integer scaling policy. You can test this in the multiple resolutions demo project.

This isn't the issue I'm having. I do want stretch mode, but only when it's enabled.

If you look at the code in the sample I gave, I am already setting the stretch mode manually depending on whether integer scaling is on or off: `#Set the screen stretch mode so that stretch is disabled, aspect ratio is kept, the minimum size is 800x600, and the scale is at 1.

if(Global.integerScaling):

get_tree().set_screen_stretch(0, 1, Vector2(800, 600), 1)

..........

else:

Set the screen to have the same stretch settings, except now the stretch mode is set to stretch_mode_2d

get_tree().set_screen_stretch(1, 1, Vector2(800, 600), 1)`

The issue is not that I don't want black bars on my window. The issue is that I am trying to set the stretch mode programmatically, and black bars are persisting despite stretch being ignored.

I'm fairly certain this is a bug with the engine, as there aren't supposed to be black bars when the stretch mode is at 0. I've already run this by a Godot forum member, who also said it's probably a bug.

To be honest, I'm really hoping that it is an issue with my code so that the fix doesn't have to be done in the engine itself, but I've seen no evidence to support this yet.

Just wanted to clarify what the issue is, thanks.