Skip to content

Commit

Permalink
Add a Viewport method to get automatically computed 2D scale factor
Browse files Browse the repository at this point in the history
`Viewport.get_stretch_transform()` returns the automatically computed
2D stretch transform. Combined with `Transform2D.get_scale()`, this is
useful when using the `canvas_items` stretch mode in a project.

There are many situations where knowing this factor is useful:

- Divide Camera2D zoom to keep the size of the 2D game world identical
  regardless of the 2D scale factor (so that UI elements can still be scaled).
- Make certain controls always drawn at 1:1 scale
  (e.g. for the crosshair in a FPS). This is done by dividing the Control
  node's scale by the scale factor.
  • Loading branch information
Calinou committed Oct 2, 2024
1 parent f4af820 commit 6f3203c
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 1 deletion.
7 changes: 7 additions & 0 deletions doc/classes/Viewport.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@
Returns the transform from the Viewport's coordinates to the screen coordinates of the containing window manager window.
</description>
</method>
<method name="get_stretch_transform" qualifiers="const">
<return type="Transform2D" />
<description>
Returns the automatically computed 2D stretch transform, taking the [Viewport]'s stretch settings into account. The final value is multiplied by [member Window.content_scale_factor]. Using [method Transform2D.get_scale] on the returned value, this can be used to compensate for scaling when zooming a [Camera2D] node, or to scale down a [TextureRect] to be pixel-perfect regardless of the automatically computed scale factor.
[b]Note:[/b] Due to how pixel scaling works, the transform's X scale value may differ slightly from the Y scale, even when [member Window.content_scale_aspect] is set to a mode that preserves pixel aspect ratio. If [member Window.content_scale_aspect] is [constant Window.CONTENT_SCALE_ASPECT_IGNORE], the X value may differ [i]significantly[/i] from Y due to differences between the original aspect ratio and the window aspect ratio.
</description>
</method>
<method name="get_texture" qualifiers="const">
<return type="ViewportTexture" />
<description>
Expand Down
2 changes: 1 addition & 1 deletion doc/classes/Window.xml
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@
Specifies how the content's aspect behaves when the [Window] is resized. The base aspect is determined by [member content_scale_size].
</member>
<member name="content_scale_factor" type="float" setter="set_content_scale_factor" getter="get_content_scale_factor" default="1.0">
Specifies the base scale of [Window]'s content when its [member size] is equal to [member content_scale_size].
Specifies the base scale of [Window]'s content when its [member size] is equal to [member content_scale_size]. See also [method Viewport.get_stretch_transform].
</member>
<member name="content_scale_mode" type="int" setter="set_content_scale_mode" getter="get_content_scale_mode" enum="Window.ContentScaleMode" default="0">
Specifies how the content is scaled when the [Window] is resized.
Expand Down
5 changes: 5 additions & 0 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,10 @@ Ref<World2D> Viewport::get_world_2d() const {
return world_2d;
}

Transform2D Viewport::get_stretch_transform() const {
return stretch_transform;
}

Transform2D Viewport::get_final_transform() const {
ERR_READ_THREAD_GUARD_V(Transform2D());
return stretch_transform * global_canvas_transform;
Expand Down Expand Up @@ -4553,6 +4557,7 @@ void Viewport::_bind_methods() {

ClassDB::bind_method(D_METHOD("set_global_canvas_transform", "xform"), &Viewport::set_global_canvas_transform);
ClassDB::bind_method(D_METHOD("get_global_canvas_transform"), &Viewport::get_global_canvas_transform);
ClassDB::bind_method(D_METHOD("get_stretch_transform"), &Viewport::get_stretch_transform);
ClassDB::bind_method(D_METHOD("get_final_transform"), &Viewport::get_final_transform);
ClassDB::bind_method(D_METHOD("get_screen_transform"), &Viewport::get_screen_transform);

Expand Down
1 change: 1 addition & 0 deletions scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ class Viewport : public Node {
void set_global_canvas_transform(const Transform2D &p_transform);
Transform2D get_global_canvas_transform() const;

Transform2D get_stretch_transform() const;
virtual Transform2D get_final_transform() const;

void gui_set_root_order_dirty();
Expand Down

0 comments on commit 6f3203c

Please sign in to comment.