Skip to content

Instantly share code, notes, and snippets.

@jshorty
Created April 5, 2020 08:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jshorty/4090ba064ca0d3634d040e7a70c4833a to your computer and use it in GitHub Desktop.
Save jshorty/4090ba064ca0d3634d040e7a70c4833a to your computer and use it in GitHub Desktop.
Sprite that "snapshots" a Polygon2D for rendering performance
extends Sprite
# This dictates the size of the viewport used for the "snapshot".
export var source_image_size : Vector2
export var polygon : PoolVector2Array
func _ready():
var viewport_container = ViewportContainer.new()
viewport_container.set_size(source_image_size)
add_child(viewport_container)
# Additional optimizations can be made on the viewport's properties,
# depending on the use case.
var viewport = Viewport.new()
viewport.set_size(source_image_size)
viewport_container.add_child(viewport)
var polygon_2d = Polygon2D.new()
polygon_2d.set_polygon(polygon)
viewport.add_child(polygon_2d)
# Need to yield here when "snapshotting" the first frame of a scene.
# As described in issue https://github.com/godotengine/godot/issues/19239
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
var image = viewport.get_texture().get_data()
image.flip_y()
var texture = ImageTexture.new()
texture.create_from_image(image)
set_texture(texture)
# Don't need any of this any longer!
viewport_container.queue_free()
@jshorty
Copy link
Author

jshorty commented Apr 17, 2020

Note that if the instance is freed while yielding, this will cause errors. An option to avoid this is to overload the definition of queue_free() and poll an instance variable, since the yield is just for a couple frames (not entirely sure how well this scales):

var is_yielding = false

func queue_free():
  if !is_yielding:
    .queue_free()
  else:
    queue_free()

func _ready():
  ...
  is_yielding = true
  yield(get_tree(), "idle_frame")
  yield(get_tree(), "idle_frame")
  is_yielding = false
  ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment