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 // ------------------------- |