Topic was automatically imported from the old Question2Answer platform.
Asked By
avencherus
Old Version
Published before Godot 3 was released.
I’d like to call some draw commands, but at some later time overlay some others on top. However, the _draw() method gets called through update(), and this seems to clear the buffer.
Is there a way to retain a canvas drawing and continue to draw on top of it without clearing it?
Like drawing on a viewport and creating a texture from it?
If you need to physically accumulate the drawings, I would see two options:
memorize drawings in a list of draw commands, so you can re-draw everything when the node needs to be updated
Use a RenderTexture to accumulate the drawings. However I have no idea how it would work in the 2D engine, I suppose you can have a secondary Viewport with a RenderTexture as target, disable frame clearing, then you would use that texture in the main viewport to display it. (and of course, as I am trying that right now, it lamentably fails… EDIT I found it, getting there. I’ll maybe show an example if I get it to work :D)
Quite right.
I got something running with method 2, but I had to hook a viewport sprite into it to see the results, since my node was put as a child of the viewport and it doesn’t quite show what’s going on.
I’d still like to see what you come up with.
I’m wondering now the best way to set it up though.
avencherus | 2016-10-19 22:18
I came up with this test script.
It’s only a demo, you may want to adapt it to be easier to re-use.
extends Node
var _chalk = null
func _ready():
# Create the viewport
var viewport = Viewport.new()
# Make it so it renders on a texture
viewport.set_as_render_target(true)
# Set the size of it
viewport.set_rect(Rect2(0,0,256,256))
# I tried to set the background color, but none of this worked...
# var world = World.new()
# var env = Environment.new()
# env.set_background(Environment.BG_COLOR)
# env.set_background_param(Environment.BG_PARAM_COLOR, Color(0,0,0))
# world.set_environment(env)
# viewport.set_world(world)
# viewport.set_use_own_world(true)
# Don't clear the frame when it gets updated so it will accumulate drawings
viewport.set_render_target_clear_on_new_frame(false)
add_child(viewport)
# Create a sprite to serve as a "drawer"
_chalk = Sprite.new()
_chalk.set_texture(preload("icon.png"))
_chalk.set_pos(viewport.get_rect().size/2.0)
viewport.add_child(_chalk)
# Use a sprite to display the result texture
var rt = viewport.get_render_target_texture()
var board = Sprite.new()
board.set_texture(rt)
board.set_pos(Vector2(100,100))
add_child(board)
set_process(true)
func _process(delta):
_chalk.rotate(delta)
var s = sin(OS.get_ticks_msec()/1000.0)+1.2
_chalk.set_scale(Vector2(s,s))
Zylann | 2016-10-19 23:51
Very nice, exactly the kind of effects I’m looking into recreating in Godot.