# HG changeset patch # User Mike Becker # Date 1746967860 -7200 # Node ID bfb2a7d6204790ddbe2b0d7c3f932611dca5af8b # Parent e5f8c99b09874f4417a1e42749b95d97c77f4f03 replace scaling with correct mesh sizes diff -r e5f8c99b0987 -r bfb2a7d62047 src/ascension/datatypes.h --- 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; diff -r e5f8c99b0987 -r bfb2a7d62047 src/ascension/mesh.h --- 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); diff -r e5f8c99b0987 -r bfb2a7d62047 src/ascension/ui/text.h --- 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 { diff -r e5f8c99b0987 -r bfb2a7d62047 src/mesh.c --- 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); diff -r e5f8c99b0987 -r bfb2a7d62047 src/scene_node.c --- 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; diff -r e5f8c99b0987 -r bfb2a7d62047 src/sprite.c --- 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; } diff -r e5f8c99b0987 -r bfb2a7d62047 src/text.c --- 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); diff -r e5f8c99b0987 -r bfb2a7d62047 test/snake/snake.c --- 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,