Sat, 10 May 2025 18:51:45 +0200
refactor rendering 1/3 - create new mesh structs
shader/sprite_vtx.glsl | file | annotate | diff | comparison | revisions | |
src/Makefile | file | annotate | diff | comparison | revisions | |
src/ascension/2d/sprite.h | file | annotate | diff | comparison | revisions | |
src/ascension/datatypes.h | file | annotate | diff | comparison | revisions | |
src/ascension/glcontext.h | file | annotate | diff | comparison | revisions | |
src/ascension/mesh.h | file | annotate | diff | comparison | revisions | |
src/ascension/primitives.h | file | annotate | diff | comparison | revisions | |
src/glcontext.c | file | annotate | diff | comparison | revisions | |
src/mesh.c | file | annotate | diff | comparison | revisions | |
src/primitives.c | file | annotate | diff | comparison | revisions | |
src/sprite.c | file | annotate | diff | comparison | revisions | |
src/text.c | file | annotate | diff | comparison | revisions | |
test/snake/Makefile | file | annotate | diff | comparison | revisions |
--- a/shader/sprite_vtx.glsl Sat May 10 15:42:56 2025 +0200 +++ b/shader/sprite_vtx.glsl Sat May 10 18:51:45 2025 +0200 @@ -1,6 +1,7 @@ #version 400 core -layout(location = 0) in vec2 position; +layout(location = 0) in vec2 in_pos; +layout(location = 1) in vec2 in_uv; out vec2 texcoord; out vec2 uvcoord; @@ -9,8 +10,9 @@ uniform mat4 model; void main(void) { - vec4 pos = projection*view*model*vec4(position.xy, 0.0, 1.0); + vec4 pos = projection*view*model*vec4(in_pos.xy, 0.0, 1.0); gl_Position = pos; - uvcoord = position; - texcoord = vec2(model[0].x, model[1].y)*position; + uvcoord = in_uv; + // TODO: we don't need that in the future + texcoord = vec2(model[0].x, model[1].y)*in_pos; }
--- a/src/Makefile Sat May 10 15:42:56 2025 +0200 +++ b/src/Makefile Sat May 10 18:51:45 2025 +0200 @@ -30,7 +30,6 @@ SRC = context.c glcontext.c filesystem.c error.c \ window.c shader.c mesh.c texture.c \ sprite.c \ - primitives.c \ camera.c scene.c scene_node.c behavior.c \ font.c text.c @@ -47,7 +46,7 @@ $(BUILD_DIR)/behavior.o: behavior.c ascension/behavior.h \ ascension/scene_node.h ascension/datatypes.h ascension/transform.h \ - ascension/error.h + ascension/error.h ascension/scene.h ascension/camera.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< @@ -58,19 +57,17 @@ $(BUILD_DIR)/context.o: context.c ascension/context.h \ ascension/datatypes.h ascension/window.h ascension/glcontext.h \ - ascension/primitives.h ascension/mesh.h ascension/shader.h \ - ascension/texture.h ascension/scene.h ascension/scene_node.h \ - ascension/transform.h ascension/camera.h ascension/input.h \ - ascension/ui/font.h ascension/error.h + ascension/shader.h ascension/texture.h ascension/scene.h \ + ascension/scene_node.h ascension/transform.h ascension/camera.h \ + ascension/input.h ascension/ui/font.h ascension/error.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< $(BUILD_DIR)/error.o: error.c ascension/context.h ascension/datatypes.h \ - ascension/window.h ascension/glcontext.h ascension/primitives.h \ - ascension/mesh.h ascension/shader.h ascension/texture.h \ - ascension/scene.h ascension/scene_node.h ascension/transform.h \ - ascension/camera.h ascension/input.h ascension/ui/font.h \ - ascension/error.h + ascension/window.h ascension/glcontext.h ascension/shader.h \ + ascension/texture.h ascension/scene.h ascension/scene_node.h \ + ascension/transform.h ascension/camera.h ascension/input.h \ + ascension/ui/font.h ascension/error.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< @@ -80,94 +77,89 @@ $(BUILD_DIR)/font.o: font.c ascension/error.h ascension/context.h \ ascension/datatypes.h ascension/window.h ascension/glcontext.h \ - ascension/primitives.h ascension/mesh.h ascension/shader.h \ - ascension/texture.h ascension/scene.h ascension/scene_node.h \ - ascension/transform.h ascension/camera.h ascension/input.h \ - ascension/ui/font.h ascension/filesystem.h ascension/ui/font.h + ascension/shader.h ascension/texture.h ascension/scene.h \ + ascension/scene_node.h ascension/transform.h ascension/camera.h \ + ascension/input.h ascension/ui/font.h ascension/filesystem.h \ + ascension/ui/font.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< $(BUILD_DIR)/glcontext.o: glcontext.c ascension/glcontext.h \ - ascension/primitives.h ascension/mesh.h ascension/shader.h \ - ascension/texture.h ascension/error.h + ascension/shader.h ascension/texture.h ascension/error.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< -$(BUILD_DIR)/mesh.o: mesh.c ascension/error.h ascension/mesh.h - @echo "Compiling $<" - $(CC) -o $@ $(CFLAGS) -c $< - -$(BUILD_DIR)/primitives.o: primitives.c ascension/primitives.h \ - ascension/mesh.h ascension/error.h +$(BUILD_DIR)/mesh.o: mesh.c ascension/error.h ascension/mesh.h \ + ascension/datatypes.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< $(BUILD_DIR)/scene.o: scene.c ascension/error.h ascension/context.h \ ascension/datatypes.h ascension/window.h ascension/glcontext.h \ - ascension/primitives.h ascension/mesh.h ascension/shader.h \ - ascension/texture.h ascension/scene.h ascension/scene_node.h \ - ascension/transform.h ascension/camera.h ascension/input.h \ - ascension/ui/font.h ascension/scene.h ascension/behavior.h \ - ascension/shader.h ascension/2d.h ascension/2d/sprite.h \ - ascension/2d/../scene_node.h ascension/2d/../texture.h + ascension/shader.h ascension/texture.h ascension/scene.h \ + ascension/scene_node.h ascension/transform.h ascension/camera.h \ + ascension/input.h ascension/ui/font.h ascension/scene.h \ + ascension/behavior.h ascension/shader.h ascension/2d.h \ + ascension/2d/sprite.h ascension/2d/../scene_node.h \ + ascension/2d/../mesh.h ascension/2d/../datatypes.h \ + ascension/2d/../texture.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< $(BUILD_DIR)/scene_node.o: scene_node.c ascension/scene_node.h \ ascension/datatypes.h ascension/transform.h ascension/context.h \ - ascension/window.h ascension/glcontext.h ascension/primitives.h \ - ascension/mesh.h ascension/shader.h ascension/texture.h \ - ascension/scene.h ascension/scene_node.h ascension/camera.h \ - ascension/input.h ascension/ui/font.h + ascension/window.h ascension/glcontext.h ascension/shader.h \ + ascension/texture.h ascension/scene.h ascension/scene_node.h \ + ascension/camera.h ascension/input.h ascension/ui/font.h \ + ascension/error.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< $(BUILD_DIR)/shader.o: shader.c ascension/context.h ascension/datatypes.h \ - ascension/window.h ascension/glcontext.h ascension/primitives.h \ - ascension/mesh.h ascension/shader.h ascension/texture.h \ - ascension/scene.h ascension/scene_node.h ascension/transform.h \ - ascension/camera.h ascension/input.h ascension/ui/font.h \ - ascension/error.h ascension/shader.h ascension/filesystem.h + ascension/window.h ascension/glcontext.h ascension/shader.h \ + ascension/texture.h ascension/scene.h ascension/scene_node.h \ + ascension/transform.h ascension/camera.h ascension/input.h \ + ascension/ui/font.h ascension/error.h ascension/shader.h \ + ascension/filesystem.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< $(BUILD_DIR)/sprite.o: sprite.c ascension/2d/sprite.h \ ascension/2d/../scene_node.h ascension/2d/../datatypes.h \ - ascension/2d/../transform.h ascension/2d/../texture.h \ - ascension/context.h ascension/datatypes.h ascension/window.h \ - ascension/glcontext.h ascension/primitives.h ascension/mesh.h \ - ascension/shader.h ascension/texture.h ascension/scene.h \ - ascension/scene_node.h ascension/camera.h ascension/input.h \ - ascension/ui/font.h ascension/glcontext.h + ascension/2d/../transform.h ascension/2d/../mesh.h \ + ascension/2d/../texture.h ascension/context.h ascension/datatypes.h \ + ascension/window.h ascension/glcontext.h ascension/shader.h \ + ascension/texture.h ascension/scene.h ascension/scene_node.h \ + ascension/camera.h ascension/input.h ascension/ui/font.h \ + ascension/glcontext.h ascension/mesh.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< $(BUILD_DIR)/text.o: text.c ascension/error.h ascension/context.h \ ascension/datatypes.h ascension/window.h ascension/glcontext.h \ - ascension/primitives.h ascension/mesh.h ascension/shader.h \ - ascension/texture.h ascension/scene.h ascension/scene_node.h \ - ascension/transform.h ascension/camera.h ascension/input.h \ - ascension/ui/font.h ascension/ui/text.h ascension/ui/font.h \ - ascension/ui/../2d/sprite.h ascension/ui/../2d/../scene_node.h \ - ascension/ui/../2d/../texture.h + ascension/shader.h ascension/texture.h ascension/scene.h \ + ascension/scene_node.h ascension/transform.h ascension/camera.h \ + ascension/input.h ascension/ui/font.h ascension/ui/text.h \ + ascension/ui/font.h ascension/ui/../2d/sprite.h \ + ascension/ui/../2d/../scene_node.h ascension/ui/../2d/../mesh.h \ + ascension/ui/../2d/../datatypes.h ascension/ui/../2d/../texture.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< $(BUILD_DIR)/texture.o: texture.c ascension/error.h ascension/context.h \ ascension/datatypes.h ascension/window.h ascension/glcontext.h \ - ascension/primitives.h ascension/mesh.h ascension/shader.h \ - ascension/texture.h ascension/scene.h ascension/scene_node.h \ - ascension/transform.h ascension/camera.h ascension/input.h \ - ascension/ui/font.h ascension/texture.h ascension/filesystem.h + ascension/shader.h ascension/texture.h ascension/scene.h \ + ascension/scene_node.h ascension/transform.h ascension/camera.h \ + ascension/input.h ascension/ui/font.h ascension/texture.h \ + ascension/filesystem.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $< $(BUILD_DIR)/window.o: window.c ascension/error.h ascension/window.h \ - ascension/datatypes.h ascension/glcontext.h ascension/primitives.h \ - ascension/mesh.h ascension/shader.h ascension/texture.h \ - ascension/scene.h ascension/scene_node.h ascension/transform.h \ - ascension/camera.h ascension/context.h ascension/window.h \ - ascension/input.h ascension/ui/font.h + ascension/datatypes.h ascension/glcontext.h ascension/shader.h \ + ascension/texture.h ascension/scene.h ascension/scene_node.h \ + ascension/transform.h ascension/camera.h ascension/context.h \ + ascension/window.h ascension/input.h ascension/ui/font.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $<
--- a/src/ascension/2d/sprite.h Sat May 10 15:42:56 2025 +0200 +++ b/src/ascension/2d/sprite.h Sat May 10 18:51:45 2025 +0200 @@ -29,10 +29,12 @@ #define ASCENSION_SPRITE_H #include "../scene_node.h" +#include "../mesh.h" #include "../texture.h" typedef struct AscSprite { AscSceneNode data; + AscMesh mesh; AscTexture *texture; } AscSprite;
--- a/src/ascension/datatypes.h Sat May 10 15:42:56 2025 +0200 +++ b/src/ascension/datatypes.h Sat May 10 18:51:45 2025 +0200 @@ -71,6 +71,14 @@ } asc_recti; #define asc_recti_new(x, y, w, h) (asc_recti){asc_vec2i_new(x,y), asc_vec2u_new(w,h)} +typedef union asc_vec2f { + struct { float x, y; }; + struct { float width, height; }; + struct { float u, v; }; + float data[2]; +} asc_vec2f; +#define asc_vec2f_new(x, y, z) (asc_vec2f){{(float)x, (float)y}} + typedef union asc_vec3f { struct { float x, y, z; }; struct { float width, height, depth; };
--- a/src/ascension/glcontext.h Sat May 10 15:42:56 2025 +0200 +++ b/src/ascension/glcontext.h Sat May 10 18:51:45 2025 +0200 @@ -32,7 +32,6 @@ #include <cx/list.h> -#include "primitives.h" #include "shader.h" #include "texture.h" @@ -43,11 +42,6 @@ int depth_size; } AscGLContextSettings; -enum AscDefaultPrimitives { - ASC_PRIMITIVE_PLANE_IDX = 0, - ASC_PRIMITIVE_COUNT -}; - enum AscDefaultTextures2d { ASC_TEXTURE_2D_EMPTY_1X1_IDX = 0, ASC_TEXTURE_2D_COUNT @@ -62,7 +56,7 @@ SDL_Window *window; SDL_GLContext glctx; CxList *cleanup_funcs; - AscMesh primitives[ASC_PRIMITIVE_COUNT]; + // TODO: find a better way to store the dummy textures AscTexture textures_2d[ASC_TEXTURE_2D_COUNT]; AscTexture textures_rect[ASC_TEXTURE_RECT_COUNT]; struct { @@ -71,7 +65,6 @@ } AscGLContext; #define asc_active_glctx (&asc_active_window->glctx) -#define ASC_PRIMITIVE_PLANE (&asc_active_glctx->primitives[ASC_PRIMITIVE_PLANE_IDX]) #define ASC_TEXTURE_2D_EMPTY_1X1 (&asc_active_glctx->textures_2d[ASC_TEXTURE_2D_EMPTY_1X1_IDX]) #define ASC_TEXTURE_RECT_EMPTY_1X1 (&asc_active_glctx->textures_rect[ASC_TEXTURE_RECT_EMPTY_1X1_IDX]) #define ASC_SHADER_SPRITE (&asc_active_glctx->shader.sprite)
--- a/src/ascension/mesh.h Sat May 10 15:42:56 2025 +0200 +++ b/src/ascension/mesh.h Sat May 10 18:51:45 2025 +0200 @@ -28,12 +28,61 @@ #ifndef ASCENSION_MESH_H #define ASCENSION_MESH_H +#include "datatypes.h" + +enum AscMeshType { + ASC_MESH_2D, + ASC_MESH_2D_COLORED, + ASC_MESH_3D, + ASC_MESH_3D_COLORED, +}; + typedef struct AscMesh { + // TODO: for batched rendering, VAO and VBO must not be part of the mesh unsigned vbo; unsigned vao; - unsigned vertices; + enum AscMeshType type; + unsigned vtx_count; + float *vtx_data; } AscMesh; +typedef struct AscMeshVertex2d { + asc_vec2f pos; + asc_vec2f uv; +} AscMeshVertex2d; + +typedef struct AscMeshVertex2dColored { + asc_vec2f pos; + asc_vec2f uv; + asc_col4f color; +} AscMeshVertex2dColored; + +typedef struct AscMeshVertex3d { + asc_vec3f pos; + asc_vec2f uv; +} AscMeshVertex3d; + +typedef struct AscMeshVertex3dColored { + asc_vec3f pos; + asc_vec2f uv; + asc_col4f color; +} AscMeshVertex3dColored; + + +void asc_mesh_destroy(AscMesh *mesh); + + +/** + * Creates a 2D plane. + * + * @param mesh the mesh to initialize + */ +void asc_mesh_plane_2d(AscMesh *mesh); + + + +// TODO: replace below functions with a batched rendering implementation + /** * Allocates VBO and VAO for one or more meshes. * @@ -55,6 +104,6 @@ * * @param mesh the mesh to draw */ -void asc_mesh_draw_triangle_strip(AscMesh *mesh); +void asc_mesh_draw_triangle_strip(const AscMesh *mesh); #endif //ASCENSION_MESH_H
--- a/src/ascension/primitives.h Sat May 10 15:42:56 2025 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * Copyright 2023 Mike Becker. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ASCENSION_PRIMITIVES_H -#define ASCENSION_PRIMITIVES_H - -#include <stdbool.h> - -#include "mesh.h" - -void asc_primitives_init_plane(AscMesh *mesh); - -#endif //ASCENSION_PRIMITIVES_H
--- a/src/glcontext.c Sat May 10 15:42:56 2025 +0200 +++ b/src/glcontext.c Sat May 10 18:51:45 2025 +0200 @@ -45,21 +45,6 @@ } } -static int asc_primitives_init(AscGLContext *context) { - asc_dprintf("Create primitives for the GL context of active window."); - asc_mesh_allocate_buffers(context->primitives, ASC_PRIMITIVE_COUNT); - - asc_primitives_init_plane(&context->primitives[ASC_PRIMITIVE_PLANE_IDX]); - // TODO: more primitives - - return asc_error_catch_all_gl(); -} - -static void asc_primitives_destroy(AscGLContext *context) { - asc_dprintf("Destroy primitives in GL context of active window."); - asc_mesh_free_buffers((AscMesh*)&context->primitives, sizeof(context->primitives) / sizeof(AscMesh)); -} - static int asc_shader_initialize_predefined(AscGLContext *ctx) { int ret = 0; ret |= asc_shader_sprite_init(&ctx->shader.sprite); @@ -145,12 +130,6 @@ glEnable(GL_DEBUG_OUTPUT); glDebugMessageCallback(asc_gl_debug_callback, NULL); - if (asc_primitives_init(ctx)) { - asc_error("Creating primitive meshes failed"); - SDL_GL_DeleteContext(ctx->glctx); - return false; - } - if (asc_shader_initialize_predefined(ctx)) { asc_error("Initializing predefined shaders failed"); SDL_GL_DeleteContext(ctx->glctx); @@ -180,7 +159,6 @@ cxListFree(ctx->cleanup_funcs); asc_texture_destroy_predefined(ctx); asc_shader_destroy_predefined(ctx); - asc_primitives_destroy(ctx); // destroy the GL context and the window SDL_GL_DeleteContext(ctx->glctx);
--- a/src/mesh.c Sat May 10 15:42:56 2025 +0200 +++ b/src/mesh.c Sat May 10 18:51:45 2025 +0200 @@ -44,6 +44,7 @@ } void asc_mesh_free_buffers(AscMesh *mesh, unsigned count) { + if (count == 1 && mesh->vbo == 0) return; // hack to skip this function until we remove it asc_dprintf("Free mesh buffers for %u meshes.", count); GLuint buffers[count]; GLuint arrays[count]; @@ -60,11 +61,52 @@ asc_error_catch_all_gl(); } -void asc_mesh_draw_triangle_strip(AscMesh *mesh) { +void asc_mesh_draw_triangle_strip(const AscMesh *mesh) { glBindVertexArray(mesh->vao); - glDrawArrays(GL_TRIANGLE_STRIP, 0, mesh->vertices); + glDrawArrays(GL_TRIANGLE_STRIP, 0, mesh->vtx_count); #ifndef NDEBUG // only unbind in debug mode to detect accidental re-use of the wrong VAO glBindVertexArray(0); #endif } + +void asc_mesh_destroy(AscMesh *mesh) { + asc_mesh_free_buffers(mesh, 1); + free(mesh->vtx_data); +} + +void asc_mesh_plane_2d(AscMesh *mesh) { + if (mesh->vbo == 0) { + asc_mesh_allocate_buffers(mesh, 1); + } + free(mesh->vtx_data); + 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}}, + } , // bottom left + { + .pos = {{0.0f, 1.0f}}, + .uv = {{0.0f, 1.0f}}, + }, // top left + { + .pos = {{1.0f, 0.0f}}, + .uv = {{1.0f, 0.0f}}, + }, // bottom right + { + .pos = {{1.0f, 1.0f}}, + .uv = {{1.0f, 1.0f}}, + } // 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); + glBindVertexArray(mesh->vao); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(AscMeshVertex2d), (void*)offsetof(AscMeshVertex2d, pos)); + glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(AscMeshVertex2d), (void*)offsetof(AscMeshVertex2d, uv)); + glEnableVertexAttribArray(1); +}
--- a/src/primitives.c Sat May 10 15:42:56 2025 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * Copyright 2023 Mike Becker. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ascension/primitives.h" -#include "ascension/error.h" - -#include <GL/glew.h> - -void asc_primitives_init_plane(AscMesh *mesh) { - if (mesh->vbo == 0) { - if (mesh->vao > 0) { - asc_dprintf("!!! Mesh with VAO %u has no VBO - this is most likely a programming error !!!", mesh->vao); - } - asc_mesh_allocate_buffers(mesh, 1); - } - asc_dprintf("Create plane in VBO %u and VAO %u", mesh->vbo, mesh->vao); - mesh->vertices = 4; - float data[8] = { - 0.0f, 0.0f, // bottom left - 0.0f, 1.0f, // top left - 1.0f, 0.0f, // bottom right - 1.0f, 1.0f // top right - }; - glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); - glBindVertexArray(mesh->vao); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); - glEnableVertexAttribArray(0); -}
--- a/src/sprite.c Sat May 10 15:42:56 2025 +0200 +++ b/src/sprite.c Sat May 10 18:51:45 2025 +0200 @@ -32,8 +32,12 @@ #include <GL/glew.h> +#include "ascension/mesh.h" + static void asc_sprite_destroy(AscSceneNode *node) { - ((AscSprite *) node)->texture->refcount--; + AscSprite *sprite = (AscSprite *) node; + asc_mesh_destroy(&sprite->mesh); + sprite->texture->refcount--; } AscSceneNode *asc_sprite_create(struct asc_sprite_create_args args) { @@ -52,6 +56,7 @@ 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, @@ -59,6 +64,9 @@ ); asc_node_update_transform(node); + // initialize mesh + asc_mesh_plane_2d(&sprite->mesh); + return node; } @@ -80,5 +88,5 @@ } // Draw mesh - asc_mesh_draw_triangle_strip(ASC_PRIMITIVE_PLANE); + asc_mesh_draw_triangle_strip(&node->mesh); }
--- a/src/text.c Sat May 10 15:42:56 2025 +0200 +++ b/src/text.c Sat May 10 18:51:45 2025 +0200 @@ -73,6 +73,7 @@ static void asc_text_destroy(AscSceneNode *node) { AscText *text = (AscText*) node; AscSprite *sprite = (AscSprite*) node; + asc_mesh_destroy(&sprite->mesh); asc_texture_destroy(sprite->texture, 1); assert(sprite->texture->refcount == 0); free(sprite->texture); @@ -81,15 +82,18 @@ AscSceneNode *asc_text_create(struct asc_text_create_args args) { AscText *text = calloc(1, sizeof(AscText)); - AscSceneNode *node = (AscSceneNode*) text; + AscSceneNode *node = &text->base.data; + // node properties + asc_scene_node_name(node, args.name); node->render_group = ASC_RENDER_GROUP_SPRITE_BLEND; node->destroy_func = asc_text_destroy; node->update_func = asc_text_update; - - node->flags = args.alignment; node->position = asc_vec3f_new(args.x, args.y, ASC_SCENE_2D_DEPTH_OFFSET); node->scale.depth = 1.f; + + // text properties + node->flags = args.alignment; // use flags variable to save some space text->max_width = args.max_width; text->font = asc_active_font; text->color = asc_context.ink; @@ -99,8 +103,8 @@ text->text = cx_mutstr(strdup(args.text)); } - // initialize - asc_scene_node_name(node, args.name); + // initialize mesh and texture + asc_mesh_plane_2d(&text->base.mesh); text->base.texture = malloc(sizeof(AscTexture)); asc_texture_init_rectangle(text->base.texture, 1); asc_text_update(node);
--- a/test/snake/Makefile Sat May 10 15:42:56 2025 +0200 +++ b/test/snake/Makefile Sat May 10 18:51:45 2025 +0200 @@ -47,8 +47,7 @@ $(BUILD_DIR)/snake.o: snake.c ../../src/ascension/core.h \ ../../src/ascension/error.h ../../src/ascension/context.h \ ../../src/ascension/datatypes.h ../../src/ascension/window.h \ - ../../src/ascension/glcontext.h ../../src/ascension/primitives.h \ - ../../src/ascension/mesh.h ../../src/ascension/shader.h \ + ../../src/ascension/glcontext.h ../../src/ascension/shader.h \ ../../src/ascension/texture.h ../../src/ascension/scene.h \ ../../src/ascension/scene_node.h ../../src/ascension/transform.h \ ../../src/ascension/camera.h ../../src/ascension/input.h \ @@ -56,6 +55,8 @@ ../../src/ascension/ui.h ../../src/ascension/ui/text.h \ ../../src/ascension/ui/font.h ../../src/ascension/ui/../2d/sprite.h \ ../../src/ascension/ui/../2d/../scene_node.h \ + ../../src/ascension/ui/../2d/../mesh.h \ + ../../src/ascension/ui/../2d/../datatypes.h \ ../../src/ascension/ui/../2d/../texture.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $<