aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-10-24 04:52:30 +0200
committerdec05eba <dec05eba@protonmail.com>2021-10-24 04:52:30 +0200
commit115630b520668304af1ccd3eb0b13c06e17ecccc (patch)
treee3949bd4fe36ae3b43c11d4e9ecd0bf523a6e910
parent898b8c95f1f904307c02e978b57301cf1cb0560f (diff)
Add function to load image from memory, initialize window from an existing window, allow creating text without font/string
-rw-r--r--include/mgl/graphics/image.h1
-rw-r--r--include/mgl/graphics/sprite.h2
-rw-r--r--include/mgl/graphics/text.h13
-rw-r--r--include/mgl/window/window.h1
-rw-r--r--src/graphics/image.c19
-rw-r--r--src/graphics/text.c9
-rw-r--r--src/window/window.c41
7 files changed, 68 insertions, 18 deletions
diff --git a/include/mgl/graphics/image.h b/include/mgl/graphics/image.h
index b10a028..40625bb 100644
--- a/include/mgl/graphics/image.h
+++ b/include/mgl/graphics/image.h
@@ -21,6 +21,7 @@ struct mgl_image {
};
int mgl_image_load_from_file(mgl_image *self, const char *filepath);
+int mgl_image_load_from_memory(mgl_image *self, const unsigned char *data, size_t size);
void mgl_image_unload(mgl_image *self);
size_t mgl_image_get_size(mgl_image *self);
diff --git a/include/mgl/graphics/sprite.h b/include/mgl/graphics/sprite.h
index 8c84153..03f81ab 100644
--- a/include/mgl/graphics/sprite.h
+++ b/include/mgl/graphics/sprite.h
@@ -8,7 +8,7 @@ typedef struct mgl_context mgl_context;
typedef struct mgl_texture mgl_texture;
typedef struct {
- mgl_texture *texture;
+ mgl_texture *texture; /* nullable */
mgl_color color;
mgl_vec2f position;
mgl_vec2f scale;
diff --git a/include/mgl/graphics/text.h b/include/mgl/graphics/text.h
index 33c75d0..2c2eeaf 100644
--- a/include/mgl/graphics/text.h
+++ b/include/mgl/graphics/text.h
@@ -8,18 +8,23 @@ typedef struct mgl_font mgl_font;
typedef struct mgl_context mgl_context;
typedef struct {
- mgl_font *font;
- const char *text;
+ mgl_font *font; /* nullable */
+ const char *text; /* nullable */
mgl_color color;
mgl_vec2f position;
} mgl_text;
-/* Note: keeps a reference to |text|. |text| needs to be valid as long as |self| is used. */
+/*
+ Note: keeps a reference to |text|. |text| needs to be valid as long as |self| is used.
+ |font| and |text| may be NULL.
+*/
int mgl_text_init(mgl_text *self, mgl_font *font, const char *text, float x, float y);
void mgl_text_deinit(mgl_text *self);
-/* Note: keeps a reference to |text|. |text| needs to be valid as long as |self| is used. */
+/* Note: keeps a reference to |text|. |text| needs to be valid as long as |self| is used. |text| may be NULL. */
void mgl_text_set_string(mgl_text *self, const char *str);
+/* |font| may be NULL */
+void mgl_text_set_font(mgl_text *self, mgl_font *font);
void mgl_text_set_position(mgl_text *self, mgl_vec2f position);
void mgl_text_set_color(mgl_text *self, mgl_color color);
void mgl_text_draw(mgl_context *context, mgl_text *text);
diff --git a/include/mgl/window/window.h b/include/mgl/window/window.h
index c1517da..c1542b4 100644
--- a/include/mgl/window/window.h
+++ b/include/mgl/window/window.h
@@ -20,6 +20,7 @@ struct mgl_window {
int mgl_window_create(mgl_window *self, const char *title, int width, int height);
/* if |parent_window| is 0 then the root window is used */
int mgl_window_create_with_params(mgl_window *self, const char *title, int width, int height, mgl_window_handle parent_window);
+int mgl_window_init_from_existing_window(mgl_window *self, mgl_window_handle existing_window);
void mgl_window_deinit(mgl_window *self);
void mgl_window_clear(mgl_window *self, mgl_color color);
diff --git a/src/graphics/image.c b/src/graphics/image.c
index 430f03a..593a3d2 100644
--- a/src/graphics/image.c
+++ b/src/graphics/image.c
@@ -52,6 +52,25 @@ int mgl_image_load_from_file(mgl_image *self, const char *filepath) {
return 0;
}
+/* TODO: Ensure texture is power of 2 if the hardware doesn't support non power of two textures */
+/* TODO: Verify if source format should always be 4 components (RGBA) because apparently if its another format then opengl will internally convert it to RGBA */
+int mgl_image_load_from_memory(mgl_image *self, const unsigned char *data, size_t size) {
+ self->data = NULL;
+ self->width = 0;
+ self->height = 0;
+
+ int format;
+ self->data = stbi_load_from_memory(data, size, &self->width, &self->height, &format, 0);
+ if(!self->data) {
+ fprintf(stderr, "Error: failed to load image from memory, error: %s\n", stbi_failure_reason());
+ mgl_image_unload(self);
+ return -1;
+ }
+ self->format = stbi_format_to_mgl_image_format(format);
+
+ return 0;
+}
+
void mgl_image_unload(mgl_image *self) {
if(self->data) {
stbi_image_free(self->data);
diff --git a/src/graphics/text.c b/src/graphics/text.c
index e7b31a0..76fd852 100644
--- a/src/graphics/text.c
+++ b/src/graphics/text.c
@@ -18,6 +18,10 @@ void mgl_text_set_string(mgl_text *self, const char *str) {
self->text = str;
}
+void mgl_text_set_font(mgl_text *self, mgl_font *font) {
+ self->font = font;
+}
+
void mgl_text_set_position(mgl_text *self, mgl_vec2f position) {
self->position = position;
}
@@ -43,10 +47,11 @@ static void mgl_text_draw_glyph(mgl_context *context, mgl_font_glyph *glyph, mgl
/* TODO: Use opengl buffer object instead */
/* TODO: Cache texture bind to not bind texture if its already bound and do not bind texture 0 */
void mgl_text_draw(mgl_context *context, mgl_text *text) {
- const char *str = text->text;
- if(!str)
+ if(!text->text || !text->font)
return;
+ const char *str = text->text;
+
mgl_font_glyph glyph;
mgl_vec2f position = text->position;
position.y += text->font->character_size;
diff --git a/src/window/window.c b/src/window/window.c
index 691a647..2e9a1ba 100644
--- a/src/window/window.c
+++ b/src/window/window.c
@@ -41,7 +41,7 @@ int mgl_window_create(mgl_window *self, const char *title, int width, int height
return mgl_window_create_with_params(self, title, width, height, 0);
}
-int mgl_window_create_with_params(mgl_window *self, const char *title, int width, int height, mgl_window_handle parent_window) {
+static int mgl_window_init(mgl_window *self, const char *title, int width, int height, mgl_window_handle parent_window, Window existing_window) {
self->window = 0;
mgl_context *context = mgl_get_context();
@@ -64,18 +64,29 @@ int mgl_window_create_with_params(mgl_window *self, const char *title, int width
StructureNotifyMask;
window_attr.bit_gravity = NorthWestGravity;
- self->window = XCreateWindow(context->connection, parent_window, 0, 0, width, height, 0,
- ((XVisualInfo*)context->visual_info)->depth, InputOutput, ((XVisualInfo*)context->visual_info)->visual,
- CWColormap | CWEventMask | CWBitGravity, &window_attr);
- XFreeColormap(context->connection, color_map);
- if(!self->window) {
- fprintf(stderr, "XCreateWindow failed\n");
- mgl_window_deinit(self);
- return -1;
+ if(existing_window) {
+ if(!XChangeWindowAttributes(context->connection, existing_window, CWColormap | CWEventMask | CWBitGravity, &window_attr)) {
+ fprintf(stderr, "XChangeWindowAttributes failed\n");
+ XFreeColormap(context->connection, color_map);
+ return -1;
+ }
+ XFreeColormap(context->connection, color_map);
+ self->window = existing_window;
+ } else {
+ self->window = XCreateWindow(context->connection, parent_window, 0, 0, width, height, 0,
+ ((XVisualInfo*)context->visual_info)->depth, InputOutput, ((XVisualInfo*)context->visual_info)->visual,
+ CWColormap | CWEventMask | CWBitGravity, &window_attr);
+ XFreeColormap(context->connection, color_map);
+ if(!self->window) {
+ fprintf(stderr, "XCreateWindow failed\n");
+ mgl_window_deinit(self);
+ return -1;
+ }
+
+ XStoreName(context->connection, self->window, title);
+ XMapWindow(context->connection, self->window);
}
- XStoreName(context->connection, self->window, title);
- XMapWindow(context->connection, self->window);
XFlush(context->connection);
/* TODO: Switch current when rendering to another window, and set current to NULL when destroying the currently selected context */
@@ -102,6 +113,14 @@ int mgl_window_create_with_params(mgl_window *self, const char *title, int width
return 0;
}
+int mgl_window_create_with_params(mgl_window *self, const char *title, int width, int height, mgl_window_handle parent_window) {
+ return mgl_window_init(self, title, width, height, parent_window, None);
+}
+
+int mgl_window_init_from_existing_window(mgl_window *self, mgl_window_handle existing_window) {
+ return mgl_window_init(self, "", 0, 0, 0, existing_window);
+}
+
void mgl_window_deinit(mgl_window *self) {
mgl_context *context = mgl_get_context();
if(self->window) {