Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow viewport stretch without shrink #76304

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/classes/SubViewport.xml
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@
</member>
<member name="size" type="Vector2i" setter="set_size" getter="get_size" default="Vector2i(512, 512)">
The width and height of the sub-viewport. Must be set to a value greater than or equal to 2 pixels on both dimensions. Otherwise, nothing will be displayed.
[b]Note:[/b] If the parent node is a [SubViewportContainer] and its [member SubViewportContainer.stretch] is [code]true[/code], the viewport size cannot be changed manually.
[b]Note:[/b] If the parent node is a [SubViewportContainer] and its [member SubViewportContainer.stretch] is [code]true[/code] and its [member SubViewportContainer.stretch_shrink] is not [code]0[/code], the viewport size cannot be changed manually.
</member>
<member name="size_2d_override" type="Vector2i" setter="set_size_2d_override" getter="get_size_2d_override" default="Vector2i(0, 0)">
The 2D size override of the sub-viewport. If either the width or height is [code]0[/code], the override is disabled.
7 changes: 4 additions & 3 deletions doc/classes/SubViewportContainer.xml
Original file line number Diff line number Diff line change
@@ -12,13 +12,14 @@
</tutorials>
<members>
<member name="stretch" type="bool" setter="set_stretch" getter="is_stretch_enabled" default="false">
If [code]true[/code], the sub-viewport will be automatically resized to the control's size.
[b]Note:[/b] If [code]true[/code], this will prohibit changing [member SubViewport.size] of its children manually.
If [code]true[/code] and [member stretch_shrink] is not [code]0[/code], the sub-viewport will be automatically resized to the control's size.
[b]Note:[/b] If [code]true[/code] and [member stretch_shrink] is not [code]0[/code], this will prohibit changing [member SubViewport.size] of its children manually.
</member>
<member name="stretch_shrink" type="int" setter="set_stretch_shrink" getter="get_stretch_shrink" default="1">
Divides the sub-viewport's effective resolution by this value while preserving its scale. This can be used to speed up rendering.
If not [code]0[/code], divides the sub-viewport's effective resolution by this value while preserving its scale. This can be used to speed up rendering.
For example, a 1280×720 sub-viewport with [member stretch_shrink] set to [code]2[/code] will be rendered at 640×360 while occupying the same size in the container.
[b]Note:[/b] [member stretch] must be [code]true[/code] for this property to work.
[b]Note:[/b] If [code]0[/code], sub-viewport texture is stretched across the container regardless of its size or aspect ratio.
</member>
</members>
</class>
20 changes: 10 additions & 10 deletions scene/gui/subviewport_container.cpp
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@ bool SubViewportContainer::is_stretch_enabled() const {
}

void SubViewportContainer::set_stretch_shrink(int p_shrink) {
ERR_FAIL_COND(p_shrink < 1);
ERR_FAIL_COND(p_shrink < 0);
if (shrink == p_shrink) {
return;
}
@@ -81,7 +81,7 @@ void SubViewportContainer::set_stretch_shrink(int p_shrink) {
}

void SubViewportContainer::recalc_force_viewport_sizes() {
if (!stretch) {
if (!stretch || shrink == 0) {
return;
}

@@ -192,13 +192,7 @@ void SubViewportContainer::gui_input(const Ref<InputEvent> &p_event) {
return;
}

if (stretch && shrink > 1) {
Transform2D xform;
xform.scale(Vector2(1, 1) / shrink);
_send_event_to_viewports(p_event->xformed_by(xform));
} else {
_send_event_to_viewports(p_event);
}
_send_event_to_viewports(p_event);
}

void SubViewportContainer::_send_event_to_viewports(const Ref<InputEvent> &p_event) {
@@ -208,7 +202,13 @@ void SubViewportContainer::_send_event_to_viewports(const Ref<InputEvent> &p_eve
continue;
}

c->push_input(p_event);
if (stretch && shrink != 1) {
Transform2D xform;
xform.scale(Vector2(c->get_size()) / get_size());
c->push_input(p_event->xformed_by(xform));
} else {
c->push_input(p_event);
}
}
}

12 changes: 6 additions & 6 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
@@ -4320,7 +4320,7 @@ void SubViewport::set_size_force(const Size2i &p_size) {

void SubViewport::_internal_set_size(const Size2i &p_size, bool p_force) {
SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
if (!p_force && c && c->is_stretch_enabled()) {
if (!p_force && c && c->is_stretch_enabled() && c->get_stretch_shrink() != 0) {
#ifdef DEBUG_ENABLED
WARN_PRINT("Can't change the size of a `SubViewport` with a `SubViewportContainer` parent that has `stretch` enabled. Set `SubViewportContainer.stretch` to `false` to allow changing the size manually.");
#endif // DEBUG_ENABLED
@@ -4385,8 +4385,8 @@ Transform2D SubViewport::get_screen_transform_internal(bool p_absolute_position)
Transform2D container_transform;
SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
if (c) {
if (c->is_stretch_enabled()) {
container_transform.scale(Vector2(c->get_stretch_shrink(), c->get_stretch_shrink()));
if (c->is_stretch_enabled() && c->get_stretch_shrink() != 1) {
container_transform.scale(c->get_size() / Vector2(get_size()));
}
container_transform = c->get_viewport()->get_screen_transform_internal(p_absolute_position) * c->get_global_transform_with_canvas() * container_transform;
} else {
@@ -4404,8 +4404,8 @@ Transform2D SubViewport::get_popup_base_transform() const {
return get_final_transform();
}
Transform2D container_transform;
if (c->is_stretch_enabled()) {
container_transform.scale(Vector2(c->get_stretch_shrink(), c->get_stretch_shrink()));
if (c->is_stretch_enabled() && c->get_stretch_shrink() != 1) {
container_transform.scale(c->get_size() / Vector2(get_size()));
}
return c->get_screen_transform() * container_transform * get_final_transform();
}
@@ -4464,7 +4464,7 @@ void SubViewport::_bind_methods() {
void SubViewport::_validate_property(PropertyInfo &p_property) const {
if (p_property.name == "size") {
SubViewportContainer *parent_svc = Object::cast_to<SubViewportContainer>(get_parent());
if (parent_svc && parent_svc->is_stretch_enabled()) {
if (parent_svc && parent_svc->is_stretch_enabled() && parent_svc->get_stretch_shrink() != 0) {
p_property.usage = PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY;
} else {
p_property.usage = PROPERTY_USAGE_DEFAULT;