#(unsolved) How to render primitives/draw_* to a texture ?

61 messages · Page 1 of 1 (latest)

marsh vault
#

Hi, i'm making a 2D game with 100% vectorial graphics to accommodate to all screen resolutions but because they take a lot of time to render them every frames i wanted to render then to a texture, save them in memory then display the texture instead of the vectors but i still can't find how to render a draw method on an empty image file

#

Also i'm on Godot 4.4d7 if it's useful 👍

azure solstice
marsh vault
#

but thank you i didn't know that you could load SVG, it might be useful for me for other games

azure solstice
marsh vault
azure solstice
marsh vault
#

i can wait 0, 1 or 10 frames but i still get a pitch black image instead of a transparent one with the object draw on it

#

what do i do is when i have 6 objects to render, i do an array of 6 dictionaries (subviewport; node; path) and a timer

the first pass (timer = 0),
spawn a SubViewport node as the subviewport key's value,
then spawn a node2D node as the node key's value,
set the (relative) path name as the path key's value,
set the node2D node as the child of the SubViewport node,
then render on the node2D

after that i raise the timer by one, wait another frame then

the second pass (timer = 1),
get the texture, image, then save_png of each viewports
then delete all node2D and subviewport nodes

azure solstice
marsh vault
marsh vault
#

(unsolved)How to render primitives/draw_* to a texture ?

#

(unsolved) How to render primitives/draw_* to a texture ?

azure solstice
marsh vault
azure solstice
marsh vault
# azure solstice hm, could you show your code?

ok ! i'm essencially doing this (it's a simplified version, in the normal version i'm rendering 17 different notes with a pipeline made for that and it's almost 1000 lines long)
`
var pass = 0
var size: float = 88.
var subv := SubViewport.new()
var nd2d := Node2D.new()

func _ready():
subv.add_child(nd2d)
subv.set_disable_3d(true)
subv.set_transparent_background(true)
subv.set_size(Vector2i(size, size))

func _process():
queue_redraw()

func _draw():
if pass == 0:
draw_note_A(nd2d, Vector2(size, size) / 2., size)
if pass == 1:
subv.get_texture().get_image().save_png("a_note.png")

func draw_note_A(node:Node2D, position:=Vector2(0, 0), size:= 1.):
node.draw_circle(position, size, Color.WHITE, true, -1.0, gl.win.aa)
node.draw_circle(position, size * 0.9375, Color.WHITE, false, size * .125, gl.win.aa)
var sVze = Vector2(size, size) * 56./128.
var sAze = Vector2(size,-size) * 56./128.
node.draw_line(position-sVze, position+sVze, Color.WHITE, size/(5.7)*sqrt(2), gl.win.aa)
node.draw_line(position-sAze, position+sAze, Color.WHITE, size/(5.7)*sqrt(2), gl.win.aa)`

It just doesn't draw to the viewport and i have no idea why

iron basin
#

You're never calling your draw method?
Also subv seems to never be added to the tree.

azure solstice
#

oh right isn't is _draw()?

azure solstice
#

draw() is the signal that gets emitted on a redraw

marsh vault
azure solstice
#

oh my bad

marsh vault
azure solstice
#

also if you want to draw the node this script is attached to, it's not ideal to create the viewport here, as it needs to be a child of it.

#

also also, you can't draw on a different node inside _draw() as far as i know.

marsh vault
#

well, i have my main control node with nothing else manually added in the scenetree, and i do everything by code (i come from game maker studio sorry if i don't get the node system very well)

iron basin
azure solstice
marsh vault
#

But i've been making games for quite some time, this is just the node system that i don't really get

azure solstice
marsh vault
azure solstice
marsh vault
azure solstice
#

although reparent is more intended for changing a parent while keeping the position, so i would suggest sticking to remove/add child.

iron basin
azure solstice
marsh vault
#

but in that case i should use a CanvasItem alone and draw on it instead of a SubViewport and a Node2D ?

iron basin
# azure solstice oh didn't know that's possible. good to know!

Technically you could use RenderingServer methods to add draw commands for any canvas item from anywhere. The thing is before NOTIFICATION_DRAW, draw signal, and _draw method such drawing commands are cleared, so you'd need to be careful about synchronizing it properly. CanvasItem.draw_... methods are restricted to be called only within this specific chunk because of that. https://github.com/godotengine/godot/blob/da4f9339ea7f614f5965e6a6b918b8c8285f2e1d/scene/main/canvas_item.cpp#L139-L149

iron basin
marsh vault
marsh vault
#

i'm going to try with a mock-up function, maybe ".bind" can't handle functions in dictionaries

iron basin
marsh vault
iron basin
iron basin
marsh vault
#

then how to i pass arguments to my function ? it's the only way i've found it pass arguments to a function in a dictionary

iron basin
marsh vault
marsh vault
iron basin
marsh vault
#

i think i'll do an empty project and try doing a basic subviewport off-screen rendering system then if i manage to get it to work i'll back port it into the main game