--- a/src/scene.c Tue Jun 10 19:29:07 2025 +0200 +++ b/src/scene.c Wed Jun 11 23:38:55 2025 +0200 @@ -78,55 +78,34 @@ } } -void asc_scene_draw_sprites( +static void asc_scene_draw_sprites( const AscScene *scene, - const CxList *opaque_rect, - const CxList *opaque_uv, - const CxList *blend_rect, - const CxList *blend_uv + const CxList *opaque, + const CxList *blend ) { + glEnable(GL_DEPTH_TEST); + glClear(GL_DEPTH_BUFFER_BIT); + const AscCamera *camera = asc_scene_camera(scene); + // render opaque sprites from front to back - CxIterator iter_opaque_rect = cxListBackwardsIterator(opaque_rect); - CxIterator iter_opaque_uv = cxListBackwardsIterator(opaque_uv); + CxIterator iter_opaque = cxListBackwardsIterator(opaque); // render sprites with alpha value from back to front - CxIterator iter_blend_rect = cxListIterator(blend_rect); - CxIterator iter_blend_uv = cxListIterator(blend_uv); + CxIterator iter_blend = cxListIterator(blend); // TODO: implement interleaving by depth - if (cxIteratorValid(iter_opaque_rect)) { - // TODO: add abstraction, because otherwise this will explode really fast when we start adding primitive shaders + // TODO: implement sorting by shader ID to reduce shader switches + if (cxIteratorValid(iter_opaque)) { glDisable(GL_BLEND); - const AscShaderProgram *shader = asc_sprite_shader_rect(); - asc_shader_use(shader, &scene->camera); - cx_foreach(const AscSprite*, node, iter_opaque_rect) { - asc_sprite_draw(shader, node); + cx_foreach(const AscSprite*, node, iter_opaque) { + asc_sprite_draw(camera, node); } } - if (cxIteratorValid(iter_opaque_uv)) { - glDisable(GL_BLEND); - const AscShaderProgram *shader = asc_sprite_shader_uv(); - asc_shader_use(shader, &scene->camera); - cx_foreach(const AscSprite*, node, iter_opaque_uv) { - asc_sprite_draw(shader, node); - } - } - if (cxIteratorValid(iter_blend_rect)) { + if (cxIteratorValid(iter_blend)) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - const AscShaderProgram *shader = asc_sprite_shader_rect(); - asc_shader_use(shader, &scene->camera); - cx_foreach(const AscSprite*, node, iter_blend_rect) { - asc_sprite_draw(shader, node); - } - } - if (cxIteratorValid(iter_blend_uv)) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - const AscShaderProgram *shader = asc_sprite_shader_uv(); - asc_shader_use(shader, &scene->camera); - cx_foreach(const AscSprite*, node, iter_blend_uv) { - asc_sprite_draw(shader, node); + cx_foreach(const AscSprite*, node, iter_blend) { + asc_sprite_draw(camera, node); } } } @@ -229,18 +208,17 @@ // process the render groups // ------------------------- + // clear any previously active shader / camera combination + asc_shader_use(NULL, NULL); + // 2D Elements // =========== - glEnable(GL_DEPTH_TEST); - glClear(GL_DEPTH_BUFFER_BIT); // Sprites // ------- asc_scene_draw_sprites(scene, - render_group[ASC_RENDER_GROUP_SPRITE_OPAQUE_RECT], - render_group[ASC_RENDER_GROUP_SPRITE_OPAQUE_UV], - render_group[ASC_RENDER_GROUP_SPRITE_BLEND_RECT], - render_group[ASC_RENDER_GROUP_SPRITE_BLEND_UV] + render_group[ASC_RENDER_GROUP_SPRITE_OPAQUE], + render_group[ASC_RENDER_GROUP_SPRITE_BLEND] ); }