aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-08-19 20:16:34 +0200
committerdec05eba <dec05eba@protonmail.com>2024-08-19 20:16:34 +0200
commit8731a00681a2cf99965203849bd7ba8f6c09df9a (patch)
tree2f7a3db3ec862e50c9e6e9154e575cc3c88bd293
parentf1ede6cfa5cc2af2e7f93e29f2311e9ece7f41c4 (diff)
Add mgl_texture_init_reference_existing_gl_texture to easily create a texture and then a sprite from an existing opengl texture
-rw-r--r--include/mgl/gl.h1
-rw-r--r--include/mgl/gl_macro.h2
-rw-r--r--include/mgl/graphics/texture.h9
-rw-r--r--src/gl.c1
-rw-r--r--src/graphics/texture.c38
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);
diff --git a/src/gl.c b/src/gl.c
index 7c9a6bc..bb2e90b 100644
--- a/src/gl.c
+++ b/src/gl.c
@@ -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;