Godot-ルールなしで描画

エンジンが終わりのないアイデアの流れを単に制限することが時々起こります。だから、一度私はどこからでも、何でも、どこからでも描きたいと思っていました。これが議論されることです。





まず、このような些細な作業を想像してみましょう。マウスをクリックして、たとえばキーを押すなど、ユーザーが指定するプリミティブを描画する必要があります。単純に聞こえますが、Godotでは頭痛の種になる可能性があります。





, : Godot _draw



CanvasItem



, .. , , , _process



. , , _draw



, . . , ? ? ? .





– «» . Godot – , - , . godot API , – VisualServer



. ( ) Godot. , , VisualServer



.





CanvasItem



- , , ? , . RID



(Resource ID), World2D



. CanvasItem



get_canvas_item()



, , _draw



. , , :





: Controller



Drawer



.





"" , . Controller



:





extends Node2D

onready var drawer = $"../Drawer"

var counter = 0

func custom_draw_line(start, goal, color, width=1.0, antialising=false):
	VisualServer.canvas_item_add_line(drawer.get_canvas_item(), start, goal, color, width, antialising)

func _process(delta):
	if Input.is_action_just_pressed("mouse_left"):
		counter += 2
		custom_draw_line(Vector2(100, 100)+Vector2(counter, counter), Vector2(300, 150)+Vector2(counter, counter), Color.green)
      
      



custom_draw_line(...)



, VisualServer



canvas_item_add_line(...)



, Drawer



. , Controller



, , , .





, . , , . ? Godot, . , :





void CanvasItem::_update_callback() {
	if (!is_inside_tree()) {
		pending_update = false;
		return;
	}

	RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item());
	//todo updating = true - only allow drawing here
	if (is_visible_in_tree()) { //todo optimize this!!
		if (first_draw) {
			notification(NOTIFICATION_VISIBILITY_CHANGED);
			first_draw = false;
		}
		drawing = true;
		current_item_drawn = this;
		notification(NOTIFICATION_DRAW);
		emit_signal(SceneStringNames::get_singleton()->draw);
		if (get_script_instance()) {
			get_script_instance()->call(SceneStringNames::get_singleton()->_draw);
		}
		current_item_drawn = nullptr;
		drawing = false;
	}
	//todo updating = false
	pending_update = false; // don't change to false until finished drawing (avoid recursive update)
}
      
      



7:





RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item())
      
      



, . , .. , . , Drawer



. VisualServer.canvas_item_create()



, , , , World2D.canvas



( "" ) .. Drawer



, . VisualServer



VisualServer.canvas_item_set_parent(item, parent)



. : , . , , . :VisualServer.canvas_item_clear(surface)



. :





extends Node2D

onready var drawer = $"../Drawer"

var counter = 0

var surface

func _ready():
	surface = VisualServer.canvas_item_create()
	VisualServer.canvas_item_set_parent(surface, drawer.get_canvas_item())

func custom_draw_line(start, goal, color, width=1.0, antialising=false):
	VisualServer.canvas_item_add_line(surface, start, goal, color, width, antialising)

func _process(delta):
	if Input.is_action_just_pressed("mouse_left"):
		counter += 2
		custom_draw_line(Vector2(100, 100)+Vector2(counter, counter), Vector2(300, 150)+Vector2(counter, counter), Color.green)
	elif Input.is_action_just_pressed("mouse_right"):
		VisualServer.canvas_item_clear(surface)
		counter = 0
      
      



, . , Drawer



, .





, , . , CanvasItem



, CanvasItem



( ):





void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width) {
	ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");

	RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width);
}
      
      



4, VisualServer



, , .





? , .. - , . , Resource



, . , , .





, , . , " ". , , ( ), , " ", .





- , . , .





, .. .





, , . , , _draw



CanvasItem



. , 3D , , , .





. : , Godot . , !








All Articles