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

GradientTexture1D/2D changed signal emitted before texture updating which causes issue in certain case #102077

Open
beicause opened this issue Jan 27, 2025 · 0 comments · May be fixed by #102078

Comments

@beicause
Copy link
Contributor

beicause commented Jan 27, 2025

Tested versions

Reproducible in 4.4.dev

System information

Linux - Godot 4.4.dev

Issue description

GradientTexture2D/1D emit changed signal before its texture actually updates, which causes issues in certain case that can't update texture by listen its changed signal. The issue was found in #102028.

Steps to reproduce

The issue occurs if you draw gradient texture in a viewport and only update once.

Attach the follow script to a Node2D, assign a GradientTexture2D/GradientTexture1D to the texture property, then the texture display incorrectly and doesn't update after changing its gradient, unless reload the scene. Instead, assigning a NoiseTexture2D to the texture works well.

@tool
extends Node2D
class_name TestNode2D

@export var texture: Texture2D:
	set(value):
		if texture != null:
			texture.changed.disconnect(queue_redraw)
		texture = value
		if texture != null:
			texture.changed.connect(queue_redraw)
		queue_redraw()
@export var bg_color: Color = Color.WHITE:
	set(value):
		bg_color = value
		queue_redraw()

var size: Vector2i = Vector2i(512, 512)
var vp: RID = RenderingServer.viewport_create()
var vp_canvas: RID = RenderingServer.canvas_create()
var vp_ci: RID = RenderingServer.canvas_item_create()
var update_pending: bool = false
var vp_texture: RID


func _init() -> void:
	RenderingServer.viewport_attach_canvas(vp, vp_canvas)
	RenderingServer.canvas_item_set_parent(vp_ci, vp_canvas)
	RenderingServer.viewport_set_update_mode(vp, RenderingServer.VIEWPORT_UPDATE_ALWAYS)
	RenderingServer.viewport_set_size(vp, size.x, size.y)
	vp_texture = RenderingServer.viewport_get_texture(vp)

func _draw() -> void:
	RenderingServer.canvas_item_clear(vp_ci)
	RenderingServer.canvas_item_add_rect(vp_ci, Rect2(Vector2.ZERO, size), bg_color)
	if texture != null:
		RenderingServer.canvas_item_add_texture_rect(vp_ci, Rect2(Vector2.ZERO, size), texture.get_rid())
	RenderingServer.viewport_set_active(vp, true)
	RenderingServer.force_draw(false)
	RenderingServer.viewport_set_active(vp, false)

	RenderingServer.canvas_item_add_texture_rect(get_canvas_item(), Rect2(Vector2.ZERO, size), vp_texture)

Minimal reproduction project (MRP)

N/A

@beicause beicause changed the title GradientTexture1D/2D changed signal is unreliable in certain case GradientTexture1D/2D changed signal emitted before texture updating which causes issue in certain case Jan 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants