From 9da3c2188060dc982412d7a6e1cd2051b9ddb6a6 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 19 Oct 2021 22:12:52 +0200 Subject: Change from callback to window poll --- include/mgl/graphics/font.h | 4 +- include/mgl/graphics/image.h | 28 +++++++++++ include/mgl/graphics/texture.h | 15 +++--- include/mgl/window/event.h | 10 ++++ include/mgl/window/window.h | 23 ++++----- src/graphics/font.c | 12 ++--- src/graphics/image.c | 67 +++++++++++++++++++++++++++ src/graphics/text.c | 4 +- src/graphics/texture.c | 103 ++++++++++++++++------------------------- src/window/window.c | 54 ++++++++------------- tests/main.c | 17 ++++--- 11 files changed, 206 insertions(+), 131 deletions(-) create mode 100644 include/mgl/graphics/image.h create mode 100644 include/mgl/window/event.h create mode 100644 src/graphics/image.c diff --git a/include/mgl/graphics/font.h b/include/mgl/graphics/font.h index 470662a..6aa9188 100644 --- a/include/mgl/graphics/font.h +++ b/include/mgl/graphics/font.h @@ -24,12 +24,12 @@ typedef struct { struct mgl_font { mgl_texture texture; mgl_font_atlas font_atlas; - unsigned int size; + unsigned int character_size; void *packed_chars; uint32_t num_packed_chars; }; -int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int font_size); +int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int character_size); void mgl_font_unload(mgl_font *self); int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph); diff --git a/include/mgl/graphics/image.h b/include/mgl/graphics/image.h new file mode 100644 index 0000000..b10a028 --- /dev/null +++ b/include/mgl/graphics/image.h @@ -0,0 +1,28 @@ +#ifndef MGL_IMAGE_H +#define MGL_IMAGE_H + +#include + +typedef struct mgl_image mgl_image; + +typedef enum { + MGL_IMAGE_FORMAT_ALPHA, + MGL_IMAGE_FORMAT_GRAY, + MGL_IMAGE_FORMAT_GRAY_ALPHA, + MGL_IMAGE_FORMAT_RGB, + MGL_IMAGE_FORMAT_RGBA +} mgl_image_format; + +struct mgl_image { + unsigned char *data; + int width; + int height; + mgl_image_format format; +}; + +int mgl_image_load_from_file(mgl_image *self, const char *filepath); +void mgl_image_unload(mgl_image *self); + +size_t mgl_image_get_size(mgl_image *self); + +#endif /* MGL_IMAGE_H */ diff --git a/include/mgl/graphics/texture.h b/include/mgl/graphics/texture.h index e6fc97b..3aec07d 100644 --- a/include/mgl/graphics/texture.h +++ b/include/mgl/graphics/texture.h @@ -1,16 +1,17 @@ #ifndef MGL_TEXTURE_H #define MGL_TEXTURE_H +#include "image.h" #include typedef struct mgl_texture mgl_texture; typedef enum { - MGL_TEXTURE_ALPHA, - MGL_TEXTURE_GRAY, - MGL_TEXTURE_GRAY_ALPHA, - MGL_TEXTURE_RGB, - MGL_TEXTURE_RGBA + MGL_TEXTURE_FORMAT_ALPHA, + MGL_TEXTURE_FORMAT_GRAY, + MGL_TEXTURE_FORMAT_GRAY_ALPHA, + MGL_TEXTURE_FORMAT_RGB, + MGL_TEXTURE_FORMAT_RGBA } mgl_texture_format; struct mgl_texture { @@ -27,7 +28,9 @@ typedef struct { /* |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, 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_texture_format format, mgl_texture_load_options *load_options); +int mgl_texture_load_from_image(mgl_texture *self, mgl_image *image, 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, mgl_texture_load_options *load_options); void mgl_texture_unload(mgl_texture *self); #endif /* MGL_TEXTURE_H */ diff --git a/include/mgl/window/event.h b/include/mgl/window/event.h new file mode 100644 index 0000000..2aea478 --- /dev/null +++ b/include/mgl/window/event.h @@ -0,0 +1,10 @@ +#ifndef MGL_EVENT_H +#define MGL_EVENT_H + +typedef struct mgl_event mgl_event; + +struct mgl_event { + int type; +}; + +#endif /* MGL_EVENT_H */ diff --git a/include/mgl/window/window.h b/include/mgl/window/window.h index 5232260..d66fa71 100644 --- a/include/mgl/window/window.h +++ b/include/mgl/window/window.h @@ -1,28 +1,29 @@ #ifndef MGL_WINDOW_H #define MGL_WINDOW_H +#include "../graphics/color.h" #include "../system/vec.h" +#include -typedef struct mgl_window mgl_window; +typedef struct mgl_event mgl_event; +/* x11 window handle. TODO: Add others when wayland, etc is added */ +typedef unsigned long mgl_window_handle; -typedef struct { - void *userdata; - void (*draw)(mgl_window *window, void *userdata); -} mgl_window_callback; +typedef struct mgl_window mgl_window; struct mgl_window { - unsigned long window; - mgl_window_callback callback; + mgl_window_handle window; mgl_vec2i size; mgl_vec2i cursor_position; }; -int mgl_window_create(mgl_window *self, const char *title, int width, int height, mgl_window_callback *callback); +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, unsigned long parent_window, mgl_window_callback *callback); +int mgl_window_create_with_params(mgl_window *self, const char *title, int width, int height, mgl_window_handle parent_window); void mgl_window_deinit(mgl_window *self); -void mgl_window_events_poll(mgl_window *self); -void mgl_window_draw(mgl_window *self); +void mgl_window_clear(mgl_window *self, mgl_color color); +bool mgl_window_events_poll(mgl_window *self, mgl_event *event); +void mgl_window_display(mgl_window *self); #endif /* MGL_WINDOW_H */ diff --git a/src/graphics/font.c b/src/graphics/font.c index 20d9dfa..f55144a 100644 --- a/src/graphics/font.c +++ b/src/graphics/font.c @@ -10,14 +10,14 @@ /* TODO: Test and fix .tcc files */ -int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int font_size) { +int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int character_size) { self->texture.id = 0; self->font_atlas.atlas = NULL; self->font_atlas.width = 0; self->font_atlas.height = 0; - self->size = font_size; + self->character_size = character_size; self->packed_chars = NULL; self->num_packed_chars = 0; @@ -47,8 +47,8 @@ int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int f /* TODO: Optimize */ /* Find optimal size for atlas, starting from small to large */ for(int i = 0; i < 4; ++i) { - self->font_atlas.width = (8 + (8 * i)) * self->size; - self->font_atlas.height = (8 + (8 * i)) * self->size; + self->font_atlas.width = (8 + (8 * i)) * self->character_size; + self->font_atlas.height = (8 + (8 * i)) * self->character_size; unsigned char *new_atlas = realloc(self->font_atlas.atlas, self->font_atlas.width * self->font_atlas.height); if(!new_atlas) { fprintf(stderr, "Error: failed to load font %s, error: out of memory\n", filepath); @@ -67,7 +67,7 @@ int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int f return -1; } - if(!stbtt_PackFontRange(&pc, filedata.data, 0, self->size, 0, self->num_packed_chars, self->packed_chars)) { + if(!stbtt_PackFontRange(&pc, filedata.data, 0, self->character_size, 0, self->num_packed_chars, self->packed_chars)) { stbtt_PackEnd(&pc); continue; } @@ -84,7 +84,7 @@ int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int f return -1; } - if(mgl_texture_load_from_memory(&self->texture, self->font_atlas.atlas, self->font_atlas.width, self->font_atlas.height, MGL_TEXTURE_ALPHA, NULL) != 0) { + if(mgl_texture_load_from_memory(&self->texture, self->font_atlas.atlas, self->font_atlas.width, self->font_atlas.height, MGL_IMAGE_FORMAT_ALPHA, NULL) != 0) { fprintf(stderr, "Error: failed to load font %s, error: mgl_texture_load_from_memory failed\n", filepath); mgl_filedata_free(&filedata); mgl_font_unload(self); diff --git a/src/graphics/image.c b/src/graphics/image.c new file mode 100644 index 0000000..430f03a --- /dev/null +++ b/src/graphics/image.c @@ -0,0 +1,67 @@ +#include "../../include/mgl/graphics/image.h" + +#define STBI_NO_PSD +#define STBI_NO_TGA +#define STBI_NO_HDR +#define STBI_NO_PIC +#define STBI_NO_PNM +#define STB_IMAGE_IMPLEMENTATION +#include "../../external/stb_image.h" + +static mgl_image_format stbi_format_to_mgl_image_format(int stbi_format) { + switch(stbi_format) { + case STBI_grey: + return MGL_IMAGE_FORMAT_GRAY; + case STBI_grey_alpha: + return MGL_IMAGE_FORMAT_GRAY_ALPHA; + case STBI_rgb: + return MGL_IMAGE_FORMAT_RGB; + case STBI_rgb_alpha: + return MGL_IMAGE_FORMAT_RGBA; + } + return 0; +} + +static size_t mgl_image_format_num_channels(mgl_image_format image_format) { + switch(image_format) { + case MGL_IMAGE_FORMAT_ALPHA: return 1; + case MGL_IMAGE_FORMAT_GRAY: return 1; + case MGL_IMAGE_FORMAT_GRAY_ALPHA: return 2; + case MGL_IMAGE_FORMAT_RGB: return 3; + case MGL_IMAGE_FORMAT_RGBA: return 4; + } + 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_file(mgl_image *self, const char *filepath) { + self->data = NULL; + self->width = 0; + self->height = 0; + + int format; + self->data = stbi_load(filepath, &self->width, &self->height, &format, 0); + if(!self->data) { + fprintf(stderr, "Error: failed to load image %s, error: %s\n", filepath, 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); + self->data = NULL; + } + self->width = 0; + self->height = 0; + self->format = 0; +} + +size_t mgl_image_get_size(mgl_image *self) { + return (size_t)self->width * (size_t)self->height * mgl_image_format_num_channels(self->format); +} diff --git a/src/graphics/text.c b/src/graphics/text.c index 0aa33cf..7f90216 100644 --- a/src/graphics/text.c +++ b/src/graphics/text.c @@ -42,7 +42,7 @@ void mgl_text_draw(mgl_context *context, mgl_text *text) { const char *str = text->text; mgl_font_glyph glyph; mgl_vec2f position = text->position; - position.y += text->font->size; + position.y += text->font->character_size; context->gl.glColor4ub(text->color.r, text->color.g, text->color.b, text->color.a); context->gl.glBindTexture(GL_TEXTURE_2D, text->font->texture.id); @@ -64,7 +64,7 @@ void mgl_text_draw(mgl_context *context, mgl_text *text) { } } else if(c == '\n') { position.x = text->position.x; - position.y += text->font->size; + position.y += text->font->character_size; } ++str; } diff --git a/src/graphics/texture.c b/src/graphics/texture.c index 4c7f68c..1427e6b 100644 --- a/src/graphics/texture.c +++ b/src/graphics/texture.c @@ -1,108 +1,85 @@ #include "../../include/mgl/graphics/texture.h" +#include "../../include/mgl/graphics/image.h" #include "../../include/mgl/mgl.h" - -#define STBI_NO_PSD -#define STBI_NO_TGA -#define STBI_NO_HDR -#define STBI_NO_PIC -#define STBI_NO_PNM -#define STB_IMAGE_IMPLEMENTATION -#include "../../external/stb_image.h" +#include /* TODO: Check for glTexImage2D failure */ static int mgl_texture_format_to_opengl_format(mgl_texture_format format) { switch(format) { - case MGL_TEXTURE_ALPHA: return GL_ALPHA8; - case MGL_TEXTURE_GRAY: return GL_LUMINANCE8; - case MGL_TEXTURE_GRAY_ALPHA: return GL_LUMINANCE8_ALPHA8; - case MGL_TEXTURE_RGB: return GL_RGB8; - case MGL_TEXTURE_RGBA: return GL_RGBA8; + case MGL_TEXTURE_FORMAT_ALPHA: return GL_ALPHA8; + case MGL_TEXTURE_FORMAT_GRAY: return GL_LUMINANCE8; + case MGL_TEXTURE_FORMAT_GRAY_ALPHA: return GL_LUMINANCE8_ALPHA8; + case MGL_TEXTURE_FORMAT_RGB: return GL_RGB8; + case MGL_TEXTURE_FORMAT_RGBA: return GL_RGBA8; } return 0; } static int mgl_texture_format_to_compressed_opengl_format(mgl_texture_format format) { switch(format) { - case MGL_TEXTURE_ALPHA: return GL_ALPHA8; - case MGL_TEXTURE_GRAY: return GL_LUMINANCE8; - case MGL_TEXTURE_GRAY_ALPHA: return GL_LUMINANCE8_ALPHA8; - case MGL_TEXTURE_RGB: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - case MGL_TEXTURE_RGBA: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + case MGL_TEXTURE_FORMAT_ALPHA: return GL_ALPHA8; + case MGL_TEXTURE_FORMAT_GRAY: return GL_LUMINANCE8; + case MGL_TEXTURE_FORMAT_GRAY_ALPHA: return GL_LUMINANCE8_ALPHA8; + case MGL_TEXTURE_FORMAT_RGB: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case MGL_TEXTURE_FORMAT_RGBA: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; } return 0; } static int mgl_texture_format_to_source_opengl_format(mgl_texture_format format) { switch(format) { - case MGL_TEXTURE_ALPHA: return GL_ALPHA; - case MGL_TEXTURE_GRAY: return GL_LUMINANCE8; - case MGL_TEXTURE_GRAY_ALPHA: return GL_LUMINANCE8_ALPHA8; - case MGL_TEXTURE_RGB: return GL_RGB; - case MGL_TEXTURE_RGBA: return GL_RGBA; + case MGL_TEXTURE_FORMAT_ALPHA: return GL_ALPHA; + case MGL_TEXTURE_FORMAT_GRAY: return GL_LUMINANCE8; + case MGL_TEXTURE_FORMAT_GRAY_ALPHA: return GL_LUMINANCE8_ALPHA8; + case MGL_TEXTURE_FORMAT_RGB: return GL_RGB; + case MGL_TEXTURE_FORMAT_RGBA: return GL_RGBA; } return 0; } -static mgl_texture_format stbi_format_to_mgl_texture_format(int stbi_format) { - switch(stbi_format) { - case STBI_grey: - return MGL_TEXTURE_GRAY; - case STBI_grey_alpha: - return MGL_TEXTURE_GRAY_ALPHA; - case STBI_rgb: - return MGL_TEXTURE_RGB; - case STBI_rgb_alpha: - return MGL_TEXTURE_RGBA; +static mgl_texture_format mgl_image_format_to_mgl_texture_format(mgl_image_format image_format) { + switch(image_format) { + case MGL_IMAGE_FORMAT_ALPHA: return MGL_TEXTURE_FORMAT_ALPHA; + case MGL_IMAGE_FORMAT_GRAY: return MGL_TEXTURE_FORMAT_GRAY; + case MGL_IMAGE_FORMAT_GRAY_ALPHA: return MGL_TEXTURE_FORMAT_GRAY_ALPHA; + case MGL_IMAGE_FORMAT_RGB: return MGL_TEXTURE_FORMAT_RGB; + case MGL_IMAGE_FORMAT_RGBA: return MGL_TEXTURE_FORMAT_RGBA; } 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_texture_load_from_file(mgl_texture *self, const char *filepath, mgl_texture_load_options *load_options) { self->id = 0; + self->width = 0; + self->height = 0; - int format; - stbi_uc *image_data = stbi_load(filepath, &self->width, &self->height, &format, 0); - if(!image_data) { - fprintf(stderr, "Error: failed to load image %s, error: %s\n", filepath, stbi_failure_reason()); + mgl_image image; + if(mgl_image_load_from_file(&image, filepath) != 0) return -1; - } - self->format = stbi_format_to_mgl_texture_format(format); - - mgl_context *context = mgl_get_context(); - context->gl.glGenTextures(1, &self->id); - if(self->id == 0) { - fprintf(stderr, "Error: failed to load image %s", filepath); - stbi_image_free(image_data); - return -1; - } - - const int opengl_texture_format = load_options && load_options->compressed ? mgl_texture_format_to_compressed_opengl_format(self->format) : mgl_texture_format_to_opengl_format(self->format); - 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, image_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); - context->gl.glBindTexture(GL_TEXTURE_2D, 0); + int result = mgl_texture_load_from_image(self, &image, load_options); + mgl_image_unload(&image); + return result; +} - stbi_image_free(image_data); - return 0; +int mgl_texture_load_from_image(mgl_texture *self, mgl_image *image, mgl_texture_load_options *load_options) { + return mgl_texture_load_from_memory(self, image->data, image->width, image->height, image->format, load_options); } -int mgl_texture_load_from_memory(mgl_texture *self, const unsigned char *data, int width, int height, mgl_texture_format format, mgl_texture_load_options *load_options) { +int mgl_texture_load_from_memory(mgl_texture *self, const unsigned char *data, int width, int height, mgl_image_format format, mgl_texture_load_options *load_options) { self->id = 0; self->width = width; self->height = height; - self->format = format; + self->format = mgl_image_format_to_mgl_texture_format(format); mgl_context *context = mgl_get_context(); context->gl.glGenTextures(1, &self->id); - if(self->id == 0) + if(self->id == 0) { + fprintf(stderr, "Error: failed to load image from memory (glGenTextures failed)\n"); + mgl_texture_unload(self); return -1; + } const int opengl_texture_format = load_options && load_options->compressed ? mgl_texture_format_to_compressed_opengl_format(self->format) : mgl_texture_format_to_opengl_format(self->format); diff --git a/src/window/window.c b/src/window/window.c index c155687..d81f98e 100644 --- a/src/window/window.c +++ b/src/window/window.c @@ -37,13 +37,12 @@ static void mgl_window_on_resize(mgl_window *self, int width, int height) { context->gl.glOrtho(0.0, width, height, 0.0, -1.0, 1.0); } -int mgl_window_create(mgl_window *self, const char *title, int width, int height, mgl_window_callback *callback) { - return mgl_window_create_with_params(self, title, width, height, 0, callback); +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, unsigned long parent_window, mgl_window_callback *callback) { +int mgl_window_create_with_params(mgl_window *self, const char *title, int width, int height, mgl_window_handle parent_window) { self->window = 0; - self->callback = *callback; mgl_context *context = mgl_get_context(); @@ -127,40 +126,27 @@ static void mgl_window_on_receive_event(mgl_window *self, XEvent *xev) { } } -void mgl_window_events_poll(mgl_window *self) { +void mgl_window_clear(mgl_window *self, mgl_color color) { + mgl_context *context = mgl_get_context(); + context->gl.glClear(GL_COLOR_BUFFER_BIT); + context->gl.glClearColor((float)color.r / 255.0f, (float)color.g / 255.0f, (float)color.b / 255.0f, (float)color.a / 255.0f); +} + +bool mgl_window_events_poll(mgl_window *self, mgl_event *event) { + /* TODO: Use |event| */ + Display *display = mgl_get_context()->connection; - const int x11_fd = ConnectionNumber(display); - - fd_set in_fds; - FD_ZERO(&in_fds); /* TODO: Optimize */ - FD_SET(x11_fd, &in_fds); - - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - /*tv.tv_sec = timeout_ms / 1000; - tv.tv_usec = (timeout_ms * 1000) - (tv.tv_sec * 1000 * 1000);*/ - - /* TODO: Is this needed when using XPending? */ - /*const int num_ready_fds = select(1 + x11_fd, &in_fds, NULL, NULL, &tv);*/ - const int num_ready_fds = 1; - if(num_ready_fds > 0) { - XEvent xev; - while(self->window && XPending(display)) { - XNextEvent(display, &xev); - mgl_window_on_receive_event(self, &xev); - } - } else if(num_ready_fds == -1 && errno != EINTR) { - /* TODO: */ - fprintf(stderr, "Disconnected!\n"); + if(XPending(display)) { + XEvent xev; /* TODO: Move to window struct */ + XNextEvent(display, &xev); + mgl_window_on_receive_event(self, &xev); + return true; + } else { + return false; } } -void mgl_window_draw(mgl_window *self) { +void mgl_window_display(mgl_window *self) { mgl_context *context = mgl_get_context(); - context->gl.glClear(GL_COLOR_BUFFER_BIT); - context->gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - if(self->callback.draw) - self->callback.draw(self, self->callback.userdata); context->gl.glXSwapBuffers(context->connection, self->window); } diff --git a/tests/main.c b/tests/main.c index 38a0931..e7dc656 100644 --- a/tests/main.c +++ b/tests/main.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -45,12 +46,8 @@ int main(int argc, char **argv) { userdata.texture = &texture; userdata.font = &font; - mgl_window_callback window_callback; - window_callback.userdata = &userdata; - window_callback.draw = draw; - mgl_window window; - if(mgl_window_create(&window, "mgl", 1280, 720, &window_callback) != 0) + if(mgl_window_create(&window, "mgl", 1280, 720) != 0) return 1; if(mgl_texture_load_from_file(&texture, "tests/X11.png", NULL) != 0) @@ -59,9 +56,15 @@ int main(int argc, char **argv) { if(mgl_font_load_from_file(&font, "/usr/share/fonts/noto/NotoSans-Regular.ttf", 32) != 0) return 1; + mgl_event event; for(;;) { - mgl_window_events_poll(&window); - mgl_window_draw(&window); + while(mgl_window_events_poll(&window, &event)) { + + } + + mgl_window_clear(&window, (mgl_color){0, 0, 0, 255}); + draw(&window, &userdata); + mgl_window_display(&window); } mgl_font_unload(&font); -- cgit v1.2.3