diff options
-rw-r--r-- | include/mgl/gl.h | 1 | ||||
-rw-r--r-- | include/mgl/gl_macro.h | 2 | ||||
-rw-r--r-- | include/mgl/graphics/texture.h | 9 | ||||
-rw-r--r-- | src/gl.c | 1 | ||||
-rw-r--r-- | src/graphics/texture.c | 38 |
5 files changed, 51 insertions, 0 deletions
diff --git a/include/mgl/gl.h b/include/mgl/gl.h index 3a96241..87a3ccd 100644 --- a/include/mgl/gl.h +++ b/include/mgl/gl.h @@ -60,6 +60,7 @@ typedef struct { void (*glBlendFunc)(unsigned int sfactor, unsigned int dfactor); void (*glGenTextures)(int n, unsigned int *textures); void (*glDeleteTextures)(int n, const unsigned int *textures); + void (*glGetTexLevelParameteriv)(unsigned int target, int level, unsigned int pname, int *params); void (*glTexImage2D)(unsigned int target, int level, int internalFormat, int width, int height, int border, unsigned int format, unsigned int type, const void *pixels); void (*glTexSubImage2D)(unsigned int target, int level, int xoffset, int yoffset, int width, int height, unsigned int format, unsigned int type, const void *pixels); void (*glBindTexture)(unsigned int target, unsigned int texture); diff --git a/include/mgl/gl_macro.h b/include/mgl/gl_macro.h index d6b54f0..ea2b5e4 100644 --- a/include/mgl/gl_macro.h +++ b/include/mgl/gl_macro.h @@ -28,6 +28,8 @@ #define GL_TEXTURE_MIN_FILTER 0x2801 #define GL_UNSIGNED_BYTE 0x1401 #define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 #define GL_ALPHA 0x1906 #define GL_LUMINANCE 0x1909 diff --git a/include/mgl/graphics/texture.h b/include/mgl/graphics/texture.h index 1f473e2..d65adee 100644 --- a/include/mgl/graphics/texture.h +++ b/include/mgl/graphics/texture.h @@ -23,6 +23,7 @@ struct mgl_texture { int max_height; bool pixel_coordinates; bool mipmap; + bool owned; }; typedef struct { @@ -31,13 +32,21 @@ typedef struct { bool mipmap; /* false by default, generate mipmaps (available since opengl 3.0) */ } mgl_texture_load_options; +typedef struct { + bool pixel_coordinates; /* false by default, texture coordinates are normalized */ +} mgl_texture_reference_options; + int mgl_texture_init(mgl_texture *self); +/* |reference_options| can be null, in which case the default options are used */ +int mgl_texture_init_reference_existing_gl_texture(mgl_texture *self, unsigned int texture_id, mgl_texture_format format, const mgl_texture_reference_options *reference_options); + /* |load_options| can be null, in which case the default options are used */ int mgl_texture_load_from_file(mgl_texture *self, const char *filepath, const mgl_texture_load_options *load_options); /* |load_options| can be null, in which case the default options are used */ int mgl_texture_load_from_image(mgl_texture *self, const mgl_image *image, const mgl_texture_load_options *load_options); /* |load_options| can be null, in which case the default options are used */ int mgl_texture_load_from_memory(mgl_texture *self, const unsigned char *data, int width, int height, mgl_image_format format, const mgl_texture_load_options *load_options); + int mgl_texture_update(mgl_texture *self, const unsigned char *data, int offset_x, int offset_y, int width, int height, mgl_image_format format); /* |load_options| can be null, in which case the default options are used */ int mgl_texture_resize(mgl_texture *self, int new_width, int new_height, const mgl_texture_load_options *load_options); @@ -29,6 +29,7 @@ static int mgl_gl_load_gl(mgl_gl *self) { { (void**)&self->glBlendFunc, "glBlendFunc" }, { (void**)&self->glGenTextures, "glGenTextures" }, { (void**)&self->glDeleteTextures, "glDeleteTextures" }, + { (void**)&self->glGetTexLevelParameteriv, "glGetTexLevelParameteriv" }, { (void**)&self->glTexImage2D, "glTexImage2D" }, { (void**)&self->glTexSubImage2D, "glTexSubImage2D" }, { (void**)&self->glBindTexture, "glBindTexture" }, diff --git a/src/graphics/texture.c b/src/graphics/texture.c index 5de3d2b..9a13314 100644 --- a/src/graphics/texture.c +++ b/src/graphics/texture.c @@ -51,6 +51,17 @@ static mgl_texture_format mgl_image_format_to_mgl_texture_format(mgl_image_forma return 0; } +static void gl_get_texture_size(unsigned int texture_id, int *width, int *height) { + *width = 0; + *height = 0; + + mgl_context *context = mgl_get_context(); + context->gl.glBindTexture(GL_TEXTURE_2D, texture_id); + context->gl.glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, width); + context->gl.glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, height); + context->gl.glBindTexture(GL_TEXTURE_2D, 0); +} + int mgl_texture_init(mgl_texture *self) { self->id = 0; self->width = 0; @@ -59,6 +70,8 @@ int mgl_texture_init(mgl_texture *self) { self->max_width = 0; self->max_height = 0; self->pixel_coordinates = false; + self->mipmap = false; + self->owned = true; mgl_context *context = mgl_get_context(); context->gl.glGenTextures(1, &self->id); @@ -75,6 +88,28 @@ int mgl_texture_init(mgl_texture *self) { return 0; } +int mgl_texture_init_reference_existing_gl_texture(mgl_texture *self, unsigned int texture_id, mgl_texture_format format, const mgl_texture_reference_options *reference_options) { + self->id = texture_id; + self->width = 0; + self->height = 0; + self->format = format; + self->max_width = 0; + self->max_height = 0; + self->pixel_coordinates = reference_options && reference_options->pixel_coordinates; + self->mipmap = false; + self->owned = false; + + gl_get_texture_size(self->id, &self->width, &self->height); + + int max_texture_size = 0; + mgl_context *context = mgl_get_context(); + context->gl.glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); + self->max_width = max_texture_size; + self->max_height = max_texture_size; + + return 0; +} + int mgl_texture_load_from_file(mgl_texture *self, const char *filepath, const mgl_texture_load_options *load_options) { mgl_image image; if(mgl_image_load_from_file(&image, filepath) != 0) @@ -199,6 +234,9 @@ const mgl_texture* mgl_texture_current_texture(void) { void mgl_texture_unload(mgl_texture *self) { mgl_context *context = mgl_get_context(); + if(!self->owned) + return; + if(self->id) { context->gl.glDeleteTextures(1, &self->id); self->id = 0; |