godotengine / godot

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

Resizing SubViewportContainer with stretch enabled changes render resolution of child SubViewport #62041

Open lapspider45 opened 2 years ago

lapspider45 commented 2 years ago

Godot version

v4.0.alpha9.official.fc18891db

System information

Linux

Issue description

When resizing a SubViewportContainer with stretch enabled, the size of the child SubViewport is changed to the size of the container. What this does is to undo all the "stretching", since the resolution of the viewport is now the same as the displayed resolution. This is unexpected of a property named stretch, if this were intentional a more fitting name would be auto_resize. This problem was present in Godot 3 as well, but it wasn't hard to write something like this to preserve the size of the viewport:

func _on_Viewport_size_changed(): # connected to signal "resized" in Viewport
    if size == correct_size:
        return
    size = correct_size

But in newer alpha versions Godot 4, this workaround stopped working consistently, especially inside nested containers. So this is what I resorted to:

func workaround_hack():
    for i in 3: # with one iteration, this fails up to 50% of the time 
        await get_tree().process_frame
        $SubViewport.size = correct_size

This is very inelegant, and I don't see how SubViewportContainer messing with viewport sizes would be intended behavior in the first place.

Steps to reproduce

Minimal reproduction project

MRP_SubViewportContainer.zip

  1. Open main.tscn in editor
  2. Resize the root Control
  3. Notice both the viewport and icon.png changing size
Calinou commented 2 years ago

@lapspider45 Please upload a minimal reproduction project to make this easier to troubleshoot.

lapspider45 commented 2 years ago

Done.

Rindbee commented 2 years ago

In my opinion, SubViewport seems to be a pipe. Render a 2D/3D scene to a 2D texture. And SubViewportContainer is an adapter that converts SubViewport to Control.

In this way, the size property is the sampling resolution of the source, and size_2d_override is the resolution of the render target. Currently, size_2d_override only seems to work in get_visible_rect. size does the work that size_2d_override should.

This is just my guess, maybe I'm wrong.

TisFoolish commented 1 year ago

I can confirm that this still happens with Beta 10

TisFoolish commented 1 year ago

The workarounds also don't work anymore. The data of the subviewports size property properly changes, but the SVPs don't properly fill the viewport

DieStockEnte commented 1 year ago

Still happens in Godot v4.1.1 stable. As a workaround I set in the SubViewportContainer the "stretch_shrink" property to 2, to half the render resolution of the child SubViewport. This isn't ideal, because my display resolution is 1280x720, so the SubViewport will be 640x360 and I need another resolution...

djpeach commented 1 year ago

I can't reproduce this. Downloaded the minimal project, resized the subviewportContainer, and the icon does not stretch.

sbc stretch demo

lapspider45 commented 1 year ago

@djpeach it looks to me like you are reproducing the issue. Right now there is no sensible way to scale a SubViewport, since SubViewportContainer enforces a 1:1 pixel ratio in all cases

Stalker2106x commented 10 months ago

I am actually reproducing that as well on 4.1.3 A subviewport cannot have resolution stretch as a window can get.

Still happens in Godot v4.1.1 stable. As a workaround I set in the SubViewportContainer the "stretch_shrink" property to 2, to half the render resolution of the child SubViewport. This isn't ideal, because my display resolution is 1280x720, so the SubViewport will be 640x360 and I need another resolution...

This indeed resize the actual Subviewport from origin resolution, but then requires unticking scale parameter to apply. And this workaround being integer based, any resolution between 1 and 2 are unavailable.

EDIT: Setting the original resolution on Subviewport "size_2d_override", and target resolution on its "size" makes the viewport actually respect its resolution and scale to. Which works for me 🎉

Rindbee commented 10 months ago

EDIT: Setting the original resolution on Subviewport "size_2d_override", and target resolution on its "size" makes the viewport actually respect its resolution and scale to. Which works for me 🎉

Yes, it works. It might be worth detailing in the documentation the correct usage of these related properties.

Or when stretch of SubViewportContainer is checked, the current size of SubViewport is automatically used to set size_2d_override.