| 55 |
55 |
| 56 asc_dprintf("Destroyed scene %"PRIxPTR, (uintptr_t) scene); |
56 asc_dprintf("Destroyed scene %"PRIxPTR, (uintptr_t) scene); |
| 57 asc_scene_node_free(scene->root); |
57 asc_scene_node_free(scene->root); |
| 58 } |
58 } |
| 59 |
59 |
| 60 void asc_scene_draw(AscScene *scene, asc_recti viewport) { |
60 void asc_scene_draw(AscScene *scene) { |
| 61 if (scene->root == NULL) return; |
61 if (scene->root == NULL) return; |
| |
62 |
| |
63 // if the window resized, we must update the viewport |
| |
64 if (asc_active_window->resized) { |
| |
65 if (scene->camera.viewport_update_func == NULL) { |
| |
66 // this assumes the viewport was initialized with zeros! |
| |
67 scene->camera.viewport.size = asc_active_window->dimensions; |
| |
68 } else { |
| |
69 scene->camera.viewport = scene->camera.viewport_update_func(asc_active_window->dimensions); |
| |
70 } |
| |
71 } |
| 62 |
72 |
| 63 // create render groups |
73 // create render groups |
| 64 CxList *render_group[ASC_RENDER_GROUP_COUNT]; |
74 CxList *render_group[ASC_RENDER_GROUP_COUNT]; |
| 65 cx_for_n(i, ASC_RENDER_GROUP_COUNT) { |
75 cx_for_n(i, ASC_RENDER_GROUP_COUNT) { |
| 66 render_group[i] = cxArrayListCreateSimple(CX_STORE_POINTERS, 32); |
76 render_group[i] = cxArrayListCreateSimple(CX_STORE_POINTERS, 32); |
| 67 } |
77 } |
| 68 |
78 |
| 69 // skip the root node deliberately; we know it's just the container |
79 // update the scene graph and add nodes to their render groups |
| 70 CxTreeVisitor iter = cx_tree_visitor(scene->root, |
80 CxTreeVisitor iter = cx_tree_visitor(scene->root, |
| 71 offsetof(AscSceneNode, children), |
81 offsetof(AscSceneNode, children), |
| 72 offsetof(AscSceneNode, next) |
82 offsetof(AscSceneNode, next) |
| 73 ); |
83 ); |
| 74 cxIteratorNext(iter); |
|
| 75 |
|
| 76 // update the children and add them to the render groups |
|
| 77 cx_foreach(AscSceneNode*, node, iter) { |
84 cx_foreach(AscSceneNode*, node, iter) { |
| 78 node->depth = iter.depth; |
85 node->depth = iter.depth; |
| 79 |
86 |
| 80 // skip hidden nodes (and all their children) |
87 // skip hidden nodes (and all their children) |
| 81 if (asc_test_flag(node->flags, ASC_SCENE_NODE_HIDDEN)) { |
88 if (asc_test_flag(node->flags, ASC_SCENE_NODE_HIDDEN)) { |
| 124 } |
131 } |
| 125 } |
132 } |
| 126 |
133 |
| 127 // set the viewport (in OpenGL we need to invert the Y axis) |
134 // set the viewport (in OpenGL we need to invert the Y axis) |
| 128 glViewport( |
135 glViewport( |
| 129 viewport.pos.x, |
136 scene->camera.viewport.pos.x, |
| 130 -viewport.pos.y, |
137 -scene->camera.viewport.pos.y, |
| 131 viewport.size.width, |
138 scene->camera.viewport.size.width, |
| 132 viewport.size.height |
139 scene->camera.viewport.size.height |
| 133 ); |
140 ); |
| 134 |
141 |
| 135 // ------------------------- |
142 // ------------------------- |
| 136 // process the render groups |
143 // process the render groups |
| 137 // ------------------------- |
144 // ------------------------- |