src/scene.c

changeset 71
baa73a0be3ce
parent 69
86d545f490e4
child 72
84472fb3adbd
equal deleted inserted replaced
70:81a089a47eff 71:baa73a0be3ce
56 offsetof(AscSceneNode, children), 56 offsetof(AscSceneNode, children),
57 offsetof(AscSceneNode, next) 57 offsetof(AscSceneNode, next)
58 ); 58 );
59 } 59 }
60 60
61 struct asc_render_group_entry { 61 static void asc_sprite_draw(AscSprite const *node) {
62 asc_scene_draw_func draw; 62 // Obtain shader
63 AscSceneNode const *node; 63 AscShaderSprite *shader = &asc_active_window->glctx.shader.sprite;
64 }; 64
65 65 // Upload model matrix
66 #define asc_draw_render_group(iter) \ 66 glUniformMatrix4fv(shader->base.model, 1,
67 cx_foreach(struct asc_render_group_entry*, entry, iter) { \ 67 GL_FALSE, node->data.world_transform);
68 entry->draw(entry->node); \ 68
69 } 69 // Bind texture
70 asc_texture_bind(&node->tex, shader->tex, 0);
71
72 // Apply depth
73 glUniform1f(shader->depth, (float)(node->data.depth));
74
75 // Draw mesh
76 asc_primitives_draw_plane();
77 }
70 78
71 void asc_scene_draw(AscSceneNode *root, asc_recti viewport, AscCamera *camera) { 79 void asc_scene_draw(AscSceneNode *root, asc_recti viewport, AscCamera *camera) {
72 // create render groups 80 // create render groups
73 CxList *render_group[ASC_RENDER_GROUP_COUNT]; 81 CxList *render_group[ASC_RENDER_GROUP_COUNT];
74 cx_for_n(i, ASC_RENDER_GROUP_COUNT) { 82 cx_for_n(i, ASC_RENDER_GROUP_COUNT) {
75 render_group[i] = cxArrayListCreateSimple( 83 render_group[i] = cxArrayListCreateSimple(CX_STORE_POINTERS, 32);
76 sizeof(struct asc_render_group_entry), 32);
77 } 84 }
78 85
79 // skip the root node deliberately, we know it's just the container 86 // skip the root node deliberately, we know it's just the container
80 CxTreeVisitor iter = asc_scene_node_visitor(root); 87 CxTreeVisitor iter = asc_scene_node_visitor(root);
81 cxIteratorNext(iter); 88 cxIteratorNext(iter);
124 node->parent->world_transform 131 node->parent->world_transform
125 ); 132 );
126 } 133 }
127 134
128 // add to render group 135 // add to render group
129 if (node->draw_func != NULL) { 136 cxListAdd(render_group[node->render_group], node);
130 struct asc_render_group_entry entry = {
131 node->draw_func, node
132 };
133 cxListAdd(render_group[node->render_group], &entry);
134 }
135 } 137 }
136 138
137 // set the viewport (in OpenGL we need to invert the Y axis) 139 // set the viewport (in OpenGL we need to invert the Y axis)
138 glViewport( 140 glViewport(
139 viewport.pos.x, 141 viewport.pos.x,
162 GL_FALSE, camera->projection); 164 GL_FALSE, camera->projection);
163 165
164 // render opaque sprites from front to back 166 // render opaque sprites from front to back
165 glDisable(GL_BLEND); 167 glDisable(GL_BLEND);
166 render_iter = cxListBackwardsIterator(render_group[ASC_RENDER_GROUP_SPRITE_OPAQUE]); 168 render_iter = cxListBackwardsIterator(render_group[ASC_RENDER_GROUP_SPRITE_OPAQUE]);
167 asc_draw_render_group(render_iter); 169 cx_foreach(AscSprite const *, node, render_iter) {
170 asc_sprite_draw(node);
171 }
168 172
169 // render sprites with alpha value from back to front 173 // render sprites with alpha value from back to front
170 glEnable(GL_BLEND); 174 glEnable(GL_BLEND);
171 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 175 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
172 render_iter = cxListIterator(render_group[ASC_RENDER_GROUP_SPRITE_BLEND]); 176 render_iter = cxListIterator(render_group[ASC_RENDER_GROUP_SPRITE_BLEND]);
173 asc_draw_render_group(render_iter); 177 cx_foreach(AscSprite const *, node, render_iter) {
178 asc_sprite_draw(node);
179 }
174 180
175 // destroy render groups 181 // destroy render groups
176 cx_for_n(i, ASC_RENDER_GROUP_COUNT) { 182 cx_for_n(i, ASC_RENDER_GROUP_COUNT) {
177 cxListDestroy(render_group[i]); 183 cxListDestroy(render_group[i]);
178 } 184 }

mercurial