--- a/src/sprite.c Sun Jun 08 14:57:54 2025 +0200 +++ b/src/sprite.c Sun Jun 08 14:58:19 2025 +0200 @@ -29,11 +29,48 @@ #include "ascension/context.h" #include "ascension/glcontext.h" +#include "ascension/error.h" +#include "ascension/mesh.h" +#include "ascension/constants.h" #include <GL/glew.h> -#include "ascension/error.h" -#include "ascension/mesh.h" + +struct asc_sprite_shader_s { + AscShaderProgram program; + int tex; +}; + +static void *asc_sprite_shader_create(bool rect) { + AscShaderCodes codes; + if (asc_shader_load_code_files((AscShaderCodeInfo){ + .files.vtx = "sprite_vtx.glsl", + .files.frag = "sprite_frag.glsl", + .defines.frag = rect ? "#define USE_RECT" : NULL, + }, &codes)) { + asc_error("Loading sprite shader failed."); + return NULL; + } + struct asc_sprite_shader_s *shader = asc_shader_create(codes, sizeof(*shader)); + if (asc_has_error()) { + asc_shader_free_codes(codes); + return NULL; + } + shader->tex = glGetUniformLocation(shader->program.gl_id, "tex"); + asc_shader_free_codes(codes); + + asc_error_catch_all_gl(); + + return shader; +} + +static AscShaderProgram *asc_sprite_shader_rect_create() { + return asc_sprite_shader_create(true); +} + +static AscShaderProgram *asc_sprite_shader_uv_create() { + return asc_sprite_shader_create(false); +} static void asc_sprite_destroy(AscSceneNode *node) { AscSprite *sprite = (AscSprite *) node; @@ -88,7 +125,17 @@ return node; } -void asc_sprite_draw(const AscShaderSprite *shader, const AscSprite *node) { +const AscShaderProgram *asc_sprite_shader_rect(void) { + return asc_shader_lookup_or_create(ASC_SHADER_SPRITE_RECT, asc_sprite_shader_rect_create); +} + +const AscShaderProgram *asc_sprite_shader_uv(void) { + return asc_shader_lookup_or_create(ASC_SHADER_SPRITE_UV, asc_sprite_shader_uv_create); +} + +void asc_sprite_draw(const AscShaderProgram *program, const AscSprite *node) { + asc_ptr_cast(const struct asc_sprite_shader_s, shader, program); + // Upload model matrix glUniformMatrix4fv(shader->program.model, 1, GL_FALSE, node->data.world_transform); @@ -107,23 +154,3 @@ asc_node_update(node); } -int asc_shader_sprite_init(AscShaderSprite *sprite, bool rect) { - AscShaderCodes codes; - if (asc_shader_load_code_files((AscShaderCodeInfo){ - .files.vtx = "sprite_vtx.glsl", - .files.frag = "sprite_frag.glsl", - .defines.frag = rect ? "#define USE_RECT" : NULL, - }, &codes)) { - asc_error("Loading sprite shader failed."); - return 1; - } - sprite->program = asc_shader_program_create(codes); - if (asc_has_error()) { - asc_shader_free_codes(codes); - return 1; - } - sprite->tex = glGetUniformLocation(sprite->program.id, "tex"); - asc_shader_free_codes(codes); - - return asc_error_catch_all_gl(); -}