From 61c7efc6dd2a036b5d14aa223d06a18cb7d1388e Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 16 Nov 2021 03:54:26 +0100 Subject: Sprite: add rotation and origin --- include/mgl/gl.h | 1 + include/mgl/graphics/sprite.h | 6 +++++- src/gl.c | 1 + src/graphics/sprite.c | 25 +++++++++++++++++++------ tests/main.c | 11 +++++++++-- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/include/mgl/gl.h b/include/mgl/gl.h index 75bc764..7dc1dd7 100644 --- a/include/mgl/gl.h +++ b/include/mgl/gl.h @@ -43,6 +43,7 @@ typedef struct { void (*glLoadIdentity)(void); void (*glLoadMatrixf)(const float *m); void (*glTranslatef)(float x, float y, float z); + void (*glRotatef)(float angle, float x, float y, float z); void (*glGenBuffers)(int n, unsigned int *buffers); void (*glBindBuffer)(unsigned int target, unsigned int buffer); void (*glDeleteBuffers)(int n, const unsigned int *buffers); diff --git a/include/mgl/graphics/sprite.h b/include/mgl/graphics/sprite.h index 03f81ab..64d9c03 100644 --- a/include/mgl/graphics/sprite.h +++ b/include/mgl/graphics/sprite.h @@ -12,15 +12,19 @@ typedef struct { mgl_color color; mgl_vec2f position; mgl_vec2f scale; + mgl_vec2f origin; /* top left by default (0, 0) */ + float rotation; /* in degrees */ } mgl_sprite; /* |texture| may be NULL */ -void mgl_sprite_init(mgl_sprite *self, mgl_texture *texture, float x, float y); +void mgl_sprite_init(mgl_sprite *self, mgl_texture *texture); /* |texture| may be NULL */ void mgl_sprite_set_texture(mgl_sprite *self, mgl_texture *texture); void mgl_sprite_set_position(mgl_sprite *self, mgl_vec2f position); void mgl_sprite_set_color(mgl_sprite *self, mgl_color color); +void mgl_sprite_set_rotation(mgl_sprite *self, float degrees); +void mgl_sprite_set_origin(mgl_sprite *self, mgl_vec2f origin); void mgl_sprite_draw(mgl_context *context, mgl_sprite *sprite); #endif /* MGL_SPRITE_H */ diff --git a/src/gl.c b/src/gl.c index 5999b80..4d8fb58 100644 --- a/src/gl.c +++ b/src/gl.c @@ -57,6 +57,7 @@ int mgl_gl_load(mgl_gl *self) { { &self->glLoadIdentity, "glLoadIdentity" }, { &self->glLoadMatrixf, "glLoadMatrixf" }, { &self->glTranslatef, "glTranslatef" }, + { &self->glRotatef, "glRotatef" }, { &self->glGenBuffers, "glGenBuffers" }, { &self->glBindBuffer, "glBindBuffer" }, { &self->glDeleteBuffers, "glDeleteBuffers" }, diff --git a/src/graphics/sprite.c b/src/graphics/sprite.c index 2aecdd1..df3e902 100644 --- a/src/graphics/sprite.c +++ b/src/graphics/sprite.c @@ -2,11 +2,13 @@ #include "../../include/mgl/graphics/texture.h" #include "../../include/mgl/mgl.h" -void mgl_sprite_init(mgl_sprite *self, mgl_texture *texture, float x, float y) { +void mgl_sprite_init(mgl_sprite *self, mgl_texture *texture) { self->texture = texture; self->color = (mgl_color){ 255, 255, 255, 255 }; - self->position = (mgl_vec2f){ x, y }; + self->position = (mgl_vec2f){ 0.0f, 0.0f }; self->scale = (mgl_vec2f){ 1.0f, 1.0f }; + self->origin = (mgl_vec2f){ 0.0f, 0.0f }; + self->rotation = 0.0f; } void mgl_sprite_set_texture(mgl_sprite *self, mgl_texture *texture) { @@ -21,6 +23,14 @@ void mgl_sprite_set_color(mgl_sprite *self, mgl_color color) { self->color = color; } +void mgl_sprite_set_rotation(mgl_sprite *self, float degrees) { + self->rotation = degrees; +} + +void mgl_sprite_set_origin(mgl_sprite *self, mgl_vec2f origin) { + self->origin = origin; +} + /* TODO: Cache texture bind to not bind texture if its already bound and do not bind texture 0 */ void mgl_sprite_draw(mgl_context *context, mgl_sprite *sprite) { if(!sprite->texture) @@ -35,18 +45,21 @@ void mgl_sprite_draw(mgl_context *context, mgl_sprite *sprite) { context->gl.glColor4ub(sprite->color.r, sprite->color.g, sprite->color.b, sprite->color.a); mgl_texture_use(sprite->texture); + context->gl.glTranslatef(sprite->position.x, sprite->position.y, 0.0f); + context->gl.glRotatef(sprite->rotation, 0.0f, 0.0f, 1.0f); context->gl.glBegin(GL_QUADS); context->gl.glTexCoord2f(0.0f, 0.0f); - context->gl.glVertex3f(sprite->position.x, sprite->position.y, 0.0f); + context->gl.glVertex3f(-sprite->origin.x * sprite->scale.x, -sprite->origin.y * sprite->scale.y, 0.0f); context->gl.glTexCoord2f(texture_right, 0.0f); - context->gl.glVertex3f(sprite->position.x + sprite->texture->width * sprite->scale.x, sprite->position.y, 0.0f); + context->gl.glVertex3f((sprite->texture->width - sprite->origin.x) * sprite->scale.x, -sprite->origin.y * sprite->scale.y, 0.0f); context->gl.glTexCoord2f(texture_right, texture_bottom); - context->gl.glVertex3f(sprite->position.x + sprite->texture->width * sprite->scale.x, sprite->position.y + sprite->texture->height * sprite->scale.y, 0.0f); + context->gl.glVertex3f((sprite->texture->width - sprite->origin.x) * sprite->scale.x, (sprite->texture->height - sprite->origin.y) * sprite->scale.y, 0.0f); context->gl.glTexCoord2f(0.0f, texture_bottom); - context->gl.glVertex3f(sprite->position.x, sprite->position.y + sprite->texture->height * sprite->scale.y, 0.0f); + context->gl.glVertex3f(-sprite->origin.x * sprite->scale.x, (sprite->texture->height - sprite->origin.y) * sprite->scale.y, 0.0f); context->gl.glEnd(); mgl_texture_use(NULL); + context->gl.glLoadIdentity(); /* TODO: Remove, but what about glRotatef above */ } diff --git a/tests/main.c b/tests/main.c index 3dc8c98..f76f384 100644 --- a/tests/main.c +++ b/tests/main.c @@ -34,9 +34,16 @@ static void draw(mgl_window *window, void *userdata) { mgl_shader_program_set_uniform_vec2f(u->shader_program, "resolution", (mgl_vec2f){ u->texture->width, u->texture->height }); + static float rot = 0.0f; + rot += 5.0f; + mgl_sprite sprite; - mgl_sprite_init(&sprite, u->texture, 100.0f - 10.0f, 0.0f); + mgl_sprite_init(&sprite, u->texture); + mgl_sprite_set_position(&sprite, (mgl_vec2f){ 100.0f - 10.0f + u->texture->width * 0.5f * 2.0f, u->texture->height * 0.5f * 2.0f }); mgl_sprite_set_color(&sprite, (mgl_color){255, 255, 255, 128}); + mgl_sprite_set_rotation(&sprite, rot); + mgl_sprite_set_origin(&sprite, (mgl_vec2f){ u->texture->width * 0.5f, u->texture->height * 0.5f }); + sprite.scale = (mgl_vec2f){ 2.0f, 2.0f }; mgl_shader_program_use(u->shader_program); mgl_sprite_draw(context, &sprite); mgl_shader_program_use(NULL); @@ -213,7 +220,7 @@ int main(int argc, char **argv) { if(mgl_texture_init(&texture) != 0) return 1; - if(mgl_texture_load_from_file(&texture, "tests/X11.jpg", &(mgl_texture_load_options){ false, true }) != 0) + if(mgl_texture_load_from_file(&texture, "tests/X11.jpg", &(mgl_texture_load_options){ false, false }) != 0) return 1; if(mgl_mapped_file_load("/usr/share/fonts/noto/NotoSans-Regular.ttf", &font_file, &(mgl_memory_mapped_file_load_options){ .readable = true, .writable = false }) != 0) -- cgit v1.2.3