diff options
author | dec05eba <dec05eba@protonmail.com> | 2024-08-02 06:01:36 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2024-08-02 06:01:36 +0200 |
commit | f2da59054cedd1c07779e72537da4d7b14616b48 (patch) | |
tree | b6c8606c1e7494d2fc17439552db30f55b97fd26 | |
parent | 470dac0e891c1ec59dfe52e77861cf068837976d (diff) |
Ensure correct blending function for transparent window
-rw-r--r-- | include/mgl/gl_macro.h | 1 | ||||
-rw-r--r-- | include/mgl/mgl.h | 3 | ||||
-rw-r--r-- | include/mgl/window/window.h | 5 | ||||
-rw-r--r-- | src/graphics/sprite.c | 5 | ||||
-rw-r--r-- | src/graphics/text.c | 5 | ||||
-rw-r--r-- | src/mgl.c | 2 | ||||
-rw-r--r-- | src/window/window.c | 28 | ||||
-rw-r--r-- | tests/main.c | 4 |
8 files changed, 48 insertions, 5 deletions
diff --git a/include/mgl/gl_macro.h b/include/mgl/gl_macro.h index cbecf94..ba2d3f1 100644 --- a/include/mgl/gl_macro.h +++ b/include/mgl/gl_macro.h @@ -18,6 +18,7 @@ #define GL_COLOR_BUFFER_BIT 0x00004000 #define GL_BLEND 0x0BE2 +#define GL_ONE 1 #define GL_SRC_ALPHA 0x0302 #define GL_ONE_MINUS_SRC_ALPHA 0x0303 #define GL_TEXTURE_2D 0x0DE1 diff --git a/include/mgl/mgl.h b/include/mgl/mgl.h index 4e1a181..e314e03 100644 --- a/include/mgl/mgl.h +++ b/include/mgl/mgl.h @@ -6,10 +6,13 @@ /* Display* on x11 */ typedef void* mgl_connection; typedef struct mgl_context mgl_context; +typedef struct mgl_window mgl_window; struct mgl_context { mgl_connection connection; mgl_gl gl; + mgl_window *current_window; + unsigned long wm_delete_window_atom; unsigned long net_wm_ping_atom; unsigned long net_wm_pid_atom; diff --git a/include/mgl/window/window.h b/include/mgl/window/window.h index eb7f587..23b780a 100644 --- a/include/mgl/window/window.h +++ b/include/mgl/window/window.h @@ -74,7 +74,7 @@ typedef struct { mgl_window_handle parent_window; /* 0 = root window */ bool hidden; /* false by default */ bool override_redirect; /* false by default */ - bool support_alpha; /* support alpha for the window, false by default */ + bool support_alpha; /* support alpha for the window, false by default. If this is set to true then you need to call mgl_window_set_texture_blend_func before rendering textures and call mgl_window_set_render_blend_func afterwards to ensure correct alpha blending */ bool hide_decorations; /* this is a hint, it may be ignored by the window manager, false by default */ mgl_color background_color; /* default: black */ const char *class_name; @@ -165,6 +165,9 @@ bool mgl_window_get_clipboard(mgl_window *self, mgl_clipboard_callback callback, bool mgl_window_get_clipboard_string(mgl_window *self, char **str, size_t *size); void mgl_window_set_key_repeat_enabled(mgl_window *self, bool enabled); +void mgl_window_set_texture_blend_func(mgl_window *self); +void mgl_window_set_render_blend_func(mgl_window *self); + void mgl_window_flush(mgl_window *self); #endif /* MGL_WINDOW_H */ diff --git a/src/graphics/sprite.c b/src/graphics/sprite.c index 3110cf9..613ec4c 100644 --- a/src/graphics/sprite.c +++ b/src/graphics/sprite.c @@ -1,5 +1,6 @@ #include "../../include/mgl/graphics/sprite.h" #include "../../include/mgl/graphics/texture.h" +#include "../../include/mgl/window/window.h" #include "../../include/mgl/mgl.h" void mgl_sprite_init(mgl_sprite *self, mgl_texture *texture) { @@ -60,6 +61,8 @@ void mgl_sprite_draw(mgl_context *context, mgl_sprite *sprite) { if(!sprite->texture) return; + mgl_window_set_texture_blend_func(context->current_window); + float texture_right = 1.0f; float texture_bottom = 1.0f; if(sprite->texture->pixel_coordinates) { @@ -86,4 +89,6 @@ void mgl_sprite_draw(mgl_context *context, mgl_sprite *sprite) { context->gl.glEnd(); mgl_texture_use(NULL); context->gl.glLoadIdentity(); /* TODO: Remove, but what about glRotatef above */ + + mgl_window_set_render_blend_func(context->current_window); } diff --git a/src/graphics/text.c b/src/graphics/text.c index 0942b62..76ac128 100644 --- a/src/graphics/text.c +++ b/src/graphics/text.c @@ -1,6 +1,7 @@ #include "../../include/mgl/graphics/text.h" #include "../../include/mgl/graphics/font.h" #include "../../include/mgl/system/utf8.h" +#include "../../include/mgl/window/window.h" #include "../../include/mgl/mgl.h" #include <stdio.h> @@ -225,10 +226,14 @@ void mgl_text_draw(mgl_context *context, mgl_text *text) { text_draw_userdata.context = context; text_draw_userdata.prev_codepoint = 0; + mgl_window_set_texture_blend_func(context->current_window); + context->gl.glColor4ub(text->color.r, text->color.g, text->color.b, text->color.a); mgl_texture_use(&text->font->texture); context->gl.glBegin(GL_QUADS); mgl_text_for_each_codepoint(text, text_draw_callback, &text_draw_userdata); context->gl.glEnd(); mgl_texture_use(NULL); + + mgl_window_set_render_blend_func(context->current_window); } @@ -119,6 +119,8 @@ void mgl_deinit(void) { */ mgl_gl_unload(&context.gl); } + + context.current_window = NULL; } if(init_count > 0) diff --git a/src/window/window.c b/src/window/window.c index 586719d..ccbf8ef 100644 --- a/src/window/window.c +++ b/src/window/window.c @@ -85,6 +85,7 @@ typedef struct { GLXFBConfig *fbconfigs; GLXFBConfig fbconfig; XVisualInfo *visual_info; + bool support_alpha; /* This only contains connected and active monitors */ mgl_monitor monitors[MAX_MONITORS]; @@ -185,6 +186,7 @@ static int x11_context_init(x11_context *self, bool alpha) { self->fbconfigs = NULL; self->fbconfig = NULL; self->visual_info = NULL; + self->support_alpha = alpha; memset(self->monitors, 0, sizeof(self->monitors)); self->num_monitors = 0; @@ -574,6 +576,7 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window self->num_monitors = 0; mgl_context *context = mgl_get_context(); + context->current_window = self; Window parent_window = params ? params->parent_window : None; if(parent_window == 0) @@ -700,7 +703,7 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window context->gl.glEnable(GL_TEXTURE_2D); context->gl.glEnable(GL_BLEND); context->gl.glEnable(GL_SCISSOR_TEST); - context->gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + mgl_window_set_render_blend_func(self); context->gl.glEnableClientState(GL_VERTEX_ARRAY); context->gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY); context->gl.glEnableClientState(GL_COLOR_ARRAY); @@ -765,6 +768,10 @@ void mgl_window_deinit(mgl_window *self) { self->clipboard_size = 0; self->open = false; + + mgl_context *context = mgl_get_context(); + if(context->current_window == self) + context->current_window = NULL; } /* Returns MGL_KEY_UNKNOWN on no match */ @@ -1256,7 +1263,13 @@ static void mgl_window_on_receive_event(mgl_window *self, XEvent *xev, mgl_event void mgl_window_clear(mgl_window *self, mgl_color color) { mgl_context *context = mgl_get_context(); - context->gl.glClearColor((float)color.r / 255.0f, (float)color.g / 255.0f, (float)color.b / 255.0f, (float)color.a / 255.0f); + x11_context *x11_context = self->context; + + const float alpha = (float)color.a / 255.0f; + if(x11_context->support_alpha) + context->gl.glClearColor(((float)color.r / 255.0f) * alpha, ((float)color.g / 255.0f) * alpha, ((float)color.b / 255.0f) * alpha, alpha); + else + context->gl.glClearColor((float)color.r / 255.0f, (float)color.g / 255.0f, (float)color.b / 255.0f, alpha); context->gl.glClear(GL_COLOR_BUFFER_BIT); } @@ -1783,6 +1796,17 @@ void mgl_window_set_key_repeat_enabled(mgl_window *self, bool enabled) { self->key_repeat_enabled = enabled; } +void mgl_window_set_texture_blend_func(mgl_window *self) { + mgl_context *context = mgl_get_context(); + context->gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void mgl_window_set_render_blend_func(mgl_window *self) { + mgl_context *context = mgl_get_context(); + x11_context *x11_context = self->context; + context->gl.glBlendFunc(x11_context->support_alpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + void mgl_window_flush(mgl_window *self) { mgl_context *context = mgl_get_context(); XFlush(context->connection); diff --git a/tests/main.c b/tests/main.c index 720cf06..f52e3d4 100644 --- a/tests/main.c +++ b/tests/main.c @@ -220,7 +220,7 @@ static bool clipboard_callback(const unsigned char *data, size_t size, mgl_clipb return true; } -int main(int argc, char **argv) { +int main(void) { test_hash_map(); test_utf8(); @@ -252,7 +252,7 @@ int main(int argc, char **argv) { if(mgl_texture_init(&texture) != 0) return 1; - if(mgl_texture_load_from_file(&texture, "tests/X11.jpg", &(mgl_texture_load_options){ false, false }) != 0) + if(mgl_texture_load_from_file(&texture, "tests/X11.jpg", &(mgl_texture_load_options){ .compressed = false, .pixel_coordinates = false, .mipmap = false }) != 0) return 1; if(mgl_mapped_file_load("/usr/share/fonts/TTF/Hack-Regular.ttf", &font_file, &(mgl_memory_mapped_file_load_options){ .readable = true, .writable = false }) != 0) |