replace scaling with correct mesh sizes

Sun, 11 May 2025 14:51:00 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 11 May 2025 14:51:00 +0200
changeset 116
bfb2a7d62047
parent 115
e5f8c99b0987
child 117
d1267f656a97

replace scaling with correct mesh sizes

src/ascension/datatypes.h file | annotate | diff | comparison | revisions
src/ascension/mesh.h file | annotate | diff | comparison | revisions
src/ascension/ui/text.h file | annotate | diff | comparison | revisions
src/mesh.c file | annotate | diff | comparison | revisions
src/scene_node.c file | annotate | diff | comparison | revisions
src/sprite.c file | annotate | diff | comparison | revisions
src/text.c file | annotate | diff | comparison | revisions
test/snake/snake.c file | annotate | diff | comparison | revisions
--- a/src/ascension/datatypes.h	Sat May 10 18:51:45 2025 +0200
+++ b/src/ascension/datatypes.h	Sun May 11 14:51:00 2025 +0200
@@ -77,7 +77,9 @@
     struct { float u, v; };
     float data[2];
 } asc_vec2f;
-#define asc_vec2f_new(x, y, z) (asc_vec2f){{(float)x, (float)y}}
+#define asc_vec2f_new(x, y) (asc_vec2f){{(float)x, (float)y}}
+#define asc_vec2f_zero (asc_vec2f){{0, 0}}
+#define asc_vec2f_one (asc_vec2f){{1, 1}}
 
 typedef union asc_vec3f {
     struct { float x, y, z; };
@@ -86,6 +88,8 @@
     float data[3];
 } asc_vec3f;
 #define asc_vec3f_new(x, y, z) (asc_vec3f){{(float)x, (float)y, (float)(z)}}
+#define asc_vec3f_zero (asc_vec3f){{0, 0, 0}}
+#define asc_vec3f_one (asc_vec3f){{1, 1, 1}}
 
 typedef struct asc_col4i {
     asc_ubyte red, green, blue, alpha;
--- a/src/ascension/mesh.h	Sat May 10 18:51:45 2025 +0200
+++ b/src/ascension/mesh.h	Sun May 11 14:51:00 2025 +0200
@@ -71,13 +71,21 @@
 
 void asc_mesh_destroy(AscMesh *mesh);
 
+struct asc_mesh_init_plane_2d_args {
+    asc_vec2f size;
+    asc_vec2f uv_offset;
+    asc_vec2f uv_scale;
+};
 
 /**
- * Creates a 2D plane.
+ * Write a 2D plane to the specified mesh data.
  *
  * @param mesh the mesh to initialize
+ * @param ... the initialization parameters
  */
-void asc_mesh_plane_2d(AscMesh *mesh);
+#define asc_mesh_plane_2d(mesh, ...) asc_mesh_init_plane_2d(mesh, (struct asc_mesh_init_plane_2d_args){__VA_ARGS__})
+
+void asc_mesh_init_plane_2d(AscMesh *mesh, struct asc_mesh_init_plane_2d_args args);
 
 
 
--- a/src/ascension/ui/text.h	Sat May 10 18:51:45 2025 +0200
+++ b/src/ascension/ui/text.h	Sun May 11 14:51:00 2025 +0200
@@ -39,7 +39,14 @@
     AscFont font;
     asc_col4i color;
     unsigned short max_width;
+    /**
+     * The automatically calculated offset in case the text is centered.
+     */
     unsigned short offx;
+    /**
+     * The automatically calculated text dimension.
+     */
+    asc_vec2u dimension;
 } AscText;
 
 enum asc_text_alignment {
--- a/src/mesh.c	Sat May 10 18:51:45 2025 +0200
+++ b/src/mesh.c	Sun May 11 14:51:00 2025 +0200
@@ -75,35 +75,45 @@
     free(mesh->vtx_data);
 }
 
-void asc_mesh_plane_2d(AscMesh *mesh) {
+void asc_mesh_init_plane_2d(AscMesh *mesh, struct asc_mesh_init_plane_2d_args args) {
     if (mesh->vbo == 0) {
         asc_mesh_allocate_buffers(mesh, 1);
     }
+
+    // free any previous data
     free(mesh->vtx_data);
+
+    // default values
+    if (args.size.x == 0.0f) args.size.x = 1.0f;
+    if (args.size.y == 0.0f) args.size.y = 1.0f;
+    if (args.uv_scale.x == 0.0f) args.uv_scale.x = 1.0f;
+    if (args.uv_scale.y == 0.0f) args.uv_scale.y = 1.0f;
+
     asc_dprintf("Create plane in VBO %u and VAO %u", mesh->vbo, mesh->vao);
     mesh->vtx_count = 4;
     AscMeshVertex2d data[4] = {
         {
             .pos = {{0.0f, 0.0f}},
-            .uv = {{0.0f, 0.0f}},
+            .uv = {{args.uv_offset.x, args.uv_offset.y}},
         } , // bottom left
         {
-            .pos = {{0.0f, 1.0f}},
-            .uv = {{0.0f, 1.0f}},
+            .pos = {{0.0f, args.size.y}},
+            .uv = {{args.uv_offset.x, args.uv_offset.y + args.uv_scale.y}},
         }, // top left
         {
-            .pos = {{1.0f, 0.0f}},
-            .uv = {{1.0f, 0.0f}},
+            .pos = {{args.size.x, 0.0f}},
+            .uv = {{args.uv_offset.x + args.uv_scale.x, args.uv_offset.y}},
         }, // bottom right
         {
-            .pos = {{1.0f, 1.0f}},
-            .uv = {{1.0f, 1.0f}},
+            .pos = {{args.size.x, args.size.y}},
+            .uv = {{args.uv_offset.x + args.uv_scale.x, args.uv_offset.y + args.uv_scale.y}},
         } // top right
     };
     mesh->vtx_data = malloc(sizeof(data));
     memcpy(mesh->vtx_data, data, sizeof(data));
     glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo);
     glBufferData(GL_ARRAY_BUFFER, sizeof(data), mesh->vtx_data, GL_STATIC_DRAW);
+    // TODO: this should not be repeated for every adjustment - but it will be moved to the batch renderer anyway
     glBindVertexArray(mesh->vao);
     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(AscMeshVertex2d), (void*)offsetof(AscMeshVertex2d, pos));
     glEnableVertexAttribArray(0);
--- a/src/scene_node.c	Sat May 10 18:51:45 2025 +0200
+++ b/src/scene_node.c	Sun May 11 14:51:00 2025 +0200
@@ -48,7 +48,7 @@
 AscSceneNode *asc_scene_node_empty(void) {
     AscSceneNode *node = calloc(1, sizeof(AscSceneNode));
     node->render_group = ASC_RENDER_GROUP_NONE;
-    node->scale.x = node->scale.y = node->scale.z = 1;
+    node->scale = asc_vec3f_one;
     asc_transform_identity(node->transform);
     asc_transform_identity(node->world_transform);
     return node;
--- a/src/sprite.c	Sat May 10 18:51:45 2025 +0200
+++ b/src/sprite.c	Sun May 11 14:51:00 2025 +0200
@@ -56,16 +56,14 @@
     node->destroy_func = asc_sprite_destroy;
 
     node->position = asc_vec3f_new(args.x, args.y, ASC_SCENE_2D_DEPTH_OFFSET);
-    // TODO: do not use scale, add mesh params instead
-    node->scale = asc_vec3f_new(
-        args.width == 0 ? args.texture->width : args.width,
-        args.height == 0 ? args.texture->height : args.height,
-        1
-    );
+    node->scale = asc_vec3f_one;
     asc_node_update_transform(node);
 
     // initialize mesh
-    asc_mesh_plane_2d(&sprite->mesh);
+    asc_mesh_plane_2d(&sprite->mesh,
+        .size = asc_vec2f_new(args.width, args.height),
+        // TODO: support different texture modes
+    );
 
     return node;
 }
--- a/src/text.c	Sat May 10 18:51:45 2025 +0200
+++ b/src/text.c	Sun May 11 14:51:00 2025 +0200
@@ -54,20 +54,27 @@
         asc_error("Rendering TTF surface failed: %s", SDL_GetError());
         return;
     }
-    // TODO: don't use scale - create an own fitting mesh
-    asc_set_scale(node, (float)surface->w, (float)surface->h, 1.f);
     if (asc_test_flag(text->base.data.flags, ASC_TEXT_CENTERED_FLAG)) {
         unsigned short newoffx = surface->w / 2;
-        asc_vec2i pos = asc_get_position2d(node);
-        asc_set_position2d(node, pos.x + text->offx - newoffx, pos.y);
+        node->position.x = node->position.x + (float)(text->offx - newoffx);
         text->offx = newoffx;
     }
 
+    // If dimensions changed, update the mesh
+    if (text->dimension.x != (unsigned)surface->w || text->dimension.y != (unsigned)surface->h) {
+        text->dimension.x = surface->w;
+        text->dimension.y = surface->h;
+        asc_mesh_plane_2d(&text->base.mesh, .size = asc_vec2f_new(surface->w, surface->h));
+    }
+
     // Transfer Image Data
     asc_texture_from_surface(sprite->texture, surface);
 
     // Free the surface
     SDL_FreeSurface(surface);
+
+    // Schedule for transform update
+    asc_node_update_transform(node);
 }
 
 static void asc_text_destroy(AscSceneNode *node) {
@@ -90,7 +97,7 @@
     node->destroy_func = asc_text_destroy;
     node->update_func = asc_text_update;
     node->position = asc_vec3f_new(args.x, args.y, ASC_SCENE_2D_DEPTH_OFFSET);
-    node->scale.depth = 1.f;
+    node->scale = asc_vec3f_one;
 
     // text properties
     node->flags = args.alignment; // use flags variable to save some space
@@ -103,8 +110,8 @@
         text->text = cx_mutstr(strdup(args.text));
     }
 
-    // initialize mesh and texture
-    asc_mesh_plane_2d(&text->base.mesh);
+    // initialize texture
+    // mesh will be created in the update func
     text->base.texture = malloc(sizeof(AscTexture));
     asc_texture_init_rectangle(text->base.texture, 1);
     asc_text_update(node);
--- a/test/snake/snake.c	Sat May 10 18:51:45 2025 +0200
+++ b/test/snake/snake.c	Sun May 11 14:51:00 2025 +0200
@@ -72,8 +72,7 @@
     if (asc_test_flag(node->flags, ASC_SCENE_NODE_GRAPHICS_UPDATED)
         || asc_active_window->resized) {
         asc_vec2u bottom_right = asc_active_window->dimensions;
-        // TODO: replace scale with asc_text_get_size()
-        asc_vec3f text_size = node->scale;
+        asc_vec2u text_size = ((AscText*)node)->dimension;
         asc_set_position2d(
                 node,
                 (int)bottom_right.x - (int)text_size.width - 10,

mercurial