# HG changeset patch # User Mike Becker # Date 1749897517 -7200 # Node ID 3045f61bc4ebf395a6af64fbc3b73a14be6d56d4 # Parent 560772519ff982b2593d3af7c02a71fa4f964f43 make draw function dynamic required to solve issue #384 diff -r 560772519ff9 -r 3045f61bc4eb src/ascension/datatypes.h --- a/src/ascension/datatypes.h Sat Jun 14 11:40:40 2025 +0200 +++ b/src/ascension/datatypes.h Sat Jun 14 12:38:37 2025 +0200 @@ -186,6 +186,22 @@ return asc_vec3f_new(v.x*s, v.y*s, v.z*s); } +static inline unsigned asc_vec2u_sqrlen(asc_vec2u v) { + return v.x*v.x + v.y*v.y; +} + +static inline unsigned asc_vec2i_sqrlen(asc_vec2i v) { + return v.x*v.x + v.y*v.y; +} + +static inline float asc_vec2f_sqrlen(asc_vec2f v) { + return v.x*v.x + v.y*v.y; +} + +static inline float asc_vec3f_sqrlen(asc_vec3f v) { + return v.x*v.x + v.y*v.y + v.z*v.z; +} + // -------------------------------------------------------------------------- // Matrix Functions // -------------------------------------------------------------------------- diff -r 560772519ff9 -r 3045f61bc4eb src/ascension/scene_node.h --- a/src/ascension/scene_node.h Sat Jun 14 11:40:40 2025 +0200 +++ b/src/ascension/scene_node.h Sat Jun 14 12:38:37 2025 +0200 @@ -35,15 +35,17 @@ #include "transform.h" typedef struct asc_scene_node_s AscSceneNode; +typedef struct asc_camera_s AscCamera; // opaque declared typedef void(*asc_scene_node_destroy_func)(AscSceneNode*); typedef void(*asc_scene_node_update_func)(AscSceneNode*); +typedef void(*asc_scene_node_draw_func)(const AscCamera*,const AscSceneNode*); // TODO: rework the concept of render groups, because currently it is only half abstract, half hard-coded enum AscRenderGroup { ASC_RENDER_GROUP_NONE = -1, - ASC_RENDER_GROUP_SPRITE_OPAQUE, - ASC_RENDER_GROUP_SPRITE_BLEND, + ASC_RENDER_GROUP_2D_OPAQUE, + ASC_RENDER_GROUP_2D_BLEND, ASC_RENDER_GROUP_COUNT }; @@ -61,6 +63,7 @@ CxList *behaviors; asc_scene_node_destroy_func destroy_func; asc_scene_node_update_func update_func; + asc_scene_node_draw_func draw_func; asc_vec3f position; asc_vec3f rotation; asc_vec3f scale; diff -r 560772519ff9 -r 3045f61bc4eb src/ascension/sprite.h --- a/src/ascension/sprite.h Sat Jun 14 11:40:40 2025 +0200 +++ b/src/ascension/sprite.h Sat Jun 14 12:38:37 2025 +0200 @@ -71,6 +71,6 @@ void asc_sprite_set_size(AscSceneNode *node, unsigned width, unsigned height); -void asc_sprite_draw(const AscCamera *camera, const AscSprite *node); +void asc_sprite_draw(const AscCamera *camera, const AscSceneNode *node); #endif //ASCENSION_SPRITE_H diff -r 560772519ff9 -r 3045f61bc4eb src/scene.c --- a/src/scene.c Sat Jun 14 11:40:40 2025 +0200 +++ b/src/scene.c Sat Jun 14 12:38:37 2025 +0200 @@ -30,7 +30,6 @@ #include "ascension/scene.h" #include "ascension/behavior.h" #include "ascension/shader.h" -#include "ascension/sprite.h" #include #include @@ -76,7 +75,7 @@ } } -static void asc_scene_draw_sprites( +static void asc_scene_draw2d( const AscScene *scene, const CxList *opaque, const CxList *blend @@ -85,25 +84,25 @@ glClear(GL_DEPTH_BUFFER_BIT); const AscCamera *camera = asc_scene_camera(scene); - // render opaque sprites from front to back + // render opaque nodes from front to back CxIterator iter_opaque = cxListBackwardsIterator(opaque); - // render sprites with alpha value from back to front + // render nodes with alpha blending from back to front CxIterator iter_blend = cxListIterator(blend); // TODO: implement interleaving by depth // TODO: implement sorting by shader ID to reduce shader switches if (cxIteratorValid(iter_opaque)) { glDisable(GL_BLEND); - cx_foreach(const AscSprite*, node, iter_opaque) { - asc_sprite_draw(camera, node); + cx_foreach(const AscSceneNode*, node, iter_opaque) { + node->draw_func(camera, node); } } if (cxIteratorValid(iter_blend)) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - cx_foreach(const AscSprite*, node, iter_blend) { - asc_sprite_draw(camera, node); + cx_foreach(const AscSceneNode*, node, iter_blend) { + node->draw_func(camera, node); } } } @@ -210,13 +209,9 @@ asc_shader_use(NULL, NULL); // 2D Elements - // =========== - - // Sprites - // ------- - asc_scene_draw_sprites(scene, - render_group[ASC_RENDER_GROUP_SPRITE_OPAQUE], - render_group[ASC_RENDER_GROUP_SPRITE_BLEND] + asc_scene_draw2d(scene, + render_group[ASC_RENDER_GROUP_2D_OPAQUE], + render_group[ASC_RENDER_GROUP_2D_BLEND] ); } diff -r 560772519ff9 -r 3045f61bc4eb src/sprite.c --- a/src/sprite.c Sat Jun 14 11:40:40 2025 +0200 +++ b/src/sprite.c Sat Jun 14 12:38:37 2025 +0200 @@ -106,6 +106,28 @@ ); } +void asc_sprite_draw(const AscCamera *camera, const AscSceneNode *node) { + asc_ptr_cast(const AscSprite, sprite, node); + + // Activate shader + // TODO: scene should know which shader we are going to activate s.t. it can pre-sort nodes + const AscSpriteShader *shader = + sprite->texture->target == GL_TEXTURE_RECTANGLE + ? asc_sprite_shader_rect() + : asc_sprite_shader_uv(); + asc_shader_use(&shader->program, camera); + + // Upload model matrix + glUniformMatrix4fv(shader->program.model, 1, + GL_FALSE, node->world_transform); + + // Bind texture + asc_texture_bind(sprite->texture, shader->tex, 0); + + // Draw mesh + asc_mesh_draw_triangle_strip(&sprite->mesh); +} + AscSceneNode *asc_sprite_create(struct asc_sprite_create_args args) { AscSprite *sprite = cxZallocDefault(sizeof(AscSprite)); @@ -122,10 +144,11 @@ AscSceneNode *node = (AscSceneNode *) sprite; asc_scene_node_name(node, args.name); node->render_group = args.opaque - ? ASC_RENDER_GROUP_SPRITE_OPAQUE - : ASC_RENDER_GROUP_SPRITE_BLEND; + ? ASC_RENDER_GROUP_2D_OPAQUE + : ASC_RENDER_GROUP_2D_BLEND; node->update_func = asc_sprite_update; node->destroy_func = asc_sprite_destroy; + node->draw_func = asc_sprite_draw; node->position = asc_vec3f_new(args.x, args.y, ASC_SCENE_2D_DEPTH_OFFSET); node->scale = asc_vec3f_one; @@ -134,25 +157,6 @@ return node; } -void asc_sprite_draw(const AscCamera *camera, const AscSprite *node) { - // Activate shader - const AscSpriteShader *shader = - node->texture->target == GL_TEXTURE_RECTANGLE - ? asc_sprite_shader_rect() - : asc_sprite_shader_uv(); - asc_shader_use(&shader->program, camera); - - // Upload model matrix - glUniformMatrix4fv(shader->program.model, 1, - GL_FALSE, node->data.world_transform); - - // Bind texture - asc_texture_bind(node->texture, shader->tex, 0); - - // Draw mesh - asc_mesh_draw_triangle_strip(&node->mesh); -} - void asc_sprite_set_size(AscSceneNode *node, unsigned width, unsigned height) { AscSprite *sprite = (AscSprite*) node; sprite->width = width; diff -r 560772519ff9 -r 3045f61bc4eb src/text.c --- a/src/text.c Sat Jun 14 11:40:40 2025 +0200 +++ b/src/text.c Sat Jun 14 12:38:37 2025 +0200 @@ -97,9 +97,10 @@ // node properties asc_scene_node_name(node, args.name); - node->render_group = ASC_RENDER_GROUP_SPRITE_BLEND; + node->render_group = ASC_RENDER_GROUP_2D_BLEND; node->destroy_func = asc_text_destroy; node->update_func = asc_text_update; + node->draw_func = asc_sprite_draw; node->position = asc_vec3f_new(args.x, args.y, ASC_SCENE_2D_DEPTH_OFFSET); node->scale = asc_vec3f_one;