diff options
| -rw-r--r-- | gfx/include/gfx/scene/node.h | 6 | ||||
| -rw-r--r-- | gfx/src/renderer/renderer.c | 10 | ||||
| -rw-r--r-- | gfx/src/scene/node.c | 41 | ||||
| -rw-r--r-- | gfx/src/scene/node_impl.h | 5 | ||||
| -rw-r--r-- | gfx/src/scene/scene.c | 32 | ||||
| -rw-r--r-- | gfx/src/scene/scene_impl.h | 8 |
6 files changed, 51 insertions, 51 deletions
diff --git a/gfx/include/gfx/scene/node.h b/gfx/include/gfx/scene/node.h index a09bdbc..292a91f 100644 --- a/gfx/include/gfx/scene/node.h +++ b/gfx/include/gfx/scene/node.h | |||
| @@ -23,11 +23,11 @@ SceneNode* gfx_make_light_node(Light*); | |||
| 23 | /// Create a new object node. | 23 | /// Create a new object node. |
| 24 | SceneNode* gfx_make_object_node(SceneObject*); | 24 | SceneNode* gfx_make_object_node(SceneObject*); |
| 25 | 25 | ||
| 26 | /// Destroy the scene node. | 26 | /// Recursively destroy the scene node and its children. |
| 27 | /// | 27 | /// |
| 28 | /// The scene node is conveniently removed from the scene graph. | 28 | /// The scene node and its children are removed from the scene graph. |
| 29 | /// | 29 | /// |
| 30 | /// The node's camera, light, object, etc. is also conveniently destroyed. | 30 | /// Node resources -- cameras, lights, objects, etc. -- are also destroyed. |
| 31 | void gfx_destroy_node(SceneNode**); | 31 | void gfx_destroy_node(SceneNode**); |
| 32 | 32 | ||
| 33 | /// Set the node's parent. | 33 | /// Set the node's parent. |
diff --git a/gfx/src/renderer/renderer.c b/gfx/src/renderer/renderer.c index 3654546..8b101db 100644 --- a/gfx/src/renderer/renderer.c +++ b/gfx/src/renderer/renderer.c | |||
| @@ -122,10 +122,9 @@ typedef struct RenderState { | |||
| 122 | } RenderState; | 122 | } RenderState; |
| 123 | 123 | ||
| 124 | static void draw_recursively( | 124 | static void draw_recursively( |
| 125 | RenderState* state, mat4 parent_transform, node_idx node_index) { | 125 | RenderState* state, mat4 parent_transform, const SceneNode* node) { |
| 126 | assert(state); | 126 | assert(state); |
| 127 | const SceneNode* node = mem_get_node(node_index); | 127 | const mat4 node_transform = mat4_mul(parent_transform, node->transform); |
| 128 | const mat4 node_transform = mat4_mul(parent_transform, node->transform); | ||
| 129 | 128 | ||
| 130 | // Activate light. | 129 | // Activate light. |
| 131 | if (node->type == LightNode) { | 130 | if (node->type == LightNode) { |
| @@ -197,10 +196,9 @@ static void draw_recursively( | |||
| 197 | 196 | ||
| 198 | // Render children recursively. | 197 | // Render children recursively. |
| 199 | for (node_idx child_index = node->child; child_index.val;) { | 198 | for (node_idx child_index = node->child; child_index.val;) { |
| 200 | draw_recursively(state, node_transform, child_index); | ||
| 201 | |||
| 202 | const SceneNode* child = mem_get_node(child_index); | 199 | const SceneNode* child = mem_get_node(child_index); |
| 203 | child_index = child->next; | 200 | draw_recursively(state, node_transform, child); |
| 201 | child_index = child->next; | ||
| 204 | } | 202 | } |
| 205 | } | 203 | } |
| 206 | 204 | ||
diff --git a/gfx/src/scene/node.c b/gfx/src/scene/node.c index ee2f169..71e0e0b 100644 --- a/gfx/src/scene/node.c +++ b/gfx/src/scene/node.c | |||
| @@ -62,28 +62,49 @@ SceneNode* gfx_make_object_node(SceneObject* object) { | |||
| 62 | return node; | 62 | return node; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | void gfx_destroy_node(SceneNode** node) { | 65 | static void destroy_node_rec(SceneNode* node) { |
| 66 | assert(node); | 66 | assert(node); |
| 67 | assert(*node); | 67 | |
| 68 | // First child. | ||
| 69 | if (node->child.val) { | ||
| 70 | destroy_node_rec(mem_get_node(node->child)); | ||
| 71 | } | ||
| 72 | |||
| 73 | // Right sibling. | ||
| 74 | if (node->next.val) { | ||
| 75 | destroy_node_rec(mem_get_node(node->next)); | ||
| 76 | } | ||
| 68 | 77 | ||
| 69 | // Destroy the node's resource. | 78 | // Destroy the node's resource. |
| 70 | if ((*node)->type == CameraNode) { | 79 | if (node->type == CameraNode) { |
| 71 | SceneCamera* camera = mem_get_camera((*node)->camera); | 80 | SceneCamera* camera = mem_get_camera(node->camera); |
| 72 | camera->parent.val = 0; // Avoid call into gfx_del_node(). | 81 | camera->parent.val = 0; // Avoid call into gfx_del_node(). |
| 73 | gfx_destroy_camera(&camera); | 82 | gfx_destroy_camera(&camera); |
| 74 | } else if ((*node)->type == LightNode) { | 83 | } else if (node->type == LightNode) { |
| 75 | Light* light = mem_get_light((*node)->light); | 84 | Light* light = mem_get_light(node->light); |
| 76 | light->parent.val = 0; // Avoid call into gfx_del_node(). | 85 | light->parent.val = 0; // Avoid call into gfx_del_node(). |
| 77 | gfx_destroy_light(&light); | 86 | gfx_destroy_light(&light); |
| 78 | } else if ((*node)->type == ObjectNode) { | 87 | } else if (node->type == ObjectNode) { |
| 79 | SceneObject* object = mem_get_object((*node)->object); | 88 | SceneObject* object = mem_get_object(node->object); |
| 80 | object->parent.val = 0; // Avoid call into gfx_del_node(). | 89 | object->parent.val = 0; // Avoid call into gfx_del_node(). |
| 81 | gfx_destroy_object(&object); | 90 | gfx_destroy_object(&object); |
| 82 | } | 91 | } |
| 83 | 92 | ||
| 84 | // TODO: Should destroy children recursively? | 93 | mem_free_node(&node); |
| 94 | } | ||
| 95 | |||
| 96 | void gfx_destroy_node(SceneNode** node) { | ||
| 97 | assert(node); | ||
| 98 | assert(*node); | ||
| 99 | |||
| 100 | // Since the node and the whole hierarchy under it gets destroyed, there is | ||
| 101 | // no need to individually detach every node from its hierarchy. We can simply | ||
| 102 | // detach the given node and then destroy it and its sub-hierarchy. | ||
| 85 | TREE_REMOVE(*node); | 103 | TREE_REMOVE(*node); |
| 86 | mem_free_node(node); | 104 | |
| 105 | destroy_node_rec(*node); | ||
| 106 | |||
| 107 | *node = 0; | ||
| 87 | } | 108 | } |
| 88 | 109 | ||
| 89 | // TODO: Think more about ownership of nodes and resources. Should this function | 110 | // TODO: Think more about ownership of nodes and resources. Should this function |
diff --git a/gfx/src/scene/node_impl.h b/gfx/src/scene/node_impl.h index f4aea79..b5c4af8 100644 --- a/gfx/src/scene/node_impl.h +++ b/gfx/src/scene/node_impl.h | |||
| @@ -32,9 +32,10 @@ typedef struct SceneNode { | |||
| 32 | node_idx prev; // Previous sibling SceneNode. | 32 | node_idx prev; // Previous sibling SceneNode. |
| 33 | } SceneNode; | 33 | } SceneNode; |
| 34 | 34 | ||
| 35 | /// Destroy a node given its index without destroying its resource. | 35 | /// Recursively destroy a node given its index but without destroying the node |
| 36 | /// resources. | ||
| 36 | /// | 37 | /// |
| 37 | /// The node is conveniently removed from the scene graph. | 38 | /// The node and its children are removed from the scene graph. |
| 38 | /// | 39 | /// |
| 39 | /// This function is for the library's internal use only. | 40 | /// This function is for the library's internal use only. |
| 40 | void gfx_del_node(node_idx); | 41 | void gfx_del_node(node_idx); |
diff --git a/gfx/src/scene/scene.c b/gfx/src/scene/scene.c index 9e974de..d0d5e82 100644 --- a/gfx/src/scene/scene.c +++ b/gfx/src/scene/scene.c | |||
| @@ -1,43 +1,21 @@ | |||
| 1 | #include "scene_impl.h" | 1 | #include "scene_impl.h" |
| 2 | 2 | ||
| 3 | #include "camera_impl.h" | ||
| 4 | #include "node_impl.h" | 3 | #include "node_impl.h" |
| 5 | #include "object_impl.h" | ||
| 6 | #include "scene_graph.h" | ||
| 7 | #include "scene_memory.h" | ||
| 8 | 4 | ||
| 9 | static void scene_destroy_rec(node_idx node_index) { | 5 | #include <assert.h> |
| 10 | assert(node_index.val); | ||
| 11 | |||
| 12 | SceneNode* node = mem_get_node(node_index); | ||
| 13 | assert(node); | ||
| 14 | |||
| 15 | // First child. | ||
| 16 | if (node->child.val) { | ||
| 17 | scene_destroy_rec(node->child); | ||
| 18 | } | ||
| 19 | |||
| 20 | // Right sibling. | ||
| 21 | if (node->next.val) { | ||
| 22 | scene_destroy_rec(node->next); | ||
| 23 | } | ||
| 24 | |||
| 25 | gfx_destroy_node(&node); | ||
| 26 | } | ||
| 27 | 6 | ||
| 28 | void scene_make(Scene* scene) { | 7 | void scene_make(Scene* scene) { |
| 29 | assert(scene); | 8 | assert(scene); |
| 30 | SceneNode* root = gfx_make_node(); | 9 | scene->root = gfx_make_node(); |
| 31 | assert(root); | 10 | assert(scene->root); |
| 32 | scene->root = mem_get_node_index(root); | ||
| 33 | } | 11 | } |
| 34 | 12 | ||
| 35 | void scene_destroy(Scene* scene) { | 13 | void scene_destroy(Scene* scene) { |
| 36 | assert(scene); | 14 | assert(scene); |
| 37 | scene_destroy_rec(scene->root); | 15 | gfx_destroy_node(&scene->root); |
| 38 | } | 16 | } |
| 39 | 17 | ||
| 40 | SceneNode* gfx_get_scene_root(Scene* scene) { | 18 | SceneNode* gfx_get_scene_root(Scene* scene) { |
| 41 | assert(scene); | 19 | assert(scene); |
| 42 | return mem_get_node(scene->root); | 20 | return scene->root; |
| 43 | } | 21 | } |
diff --git a/gfx/src/scene/scene_impl.h b/gfx/src/scene/scene_impl.h index e6544dd..25ec8da 100644 --- a/gfx/src/scene/scene_impl.h +++ b/gfx/src/scene/scene_impl.h | |||
| @@ -4,10 +4,12 @@ | |||
| 4 | 4 | ||
| 5 | #include "types.h" | 5 | #include "types.h" |
| 6 | 6 | ||
| 7 | typedef struct SceneNode SceneNode; | ||
| 8 | |||
| 7 | typedef struct Scene { | 9 | typedef struct Scene { |
| 8 | node_idx root; | 10 | SceneNode* root; |
| 9 | scene_idx next; | 11 | scene_idx next; |
| 10 | scene_idx prev; | 12 | scene_idx prev; |
| 11 | } Scene; | 13 | } Scene; |
| 12 | 14 | ||
| 13 | /// Create a new scene. | 15 | /// Create a new scene. |
