76 } |
76 } |
77 } |
77 } |
78 } |
78 } |
79 } |
79 } |
80 |
80 |
81 void asc_scene_draw_sprites( |
81 static void asc_scene_draw_sprites( |
82 const AscScene *scene, |
82 const AscScene *scene, |
83 const CxList *opaque_rect, |
83 const CxList *opaque, |
84 const CxList *opaque_uv, |
84 const CxList *blend |
85 const CxList *blend_rect, |
|
86 const CxList *blend_uv |
|
87 ) { |
85 ) { |
|
86 glEnable(GL_DEPTH_TEST); |
|
87 glClear(GL_DEPTH_BUFFER_BIT); |
|
88 const AscCamera *camera = asc_scene_camera(scene); |
|
89 |
88 // render opaque sprites from front to back |
90 // render opaque sprites from front to back |
89 CxIterator iter_opaque_rect = cxListBackwardsIterator(opaque_rect); |
91 CxIterator iter_opaque = cxListBackwardsIterator(opaque); |
90 CxIterator iter_opaque_uv = cxListBackwardsIterator(opaque_uv); |
|
91 |
92 |
92 // render sprites with alpha value from back to front |
93 // render sprites with alpha value from back to front |
93 CxIterator iter_blend_rect = cxListIterator(blend_rect); |
94 CxIterator iter_blend = cxListIterator(blend); |
94 CxIterator iter_blend_uv = cxListIterator(blend_uv); |
|
95 |
95 |
96 // TODO: implement interleaving by depth |
96 // TODO: implement interleaving by depth |
97 if (cxIteratorValid(iter_opaque_rect)) { |
97 // TODO: implement sorting by shader ID to reduce shader switches |
98 // TODO: add abstraction, because otherwise this will explode really fast when we start adding primitive shaders |
98 if (cxIteratorValid(iter_opaque)) { |
99 glDisable(GL_BLEND); |
99 glDisable(GL_BLEND); |
100 const AscShaderProgram *shader = asc_sprite_shader_rect(); |
100 cx_foreach(const AscSprite*, node, iter_opaque) { |
101 asc_shader_use(shader, &scene->camera); |
101 asc_sprite_draw(camera, node); |
102 cx_foreach(const AscSprite*, node, iter_opaque_rect) { |
102 } |
103 asc_sprite_draw(shader, node); |
103 } |
104 } |
104 if (cxIteratorValid(iter_blend)) { |
105 } |
|
106 if (cxIteratorValid(iter_opaque_uv)) { |
|
107 glDisable(GL_BLEND); |
|
108 const AscShaderProgram *shader = asc_sprite_shader_uv(); |
|
109 asc_shader_use(shader, &scene->camera); |
|
110 cx_foreach(const AscSprite*, node, iter_opaque_uv) { |
|
111 asc_sprite_draw(shader, node); |
|
112 } |
|
113 } |
|
114 if (cxIteratorValid(iter_blend_rect)) { |
|
115 glEnable(GL_BLEND); |
105 glEnable(GL_BLEND); |
116 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
106 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
117 const AscShaderProgram *shader = asc_sprite_shader_rect(); |
107 cx_foreach(const AscSprite*, node, iter_blend) { |
118 asc_shader_use(shader, &scene->camera); |
108 asc_sprite_draw(camera, node); |
119 cx_foreach(const AscSprite*, node, iter_blend_rect) { |
|
120 asc_sprite_draw(shader, node); |
|
121 } |
|
122 } |
|
123 if (cxIteratorValid(iter_blend_uv)) { |
|
124 glEnable(GL_BLEND); |
|
125 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
|
126 const AscShaderProgram *shader = asc_sprite_shader_uv(); |
|
127 asc_shader_use(shader, &scene->camera); |
|
128 cx_foreach(const AscSprite*, node, iter_blend_uv) { |
|
129 asc_sprite_draw(shader, node); |
|
130 } |
109 } |
131 } |
110 } |
132 } |
111 } |
133 |
112 |
134 void asc_scene_draw(AscScene *scene) { |
113 void asc_scene_draw(AscScene *scene) { |
227 |
206 |
228 // ------------------------- |
207 // ------------------------- |
229 // process the render groups |
208 // process the render groups |
230 // ------------------------- |
209 // ------------------------- |
231 |
210 |
|
211 // clear any previously active shader / camera combination |
|
212 asc_shader_use(NULL, NULL); |
|
213 |
232 // 2D Elements |
214 // 2D Elements |
233 // =========== |
215 // =========== |
234 glEnable(GL_DEPTH_TEST); |
|
235 glClear(GL_DEPTH_BUFFER_BIT); |
|
236 |
216 |
237 // Sprites |
217 // Sprites |
238 // ------- |
218 // ------- |
239 asc_scene_draw_sprites(scene, |
219 asc_scene_draw_sprites(scene, |
240 render_group[ASC_RENDER_GROUP_SPRITE_OPAQUE_RECT], |
220 render_group[ASC_RENDER_GROUP_SPRITE_OPAQUE], |
241 render_group[ASC_RENDER_GROUP_SPRITE_OPAQUE_UV], |
221 render_group[ASC_RENDER_GROUP_SPRITE_BLEND] |
242 render_group[ASC_RENDER_GROUP_SPRITE_BLEND_RECT], |
|
243 render_group[ASC_RENDER_GROUP_SPRITE_BLEND_UV] |
|
244 ); |
222 ); |
245 } |
223 } |
246 |
224 |
247 void asc_scene_add_node(AscScene *scene, AscSceneNode *node) { |
225 void asc_scene_add_node(AscScene *scene, AscSceneNode *node) { |
248 asc_scene_node_link(scene->root, node); |
226 asc_scene_node_link(scene->root, node); |