extends Control var viewport: Viewport var render_queue: Array # of PoolByteArrays var result_queue: Array # of PoolByteArrays var current_image: Image var current_tex: ImageTexture # Needed to prevent GC before draw var waiting_for_viewport: bool var done_first_draw: bool func _ready() -> void: self.viewport = get_parent() self.render_queue = [] self.result_queue = [] self.waiting_for_viewport = false self.done_first_draw = false self.current_image = Image.new() self.current_tex = ImageTexture.new() func _process(_delta) -> void: update() func _draw() -> void: # Seems like the first one always fails if not self.done_first_draw: self.done_first_draw = true return if self.waiting_for_viewport: # Another node later in the draw sequence can call this within the same frame, # otherwise, this picks it up the following frame get_result() if not self.render_queue: return # Draw the next ImageTexture var data: PoolByteArray = self.render_queue.pop_front() print(data.subarray(0, 15)) self.current_image.create_from_data(4096, 4096, false, Image.FORMAT_LA8, data) self.current_tex.create_from_image(self.current_image, Texture.FLAG_FILTER) self.material.set_shader_param('tex', self.current_tex) draw_texture(self.current_tex, Vector2.ZERO) self.waiting_for_viewport = true # Grab the result next draw func get_result() -> void: var result_texture := self.viewport.get_texture() var result_image := result_texture.get_data() var result_bytes := result_image.get_data() # Debugging: compare a sequence of all the possible 16bit integers print_debug('result_image format is %d and has size'%result_image.get_format(), result_image.get_size(), result_bytes.subarray(0, 11)) test_readback(result_bytes) self.result_queue.append(result_bytes) self.waiting_for_viewport = false func test_readback(result_bytes: PoolByteArray): # Debugging: compare a sequence of all the possible 16bit integers var buff := StreamPeerBuffer.new() buff.set_data_array(result_bytes) var tex_readback = 0 var uv_readback = 0 for i in 0x1000: tex_readback = buff.get_u16() uv_readback = buff.get_u16() if tex_readback != i: print('tex readback %d (0x%04x) was instead %d (0x%04x)'%[i, i, tex_readback, tex_readback]) if uv_readback != i: print('uv readback %d (0x%04x) was instead %d (0x%04x)'%[i, i, uv_readback, uv_readback])