src/scene.c

changeset 41
df81d493716e
parent 40
6c438be1a1fd
child 43
5a8c31904e44
equal deleted inserted replaced
40:6c438be1a1fd 41:df81d493716e
63 63
64 // create the root node 64 // create the root node
65 scene->root = asc_scene_node_empty(); 65 scene->root = asc_scene_node_empty();
66 66
67 // initialize the render groups 67 // initialize the render groups
68 cx_array_initialize(scene->rg_none, 8); 68 cx_array_initialize(scene->rg_sprites_opaque, 8);
69 cx_array_initialize(scene->rg_fonts, 8); 69 cx_array_initialize(scene->rg_sprites_blended, 8);
70 } 70 }
71 71
72 void asc_scene_destroy(AscScene *scene) { 72 void asc_scene_destroy(AscScene *scene) {
73 asc_scene_node_free(scene->root); 73 asc_scene_node_free(scene->root);
74 } 74 }
81 #define asc_scene_draw_render_group(rg) \ 81 #define asc_scene_draw_render_group(rg) \
82 cx_for_n(i, rg##_size) { \ 82 cx_for_n(i, rg##_size) { \
83 rg[i].draw(rg[i].node); \ 83 rg[i].draw(rg[i].node); \
84 } (void)0 84 } (void)0
85 85
86 #define asc_scene_draw_render_group_reversed(rg) \
87 for(size_t i = rg##_size ; i > 0 ; i--) { \
88 rg[i-1].draw(rg[i-1].node); \
89 } (void)0
90
86 void asc_scene_draw(AscScene *scene) { 91 void asc_scene_draw(AscScene *scene) {
87 // reset render groups 92 // reset render groups
88 scene->rg_none_size = 0; 93 // TODO: avoid recalculating the groups, if possible
89 scene->rg_fonts_size = 0; 94 scene->rg_sprites_opaque_size = 0;
95 scene->rg_sprites_blended_size = 0;
90 96
91 // skip the root node deliberately, we know it's just the container 97 // skip the root node deliberately, we know it's just the container
92 CxTreeIterator iter = asc_scene_node_iterator(scene->root, false); 98 CxTreeIterator iter = asc_scene_node_iterator(scene->root, false);
93 cxIteratorNext(iter); 99 cxIteratorNext(iter);
94 100
95 // update the children and add them to the render groups 101 // update the children and add them to the render groups
96 cx_foreach(AscSceneNode*, node, iter) { 102 cx_foreach(AscSceneNode*, node, iter) {
103 node->depth = iter.depth;
104
97 // execute behaviors, first 105 // execute behaviors, first
98 AscBehaviorNode *behavior = node->behaviors; 106 AscBehaviorNode *behavior = node->behaviors;
99 while (behavior) { 107 while (behavior) {
100 behavior->func(node); 108 behavior->func(node);
101 behavior = behavior->next; 109 behavior = behavior->next;
120 if (node->draw_func != NULL) { 128 if (node->draw_func != NULL) {
121 struct asc_render_group_entry entry = { 129 struct asc_render_group_entry entry = {
122 node->draw_func, node 130 node->draw_func, node
123 }; 131 };
124 switch (node->render_group) { 132 switch (node->render_group) {
125 case ASC_RENDER_GROUP_NONE: 133 case ASC_RENDER_GROUP_SPRITE_OPAQUE:
126 cx_array_simple_add(scene->rg_none, entry); 134 cx_array_simple_add(scene->rg_sprites_opaque, entry);
127 break; 135 break;
128 case ASC_RENDER_GROUP_FONTS: 136 case ASC_RENDER_GROUP_SPRITE_BLEND:
129 cx_array_simple_add(scene->rg_fonts, entry); 137 cx_array_simple_add(scene->rg_sprites_blended, entry);
130 break; 138 break;
131 } 139 }
132 } 140 }
133 } 141 }
134 142
137 scene->viewport.pos.x, 145 scene->viewport.pos.x,
138 -scene->viewport.pos.y, 146 -scene->viewport.pos.y,
139 scene->viewport.size.width, 147 scene->viewport.size.width,
140 scene->viewport.size.height 148 scene->viewport.size.height
141 ); 149 );
150 glClear(GL_COLOR_BUFFER_BIT);
142 151
143 // ----------------------------------------- 152 // -----------------------------------------
144 // process the render groups for each camera 153 // process the render groups for each camera
145 // ----------------------------------------- 154 // -----------------------------------------
146 cx_for_n(cam_id, ASC_SCENE_CAMERAS_MAX) { 155 cx_for_n(cam_id, ASC_SCENE_CAMERAS_MAX) {
147 // update camera parameters, first 156 // update camera parameters, first
148 AscCamera *camera = &scene->cameras[cam_id]; 157 AscCamera *camera = &scene->cameras[cam_id];
149 if (camera->update == NULL) continue; 158 if (camera->update == NULL) continue;
150 camera->update(camera); 159 camera->update(camera);
151 160
152 // for the NONE group, the draw func is expected to do everything 161 // 2D Elements
162 // ===========
153 glEnable(GL_DEPTH_TEST); 163 glEnable(GL_DEPTH_TEST);
154 glDisable(GL_BLEND); 164 glClear(GL_DEPTH_BUFFER_BIT);
155 asc_scene_draw_render_group(scene->rg_none); 165
156 166 // Sprites
157 // draw the FONTS group 167 // -------
158 glDisable(GL_DEPTH_TEST);
159 glEnable(GL_BLEND);
160 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
161 // TODO: see if we can really always ignore the view matrix 168 // TODO: see if we can really always ignore the view matrix
162 // TODO: compute render order for alpha blending to work correctly
163 glUseProgram(ASC_SHADER_SPRITE.base.id); 169 glUseProgram(ASC_SHADER_SPRITE.base.id);
164 glUniformMatrix4fv(ASC_SHADER_SPRITE.base.projection, 1, 170 glUniformMatrix4fv(ASC_SHADER_SPRITE.base.projection, 1,
165 GL_FALSE, camera->projection); 171 GL_FALSE, camera->projection);
166 asc_scene_draw_render_group(scene->rg_fonts); 172
173 // render opaque sprites from front to back
174 glDisable(GL_BLEND);
175 asc_scene_draw_render_group_reversed(scene->rg_sprites_opaque);
176 // render sprites with alpha value from back to front
177 glEnable(GL_BLEND);
178 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
179 asc_scene_draw_render_group(scene->rg_sprites_blended);
167 } 180 }
168 } 181 }
169 182
170 AscSceneNode *asc_scene_node_empty(void) { 183 AscSceneNode *asc_scene_node_empty(void) {
171 AscSceneNode *node = calloc(1, sizeof(AscSceneNode)); 184 AscSceneNode *node = calloc(1, sizeof(AscSceneNode));

mercurial