From 840796ef37780c21d09b1ea42b631e5c322058d7 Mon Sep 17 00:00:00 2001 From: GsLogimaker Date: Wed, 27 Nov 2024 11:11:37 -0600 Subject: [PATCH 1/4] Refactor 2D rendering entities --- cpp/src/world.cpp | 17 ++++++ cpp/src/world.h | 1 - gd/modules.gd | 17 ++++++ gd/rendering/2d/2d.gd | 9 ++++ gd/rendering/2d/canvas_item.gd | 33 ++++++++++++ gd/rendering/2d/position2d.gd | 13 +++++ gd/rendering/2d/rotation2d.gd | 9 ++++ gd/rendering/2d/scale2d.gd | 9 ++++ gd/rendering/2d/systems.gd | 97 ++++++++++++++++++++++++++++++++++ gd/rendering/2d/texture2d.gd | 17 ++++++ gd/rendering/rendering.gd | 3 ++ gd/std/2d/canvas_item.gd | 58 -------------------- gd/std/2d/position2d.gd | 29 ---------- gd/std/2d/rotation2d.gd | 25 --------- gd/std/2d/scale2d.gd | 26 --------- gd/std/2d/texture2d.gd | 27 ---------- gd/std/rendering/render.gd | 7 --- gd/std/std.gd | 14 ----- plugin.gd | 11 +++- 19 files changed, 234 insertions(+), 188 deletions(-) create mode 100644 gd/modules.gd create mode 100644 gd/rendering/2d/2d.gd create mode 100644 gd/rendering/2d/canvas_item.gd create mode 100644 gd/rendering/2d/position2d.gd create mode 100644 gd/rendering/2d/rotation2d.gd create mode 100644 gd/rendering/2d/scale2d.gd create mode 100644 gd/rendering/2d/systems.gd create mode 100644 gd/rendering/2d/texture2d.gd create mode 100644 gd/rendering/rendering.gd delete mode 100644 gd/std/2d/canvas_item.gd delete mode 100644 gd/std/2d/position2d.gd delete mode 100644 gd/std/2d/rotation2d.gd delete mode 100644 gd/std/2d/scale2d.gd delete mode 100644 gd/std/2d/texture2d.gd delete mode 100644 gd/std/rendering/render.gd delete mode 100644 gd/std/std.gd diff --git a/cpp/src/world.cpp b/cpp/src/world.cpp index 90c6dbc..daa1ce9 100644 --- a/cpp/src/world.cpp +++ b/cpp/src/world.cpp @@ -2,6 +2,7 @@ #include "world.h" #include "entity.h" #include "component_builder.h" +#include "godot_cpp/classes/resource.hpp" #include "godot_cpp/classes/script.hpp" #include "godot_cpp/classes/text_server_manager.hpp" #include "godot_cpp/classes/wrapped.hpp" @@ -488,6 +489,18 @@ GFWorld::GFWorld() { #undef DEFINE_GD_COMPONENT #undef DEFINE_GD_COMPONENT_WITH_HOOKS + + // Register modules from scripts + Engine* engine = Engine::get_singleton(); + if (engine->has_singleton("_glecs_modules")) { + ecs_entity_t prev_scope = ecs_get_scope(raw()); + ecs_set_scope(raw(), glecs); + + Object* glecs_modules = engine->get_singleton("_glecs_modules"); + glecs_modules->call("register_modules", this); + + ecs_set_scope(raw(), prev_scope); + } } GFWorld::~GFWorld() { @@ -583,6 +596,10 @@ Ref GFWorld::lookup(String path) { false ); + if (!ecs_is_alive(raw(), id)) { + return nullptr; + } + return GFEntity::from_id(id, this); } diff --git a/cpp/src/world.h b/cpp/src/world.h index ae257cd..5594eb4 100644 --- a/cpp/src/world.h +++ b/cpp/src/world.h @@ -2,7 +2,6 @@ #ifndef WORLD_H #define WORLD_H - #include "godot_cpp/classes/script.hpp" #include "godot_cpp/variant/dictionary.hpp" #include diff --git a/gd/modules.gd b/gd/modules.gd new file mode 100644 index 0000000..690cc33 --- /dev/null +++ b/gd/modules.gd @@ -0,0 +1,17 @@ + +## Registers default Glecs modules with new worlds. + +@tool +class_name _GlecsModules extends Node + +const MODULES:= [ + preload("./rendering/rendering.gd"), +] + +static var _register_self_singleton = (func(): + Engine.register_singleton("_glecs_modules", _GlecsModules) + ).call() + +static func register_modules(w:GFWorld) -> void: + for module in MODULES: + w.register_script(module) diff --git a/gd/rendering/2d/2d.gd b/gd/rendering/2d/2d.gd new file mode 100644 index 0000000..c17d662 --- /dev/null +++ b/gd/rendering/2d/2d.gd @@ -0,0 +1,9 @@ + +extends GFModule + +const _CANVAS_ITEM:= preload("./canvas_item.gd") +const _POSITION_2D:= preload("./position2d.gd") +const _ROTATION_2D:= preload("./rotation2d.gd") +const _SCALE_2D:= preload("./scale2d.gd") +const _TEXTURE_2D:= preload("./texture2d.gd") +const _SYSTEMS:= preload("./systems.gd") diff --git a/gd/rendering/2d/canvas_item.gd b/gd/rendering/2d/canvas_item.gd new file mode 100644 index 0000000..c03f24c --- /dev/null +++ b/gd/rendering/2d/canvas_item.gd @@ -0,0 +1,33 @@ + +## A component that gives entities functionality of a CanvasItem. + +class_name GFCanvasItem extends GFComponent + +func get_rid() -> RID: return getm(&"rid") +func set_rid(v:RID) -> void: setm(&"rid", v) +func _build(b: GFComponentBuilder) -> void: + b.add_member("rid", TYPE_RID) + + +## Sets the parent canvas item of this canvas item by its [RID]. +func set_parent_canvas_item(rid:RID) -> void: + RenderingServer.canvas_item_set_parent( + get_rid(), + rid + ) + + +## Updates the transform of this canvas item via the three 2D spatial +## components. +func update_transform_c( + pos:GFPosition2D, + rot:GFRotation2D, + scale:GFScale2D, +) -> void: + var loc:Vector2 = pos.get_vec() if pos else Vector2() + var angle:float = rot.get_angle() if rot else 0.0 + var size:Vector2 = scale.get_scale() if scale else Vector2.ONE + RenderingServer.canvas_item_set_transform( + get_rid(), + Transform2D(angle, size, 0, loc) + ) diff --git a/gd/rendering/2d/position2d.gd b/gd/rendering/2d/position2d.gd new file mode 100644 index 0000000..b721e18 --- /dev/null +++ b/gd/rendering/2d/position2d.gd @@ -0,0 +1,13 @@ + +## A component that represents a position in 2D space. + +class_name GFPosition2D extends GFComponent + +func get_vec() -> Vector2: return getm(&"vec") +func set_vec(v:Vector2) -> void: return setm(&"vec", v) +func get_x() -> float: return getm(&"vec").x +func set_x(v:float) -> void: return setm(&"vec", Vector2(v, get_y())) +func get_y() -> float: return getm(&"vec").y +func set_y(v:float) -> void: return setm(&"vec", Vector2(get_x(), v)) +func _build(b: GFComponentBuilder) -> void: + b.add_member("vec", TYPE_VECTOR2) diff --git a/gd/rendering/2d/rotation2d.gd b/gd/rendering/2d/rotation2d.gd new file mode 100644 index 0000000..07b9c88 --- /dev/null +++ b/gd/rendering/2d/rotation2d.gd @@ -0,0 +1,9 @@ + +## A component that represents a rotaition in 2D space. + +class_name GFRotation2D extends GFComponent + +func get_angle() -> float: return getm(&"angle") +func set_angle(v:float) -> void: return setm(&"angle", v) +func _build(b: GFComponentBuilder) -> void: + b.add_member("angle", TYPE_FLOAT) diff --git a/gd/rendering/2d/scale2d.gd b/gd/rendering/2d/scale2d.gd new file mode 100644 index 0000000..caae664 --- /dev/null +++ b/gd/rendering/2d/scale2d.gd @@ -0,0 +1,9 @@ + +## A component that represents scale in 2D space. + +class_name GFScale2D extends GFComponent + +func get_scale() -> Vector2: return getm(&"scale") +func set_scale(v:Vector2) -> void: return setm(&"scale", v) +func _build(b: GFComponentBuilder) -> void: + b.add_member("scale", TYPE_VECTOR2) diff --git a/gd/rendering/2d/systems.gd b/gd/rendering/2d/systems.gd new file mode 100644 index 0000000..667568d --- /dev/null +++ b/gd/rendering/2d/systems.gd @@ -0,0 +1,97 @@ + +## A component that gives entities functionality of a CanvasItem. + +extends GFModule + +func _register(w:GFWorld): + #region GFCanvasItem + # On add GFCanvasItem + w.observer_builder("/root/flecs/core/OnAdd") \ + .with(GFCanvasItem) \ + .for_each(func(item:GFCanvasItem): + item.set_rid(RenderingServer.canvas_item_create()) + # Set parent to root + var root_canvas_item:CanvasItem = Engine.get_main_loop() \ + .current_scene + item.set_parent_canvas_item(root_canvas_item.get_canvas_item()) + ) + + # On set GFCanvasItem + w.observer_builder("/root/flecs/core/OnSet") \ + .with(GFCanvasItem) \ + .for_each(func(item:GFCanvasItem): + item.set_parent_canvas_item( + Engine.get_main_loop().current_scene.get_canvas_item() + ) + ) + + # On remove GFCanvasItem + w.observer_builder("/root/flecs/core/OnRemove") \ + .with(GFCanvasItem) \ + .for_each(func(item:GFCanvasItem): + RenderingServer.free_rid(item.get_rid()) + ) + #endregion + + #region GFPosition2D + # On GFPosition2D set, update visual transform of CanvasItemC + w.observer_builder("/root/flecs/core/OnSet") \ + .with(GFCanvasItem).access_filter() \ + .with(GFPosition2D) \ + .maybe_with(GFRotation2D) \ + .maybe_with(GFScale2D) \ + .for_each(func( + item:GFCanvasItem, + pos:GFPosition2D, + rot:GFRotation2D, + scl:GFScale2D, + ): + item.update_transform_c(pos, rot, scl) + ) + #endregion + + #region GFRotation2D + # On GFPosition2D set, update visual transform of GFCanvasItem + w.observer_builder("/root/flecs/core/OnSet") \ + .with(GFCanvasItem).access_filter() \ + .with(GFRotation2D) \ + .maybe_with(GFPosition2D) \ + .maybe_with(GFScale2D) \ + .for_each(func( + item:GFCanvasItem, + rot:GFRotation2D, + pos:GFPosition2D, + scl:GFScale2D, + ): + item.update_transform_c(pos, rot, scl) + ) + #endregion + + #region GFScale2D + # On GFScale2D set, update visual transform of GFCanvasItem + w.observer_builder("/root/flecs/core/OnSet") \ + .with(GFCanvasItem).access_filter() \ + .with(GFScale2D) \ + .maybe_with(GFPosition2D) \ + .maybe_with(GFRotation2D) \ + .for_each(func( + item:GFCanvasItem, + scal:GFScale2D, + pos:GFPosition2D, + rot:GFRotation2D, + ): + item.update_transform_c(pos, rot, scal) + ) + #endregion + + #region GFTexture2D + w.observer_builder("/root/flecs/core/OnAdd") \ + .with(GFTexture2D) \ + .with(GFCanvasItem) \ + .for_each(GFTexture2D.update_texture_rect) + + w.observer_builder("/root/flecs/core/OnSet") \ + .with(GFTexture2D) \ + .with(GFCanvasItem) \ + .for_each(GFTexture2D.update_texture_rect) + #endregion diff --git a/gd/rendering/2d/texture2d.gd b/gd/rendering/2d/texture2d.gd new file mode 100644 index 0000000..fe52512 --- /dev/null +++ b/gd/rendering/2d/texture2d.gd @@ -0,0 +1,17 @@ + +## A component containing a [Texture2D]. + +class_name GFTexture2D extends GFComponent + +func get_texture() -> Texture2D: return getm(&"texture") +func set_texture(v:Texture2D) -> void: return setm(&"texture", v) +func _build(b: GFComponentBuilder) -> void: + b.add_member("texture", TYPE_OBJECT) + +static func update_texture_rect(sprite:GFTexture2D, item:GFCanvasItem) -> void: + var texture:= sprite.get_texture() + RenderingServer.canvas_item_add_texture_rect( + item.get_rid(), + Rect2(-texture.get_size() / 2, texture.get_size()), + texture, + ) diff --git a/gd/rendering/rendering.gd b/gd/rendering/rendering.gd new file mode 100644 index 0000000..0c48bbc --- /dev/null +++ b/gd/rendering/rendering.gd @@ -0,0 +1,3 @@ +extends GFModule + +const _M:= preload("./2d/2d.gd") diff --git a/gd/std/2d/canvas_item.gd b/gd/std/2d/canvas_item.gd deleted file mode 100644 index 6edde03..0000000 --- a/gd/std/2d/canvas_item.gd +++ /dev/null @@ -1,58 +0,0 @@ - -## A component that gives entities functionality of a CanvasItem. - -extends GFComponent - -const Self:= preload("./canvas_item.gd") -const Position2DC:= preload("./position2d.gd") -const Rotation2DC:= preload("./rotation2d.gd") -const Scale2DC:= preload("./scale2d.gd") - -func _build(b: GFComponentBuilder) -> void: - b.add_member("rid", TYPE_RID) - -func get_rid() -> RID: return getm(&"rid") -func set_rid(v:RID) -> void: setm(&"rid", v) - -## Sets the parent canvas item of this canvas item by its [RID]. -func set_parent_canvas_item(rid:RID) -> void: - RenderingServer.canvas_item_set_parent( - get_rid(), - rid - ) - -## Updates the transform of this canvas item via the three 2D spatial -## components. -func update_transform_c(pos:Position2DC, rot:Rotation2DC, scale:Scale2DC) -> void: - var loc:Vector2 = pos.get_vec() if pos else Vector2() - var angle:float = rot.get_angle() if rot else 0.0 - var size:Vector2 = scale.get_scale() if scale else Vector2.ONE - RenderingServer.canvas_item_set_transform( - get_rid(), - Transform2D(angle, size, 0, loc) - ) - -func _register(w:GFWorld): - # On add - w.observer_builder("flecs/core/OnAdd") \ - .with(Self) \ - .for_each(func(item:Self): - var rid:= RenderingServer.canvas_item_create() - item.set_rid(rid) - ) - - # On set - w.observer_builder("flecs/core/OnSet") \ - .with(Self) \ - .for_each(func(item:Self): - item.set_parent_canvas_item( - Engine.get_main_loop().current_scene.get_canvas_item() - ) - ) - - # On remove - w.observer_builder("flecs/core/OnRemove") \ - .with(Self) \ - .for_each(func(item:Self): - RenderingServer.free_rid(item.get_rid()) - ) diff --git a/gd/std/2d/position2d.gd b/gd/std/2d/position2d.gd deleted file mode 100644 index d4b709f..0000000 --- a/gd/std/2d/position2d.gd +++ /dev/null @@ -1,29 +0,0 @@ - -## A component that represents a position in 2D space. - -extends GFComponent - -const Self:= preload("./position2d.gd") -const CanvasItemC:= preload("./canvas_item.gd") -const Rotation2DC:= preload("./rotation2d.gd") -const Scale2DC:= preload("./scale2d.gd") - -func _build(b: GFComponentBuilder) -> void: - b.add_member("vec", TYPE_VECTOR2) -func get_vec() -> Vector2: return getm(&"vec") -func set_vec(v:Vector2) -> void: return setm(&"vec", v) -func get_x() -> float: return getm(&"vec").x -func set_x(v:float) -> void: return setm(&"vec", Vector2(v, get_y())) -func get_y() -> float: return getm(&"vec").y -func set_y(v:float) -> void: return setm(&"vec", Vector2(get_x(), v)) - -func _register(w:GFWorld): - # On Position2D set, update visual transform of CanvasItemC - w.observer_builder("flecs/core/OnSet") \ - .with(CanvasItemC).access_filter() \ - .with(Self) \ - .maybe_with(Rotation2DC) \ - .maybe_with(Scale2DC) \ - .for_each(func(item:CanvasItemC, pos:Self, rot:Rotation2DC, scl:Scale2DC): - item.update_transform_c(pos, rot, scl) - ) diff --git a/gd/std/2d/rotation2d.gd b/gd/std/2d/rotation2d.gd deleted file mode 100644 index ead9049..0000000 --- a/gd/std/2d/rotation2d.gd +++ /dev/null @@ -1,25 +0,0 @@ - -## A component that represents a rotaition in 2D space. - -extends GFComponent - -const Self:= preload("./rotation2d.gd") -const CanvasItemC:= preload("./canvas_item.gd") -const Position2DC:= preload("./position2d.gd") -const Scale2DC:= preload("./scale2d.gd") - -func _build(b: GFComponentBuilder) -> void: - b.add_member("angle", TYPE_FLOAT) -func get_angle() -> float: return getm(&"angle") -func set_angle(v:float) -> void: return setm(&"angle", v) - -func _register(w:GFWorld): - # On Rotation2DC set, update visual transform of CanvasItemC - w.observer_builder("flecs/core/OnSet") \ - .with(CanvasItemC).access_filter() \ - .with(Self) \ - .maybe_with(Position2DC) \ - .maybe_with(Scale2DC) \ - .for_each(func(item:CanvasItemC, rot:Self, pos:Position2DC, scl:Scale2DC): - item.update_transform_c(pos, rot, scl) - ) diff --git a/gd/std/2d/scale2d.gd b/gd/std/2d/scale2d.gd deleted file mode 100644 index a91159b..0000000 --- a/gd/std/2d/scale2d.gd +++ /dev/null @@ -1,26 +0,0 @@ - -## A component that represents scale in 2D space. - -extends GFComponent - -const std:= preload("../std.gd") -const CanvasItemC:= std.CanvasItemC -const Position2DC:= std.Position2DC -const Rotation2DC:= std.Rotation2DC -const Scale2DC:= std.Scale2DC - -func _build(b: GFComponentBuilder) -> void: - b.add_member("scale", TYPE_VECTOR2) -func get_scale() -> Vector2: return getm(&"scale") -func set_scale(v:Vector2) -> void: return setm(&"scale", v) - -func _register(w:GFWorld): - # On Scale2DC set, update visual transform of CanvasItemC - w.observer_builder("flecs/core/OnSet") \ - .with(CanvasItemC).access_filter() \ - .with(Scale2DC) \ - .maybe_with(Position2DC) \ - .maybe_with(Rotation2DC) \ - .for_each(func(item:CanvasItemC, scal:Scale2DC, pos:Position2DC, rot:Rotation2DC): - item.update_transform_c(pos, rot, scal) - ) diff --git a/gd/std/2d/texture2d.gd b/gd/std/2d/texture2d.gd deleted file mode 100644 index 78e2158..0000000 --- a/gd/std/2d/texture2d.gd +++ /dev/null @@ -1,27 +0,0 @@ - -## A component containing a [Texture2D]. - -extends GFComponent - -const Self:= preload("./texture2d.gd") -const CanvasItemComponent:= preload("./canvas_item.gd") -const Render:= preload("../rendering/render.gd") - -func _build(b: GFComponentBuilder) -> void: - b.add_member("texture", TYPE_OBJECT) -func get_texture() -> Texture2D: return getm(&"texture") -func set_texture(v:Texture2D) -> void: return setm(&"texture", v) - -func _register(w:GFWorld): - # On Render-Texture set with CanvasItemComponent - w.observer_builder("flecs/core/OnSet") \ - .with(w.pair(Render, Self)) \ - .with(CanvasItemComponent).access_filter() \ - .for_each(func(ctexture:Self, item:CanvasItemComponent): - var texture:= ctexture.get_texture() - RenderingServer.canvas_item_add_texture_rect( - item.get_rid(), - Rect2(-texture.get_size() / 2, texture.get_size()), - texture, - ) - ) diff --git a/gd/std/rendering/render.gd b/gd/std/rendering/render.gd deleted file mode 100644 index ed6668e..0000000 --- a/gd/std/rendering/render.gd +++ /dev/null @@ -1,7 +0,0 @@ - -## Render -## -## A tag that, when paired with certain components, renders that component -## to screen. - -extends GFRegisterableEntity diff --git a/gd/std/std.gd b/gd/std/std.gd deleted file mode 100644 index 52b245f..0000000 --- a/gd/std/std.gd +++ /dev/null @@ -1,14 +0,0 @@ - -extends GFModule - -#region 2D -const CanvasItemC:= preload("./2d/canvas_item.gd") -const Position2DC:= preload("./2d/position2d.gd") -const Rotation2DC:= preload("./2d/rotation2d.gd") -const Scale2DC:= preload("./2d/scale2d.gd") -const Texture2DC:= preload("./2d/texture2d.gd") -#endregion - -#region Rendering -const Render:= preload("./rendering/render.gd") -#endregion diff --git a/plugin.gd b/plugin.gd index 96ce68b..7873222 100644 --- a/plugin.gd +++ b/plugin.gd @@ -1,2 +1,11 @@ @tool -extends EditorPlugin \ No newline at end of file +extends EditorPlugin + +const modules:= preload("./gd/modules.gd") + +func _enter_tree() -> void: + add_autoload_singleton("_glecs_modules", "./gd/modules.gd") + + +func _exit_tree() -> void: + remove_autoload_singleton("_glecs_modules") From f8cd2273d153f816478137269c9ffa0739e8ad06 Mon Sep 17 00:00:00 2001 From: GsLogimaker Date: Wed, 27 Nov 2024 11:11:55 -0600 Subject: [PATCH 2/4] Update asteroids example --- examples/asteroids/asteroids.gd | 68 +++++++------------------------ examples/asteroids/asteroids.tscn | 2 +- 2 files changed, 15 insertions(+), 55 deletions(-) diff --git a/examples/asteroids/asteroids.gd b/examples/asteroids/asteroids.gd index be2a9ca..3266511 100644 --- a/examples/asteroids/asteroids.gd +++ b/examples/asteroids/asteroids.gd @@ -1,64 +1,24 @@ extends Node2D -var world:= GFWorld() + +var world:= GFWorld.new() var texture:= load("res://icon.png") # Called when the node enters the scene tree for the first time. func _ready() -> void: - var e:= GFEntity.spawn().set_name("Test") - e.add_component(RenderableSprite2D, [texture]) - -# Called every frame. 'delta' is the elapsed time since the previous frame. -func _process(delta: float) -> void: - pass - -class RenderableSprite2D extends GFComponent: - static func _get_members() -> Dictionary: return { - texture = null, - rid = RID(), - } + GFEntity.spawn(world) \ + .set_name("Test") \ + .add_component(GFTexture2D, [texture]) \ + .add_component(GFCanvasItem) \ + .add_component(GFPosition2D) + + world.start_rest_api() - func _register(world:GFWorld): - # On add - world.observer_builder("flecs/core/OnAdd") \ - .with(RenderableSprite2D) \ - .for_each(func(sprite:RenderableSprite2D): - await Engine.get_main_loop().process_frame - var texture:= sprite.get_texture() - if sprite.get_texture() == null: - return - var rid:= RenderingServer.canvas_item_create() - sprite.set_rid(rid) - RenderingServer.canvas_item_set_parent(rid, Engine.get_main_loop().current_scene.get_canvas_item()) - RenderingServer.canvas_item_add_texture_rect( - rid, - Rect2(-texture.get_size() / 2, texture.get_size()), - texture, - ) - ) - # On set - world.observer_builder("flecs/core/OnSet") \ - .with(RenderableSprite2D) \ - .for_each(func(sprite:RenderableSprite2D): - var texture:= sprite.get_texture() - var rid:= sprite.get_rid() - RenderingServer.canvas_item_clear(rid) - RenderingServer.canvas_item_add_texture_rect( - rid, - Rect2(-texture.get_size() / 2, texture.get_size()), - sprite.get_texture(), - ) - ) - - func get_rid() -> RID: - return getm(&"rid") - func set_rid(v:RID) -> void: - setm(&"rid", v) - - func get_texture() -> Texture2D: - return getm(&"texture") - func set_texture(v:Texture2D) -> void: - setm(&"texture", v) +func _process(delta: float) -> void: + world.progress(delta) + world.lookup("Test") \ + .get_component(GFPosition2D) \ + .set_vec(get_global_mouse_position()) diff --git a/examples/asteroids/asteroids.tscn b/examples/asteroids/asteroids.tscn index 6750709..2bc06fd 100644 --- a/examples/asteroids/asteroids.tscn +++ b/examples/asteroids/asteroids.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=3 uid="uid://dglcrfdcbfvvf"] -[ext_resource type="Script" path="res://examples/asteroids/asteroids.gd" id="1_i0ls5"] +[ext_resource type="Script" path="res://addons/glecs/examples/asteroids/asteroids.gd" id="1_i0ls5"] [node name="Asteroids" type="Node2D"] script = ExtResource("1_i0ls5") From 828c1d19cc9e02736970f4b23e5c5c87153a13d5 Mon Sep 17 00:00:00 2001 From: GsLogimaker Date: Wed, 27 Nov 2024 13:40:15 -0600 Subject: [PATCH 3/4] Add test for rendering canvas items with entities --- unittests/test_module_rendering_2d.gd | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 unittests/test_module_rendering_2d.gd diff --git a/unittests/test_module_rendering_2d.gd b/unittests/test_module_rendering_2d.gd new file mode 100644 index 0000000..6429133 --- /dev/null +++ b/unittests/test_module_rendering_2d.gd @@ -0,0 +1,30 @@ + +extends GutTest + +const TEXTURE:= preload("res://icon.png") + +var world:GFWorld = null + +func before_each(): + world = GFWorld.new() + +func after_each(): + world.free() + +#region Tests + +func test_rendering_texture(): + var e:= GFEntity.spawn(world) \ + .add_component(GFTexture2D, [TEXTURE]) \ + .add_component(GFCanvasItem) + + var draw_rect:= RenderingServer.debug_canvas_item_get_rect( + e.get_component(GFCanvasItem).get_rid() + ) + # This assert catches if the canvas item of the entity has a display size, + # but not if it is actually rendering properly. It will still pass + # if the parent is not setup correctly, causing the canvas item not to + # render. + assert_eq(draw_rect, Rect2(-(TEXTURE.get_size()/2), TEXTURE.get_size())) + +#endregion From 69f2a46c33ae0bd76a04fac2e719473c874f56ab Mon Sep 17 00:00:00 2001 From: GsLogimaker Date: Wed, 27 Nov 2024 13:47:42 -0600 Subject: [PATCH 4/4] Fix error --- gd/rendering/2d/texture2d.gd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gd/rendering/2d/texture2d.gd b/gd/rendering/2d/texture2d.gd index fe52512..6b08479 100644 --- a/gd/rendering/2d/texture2d.gd +++ b/gd/rendering/2d/texture2d.gd @@ -10,6 +10,10 @@ func _build(b: GFComponentBuilder) -> void: static func update_texture_rect(sprite:GFTexture2D, item:GFCanvasItem) -> void: var texture:= sprite.get_texture() + + if texture == null: + return + RenderingServer.canvas_item_add_texture_rect( item.get_rid(), Rect2(-texture.get_size() / 2, texture.get_size()),