src/scene.c

changeset 41
df81d493716e
parent 40
6c438be1a1fd
child 43
5a8c31904e44
     1.1 --- a/src/scene.c	Thu Mar 21 20:48:18 2024 +0100
     1.2 +++ b/src/scene.c	Thu Mar 21 22:23:00 2024 +0100
     1.3 @@ -65,8 +65,8 @@
     1.4      scene->root = asc_scene_node_empty();
     1.5  
     1.6      // initialize the render groups
     1.7 -    cx_array_initialize(scene->rg_none, 8);
     1.8 -    cx_array_initialize(scene->rg_fonts, 8);
     1.9 +    cx_array_initialize(scene->rg_sprites_opaque, 8);
    1.10 +    cx_array_initialize(scene->rg_sprites_blended, 8);
    1.11  }
    1.12  
    1.13  void asc_scene_destroy(AscScene *scene) {
    1.14 @@ -83,10 +83,16 @@
    1.15          rg[i].draw(rg[i].node); \
    1.16      } (void)0
    1.17  
    1.18 +#define asc_scene_draw_render_group_reversed(rg) \
    1.19 +    for(size_t i = rg##_size ; i > 0 ; i--) { \
    1.20 +        rg[i-1].draw(rg[i-1].node); \
    1.21 +    } (void)0
    1.22 +
    1.23  void asc_scene_draw(AscScene *scene) {
    1.24      // reset render groups
    1.25 -    scene->rg_none_size = 0;
    1.26 -    scene->rg_fonts_size = 0;
    1.27 +    // TODO: avoid recalculating the groups, if possible
    1.28 +    scene->rg_sprites_opaque_size = 0;
    1.29 +    scene->rg_sprites_blended_size = 0;
    1.30  
    1.31      // skip the root node deliberately, we know it's just the container
    1.32      CxTreeIterator iter = asc_scene_node_iterator(scene->root, false);
    1.33 @@ -94,6 +100,8 @@
    1.34  
    1.35      // update the children and add them to the render groups
    1.36      cx_foreach(AscSceneNode*, node, iter) {
    1.37 +        node->depth = iter.depth;
    1.38 +
    1.39          // execute behaviors, first
    1.40          AscBehaviorNode *behavior = node->behaviors;
    1.41          while (behavior) {
    1.42 @@ -122,11 +130,11 @@
    1.43                      node->draw_func, node
    1.44              };
    1.45              switch (node->render_group) {
    1.46 -                case ASC_RENDER_GROUP_NONE:
    1.47 -                    cx_array_simple_add(scene->rg_none, entry);
    1.48 +                case ASC_RENDER_GROUP_SPRITE_OPAQUE:
    1.49 +                    cx_array_simple_add(scene->rg_sprites_opaque, entry);
    1.50                      break;
    1.51 -                case ASC_RENDER_GROUP_FONTS:
    1.52 -                    cx_array_simple_add(scene->rg_fonts, entry);
    1.53 +                case ASC_RENDER_GROUP_SPRITE_BLEND:
    1.54 +                    cx_array_simple_add(scene->rg_sprites_blended, entry);
    1.55                      break;
    1.56              }
    1.57          }
    1.58 @@ -139,6 +147,7 @@
    1.59              scene->viewport.size.width,
    1.60              scene->viewport.size.height
    1.61      );
    1.62 +    glClear(GL_COLOR_BUFFER_BIT);
    1.63  
    1.64      // -----------------------------------------
    1.65      // process the render groups for each camera
    1.66 @@ -149,21 +158,25 @@
    1.67          if (camera->update == NULL) continue;
    1.68          camera->update(camera);
    1.69  
    1.70 -        // for the NONE group, the draw func is expected to do everything
    1.71 +        // 2D Elements
    1.72 +        // ===========
    1.73          glEnable(GL_DEPTH_TEST);
    1.74 -        glDisable(GL_BLEND);
    1.75 -        asc_scene_draw_render_group(scene->rg_none);
    1.76 +        glClear(GL_DEPTH_BUFFER_BIT);
    1.77  
    1.78 -        // draw the FONTS group
    1.79 -        glDisable(GL_DEPTH_TEST);
    1.80 -        glEnable(GL_BLEND);
    1.81 -        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    1.82 +        // Sprites
    1.83 +        // -------
    1.84          // TODO: see if we can really always ignore the view matrix
    1.85 -        // TODO: compute render order for alpha blending to work correctly
    1.86          glUseProgram(ASC_SHADER_SPRITE.base.id);
    1.87          glUniformMatrix4fv(ASC_SHADER_SPRITE.base.projection, 1,
    1.88                             GL_FALSE, camera->projection);
    1.89 -        asc_scene_draw_render_group(scene->rg_fonts);
    1.90 +
    1.91 +        // render opaque sprites from front to back
    1.92 +        glDisable(GL_BLEND);
    1.93 +        asc_scene_draw_render_group_reversed(scene->rg_sprites_opaque);
    1.94 +        // render sprites with alpha value from back to front
    1.95 +        glEnable(GL_BLEND);
    1.96 +        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    1.97 +        asc_scene_draw_render_group(scene->rg_sprites_blended);
    1.98      }
    1.99  }
   1.100  

mercurial