From 470dac0e891c1ec59dfe52e77861cf068837976d Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 31 Jul 2024 20:55:37 +0200 Subject: Add mipmap option --- include/mgl/gl.h | 1 + include/mgl/gl_macro.h | 1 + include/mgl/graphics/sprite.h | 2 ++ include/mgl/graphics/texture.h | 2 ++ src/gl.c | 1 + src/graphics/sprite.c | 8 ++++++++ src/graphics/texture.c | 22 ++++++++++++++++++---- 7 files changed, 33 insertions(+), 4 deletions(-) diff --git a/include/mgl/gl.h b/include/mgl/gl.h index 2537d96..c96beea 100644 --- a/include/mgl/gl.h +++ b/include/mgl/gl.h @@ -85,6 +85,7 @@ typedef struct { void (*glXSwapIntervalEXT)(Display * dpy, GLXDrawable drawable, int interval); int (*glXSwapIntervalMESA)(unsigned int interval); int (*glXSwapIntervalSGI)(int interval); + void (*glGenerateMipmap)(unsigned int target); } mgl_gl; int mgl_gl_load(mgl_gl *self); diff --git a/include/mgl/gl_macro.h b/include/mgl/gl_macro.h index 3141f78..cbecf94 100644 --- a/include/mgl/gl_macro.h +++ b/include/mgl/gl_macro.h @@ -46,6 +46,7 @@ #define GL_CLAMP_TO_EDGE 0x812F #define GL_LINEAR 0x2601 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 #define GL_POINTS 0x0000 #define GL_LINES 0x0001 diff --git a/include/mgl/graphics/sprite.h b/include/mgl/graphics/sprite.h index 0193c4c..9e4ebc7 100644 --- a/include/mgl/graphics/sprite.h +++ b/include/mgl/graphics/sprite.h @@ -29,6 +29,8 @@ void mgl_sprite_set_origin(mgl_sprite *self, mgl_vec2f origin); void mgl_sprite_set_size(mgl_sprite *self, mgl_vec2f size); /* This only has an effect if the sprite has a texture set. Scales width in proportion */ void mgl_sprite_set_height(mgl_sprite *self, float height); +/* Texture size multiplied by the sprite scaling */ +mgl_vec2f mgl_sprite_get_size(const mgl_sprite *self); void mgl_sprite_draw(mgl_context *context, mgl_sprite *sprite); #endif /* MGL_SPRITE_H */ diff --git a/include/mgl/graphics/texture.h b/include/mgl/graphics/texture.h index 9524ab1..1f473e2 100644 --- a/include/mgl/graphics/texture.h +++ b/include/mgl/graphics/texture.h @@ -22,11 +22,13 @@ struct mgl_texture { int max_width; int max_height; bool pixel_coordinates; + bool mipmap; }; typedef struct { bool compressed; /* false by default */ bool pixel_coordinates; /* false by default, texture coordinates are normalized */ + bool mipmap; /* false by default, generate mipmaps (available since opengl 3.0) */ } mgl_texture_load_options; int mgl_texture_init(mgl_texture *self); diff --git a/src/gl.c b/src/gl.c index adc7c89..4ac022a 100644 --- a/src/gl.c +++ b/src/gl.c @@ -109,6 +109,7 @@ int mgl_gl_load(mgl_gl *self) { { (void**)&self->glXSwapIntervalEXT, "glXSwapIntervalEXT" }, { (void**)&self->glXSwapIntervalMESA, "glXGetSwapIntervalMESA" }, { (void**)&self->glXSwapIntervalSGI, "glXSwapIntervalSGI" }, + { (void**)&self->glGenerateMipmap, "glGenerateMipmap" }, { NULL, NULL } }; diff --git a/src/graphics/sprite.c b/src/graphics/sprite.c index 95f733b..3110cf9 100644 --- a/src/graphics/sprite.c +++ b/src/graphics/sprite.c @@ -47,6 +47,14 @@ void mgl_sprite_set_height(mgl_sprite *self, float height) { self->scale.y = self->scale.x; } +mgl_vec2f mgl_sprite_get_size(const mgl_sprite *self) { + if(self->texture) { + return (mgl_vec2f){ (float)self->texture->width * self->scale.x, (float)self->texture->height * self->scale.y }; + } else { + return (mgl_vec2f){ 0.0f, 0.0f }; + } +} + /* 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) diff --git a/src/graphics/texture.c b/src/graphics/texture.c index e098dd2..5de3d2b 100644 --- a/src/graphics/texture.c +++ b/src/graphics/texture.c @@ -96,22 +96,30 @@ int mgl_texture_load_from_memory(mgl_texture *self, const unsigned char *data, i if(width > self->max_width || height > self->max_height) return -1; + mgl_context *context = mgl_get_context(); + self->width = width; self->height = height; self->format = mgl_image_format_to_mgl_texture_format(format); - self->pixel_coordinates = load_options ? load_options->pixel_coordinates : false; + self->pixel_coordinates = load_options && load_options->pixel_coordinates; + self->mipmap = load_options && load_options->mipmap && context->gl.glGenerateMipmap; /* TODO: Check if glGenerateMipmap is actually available */ int opengl_texture_format = mgl_texture_format_to_opengl_format(self->format); if(load_options && load_options->compressed) opengl_texture_format = mgl_texture_format_to_compressed_opengl_format(self->format); - mgl_context *context = mgl_get_context(); context->gl.glBindTexture(GL_TEXTURE_2D, self->id); context->gl.glTexImage2D(GL_TEXTURE_2D, 0, opengl_texture_format, self->width, self->height, 0, mgl_texture_format_to_source_opengl_format(self->format), GL_UNSIGNED_BYTE, data); context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + if(self->mipmap) { + context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + context->gl.glGenerateMipmap(GL_TEXTURE_2D); + } else { + context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } context->gl.glBindTexture(GL_TEXTURE_2D, 0); return 0; @@ -125,6 +133,9 @@ int mgl_texture_update(mgl_texture *self, const unsigned char *data, int offset_ context->gl.glBindTexture(GL_TEXTURE_2D, self->id); const mgl_texture_format texture_format = mgl_image_format_to_mgl_texture_format(format); context->gl.glTexSubImage2D(GL_TEXTURE_2D, 0, offset_x, offset_y, width, height, mgl_texture_format_to_source_opengl_format(texture_format), GL_UNSIGNED_BYTE, data); + if(self->mipmap) { + context->gl.glGenerateMipmap(GL_TEXTURE_2D); + } context->gl.glBindTexture(GL_TEXTURE_2D, 0); return 0; } @@ -147,6 +158,9 @@ int mgl_texture_resize(mgl_texture *self, int new_width, int new_height, const m mgl_context *context = mgl_get_context(); context->gl.glBindTexture(GL_TEXTURE_2D, self->id); context->gl.glTexImage2D(GL_TEXTURE_2D, 0, opengl_texture_format, self->width, self->height, 0, mgl_texture_format_to_source_opengl_format(self->format), GL_UNSIGNED_BYTE, NULL); + if(self->mipmap) { + context->gl.glGenerateMipmap(GL_TEXTURE_2D); + } context->gl.glBindTexture(GL_TEXTURE_2D, 0); return 0; } -- cgit v1.2.3