aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-08-02 06:01:36 +0200
committerdec05eba <dec05eba@protonmail.com>2024-08-02 06:01:36 +0200
commitf2da59054cedd1c07779e72537da4d7b14616b48 (patch)
treeb6c8606c1e7494d2fc17439552db30f55b97fd26
parent470dac0e891c1ec59dfe52e77861cf068837976d (diff)
Ensure correct blending function for transparent window
-rw-r--r--include/mgl/gl_macro.h1
-rw-r--r--include/mgl/mgl.h3
-rw-r--r--include/mgl/window/window.h5
-rw-r--r--src/graphics/sprite.c5
-rw-r--r--src/graphics/text.c5
-rw-r--r--src/mgl.c2
-rw-r--r--src/window/window.c28
-rw-r--r--tests/main.c4
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);
}
diff --git a/src/mgl.c b/src/mgl.c
index 16379e0..6fd26a7 100644
--- a/src/mgl.c
+++ b/src/mgl.c
@@ -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)