aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-07-31 20:55:37 +0200
committerdec05eba <dec05eba@protonmail.com>2024-07-31 20:55:42 +0200
commit470dac0e891c1ec59dfe52e77861cf068837976d (patch)
treeca26672c104ef2b4bfb9a1884616e52b2ec7c35e
parentf3e5b69d33f47dece7e3bc8c133f65ad7169cc18 (diff)
Add mipmap option
-rw-r--r--include/mgl/gl.h1
-rw-r--r--include/mgl/gl_macro.h1
-rw-r--r--include/mgl/graphics/sprite.h2
-rw-r--r--include/mgl/graphics/texture.h2
-rw-r--r--src/gl.c1
-rw-r--r--src/graphics/sprite.c8
-rw-r--r--src/graphics/texture.c22
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;
}