From a5524a7e3e8248a5a4baa8af62a1a758f1d07e7f Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 23 Sep 2022 21:10:08 +0200 Subject: Make window rgba and set background transparent to allow window clear to work with transparency --- src/gl.c | 17 +++++++++-------- src/graphics/font.c | 8 ++++---- src/graphics/image.c | 4 ++-- src/graphics/shader.c | 24 ++++++++++++------------ src/graphics/texture.c | 2 +- src/mgl.c | 51 ++++++++++++++++++++++++++++++++++++-------------- src/window/window.c | 40 ++++++++++++++++++++++----------------- 7 files changed, 88 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/gl.c b/src/gl.c index 0745810..ead18dc 100644 --- a/src/gl.c +++ b/src/gl.c @@ -8,13 +8,13 @@ typedef struct { const char *name; } dlsym_assign; -static void* dlsym_print_fail(void *handle, const char *name) { +static void* dlsym_print_fail(void *handle, const char *name, int required) { dlerror(); void *sym = dlsym(handle, name); char *err_str = dlerror(); if(!sym) - fprintf(stderr, "dlsym(handle, \"%s\") failed, error: %s\n", name, err_str ? err_str : "(null)"); + fprintf(stderr, "mgl %s: dlsym(handle, \"%s\") failed, error: %s\n", required ? "error" : "warning", name, err_str ? err_str : "(null)"); return sym; } @@ -26,16 +26,17 @@ int mgl_gl_load(mgl_gl *self) { const char *glx_path = "libGL.so.1"; self->handle = dlopen(glx_path, RTLD_LAZY); if(!self->handle) { - fprintf(stderr, "dlopen(\"%s\", RTLD_LAZY) failed\n", glx_path); + fprintf(stderr, "mgl error:dlopen(\"%s\", RTLD_LAZY) failed\n", glx_path); return -1; } const dlsym_assign required_dlsym[] = { - { &self->glXChooseVisual, "glXChooseVisual" }, - { &self->glXCreateContext, "glXCreateContext" }, + { &self->glXCreateNewContext, "glXCreateNewContext" }, + { &self->glXMakeContextCurrent, "glXMakeContextCurrent" }, { &self->glXDestroyContext, "glXDestroyContext" }, - { &self->glXMakeCurrent, "glXMakeCurrent" }, { &self->glXSwapBuffers, "glXSwapBuffers" }, + { &self->glXChooseFBConfig, "glXChooseFBConfig" }, + { &self->glXGetVisualFromFBConfig, "glXGetVisualFromFBConfig" }, { &self->glViewport, "glViewport" }, { &self->glScissor, "glScissor" }, @@ -98,7 +99,7 @@ int mgl_gl_load(mgl_gl *self) { }; for(int i = 0; required_dlsym[i].func; ++i) { - *required_dlsym[i].func = dlsym_print_fail(self->handle, required_dlsym[i].name); + *required_dlsym[i].func = dlsym_print_fail(self->handle, required_dlsym[i].name, 1); if(!required_dlsym[i].func) { mgl_gl_unload(self); return -1; @@ -114,7 +115,7 @@ int mgl_gl_load(mgl_gl *self) { }; for(int i = 0; optional_dlsym[i].func; ++i) { - *optional_dlsym[i].func = dlsym_print_fail(self->handle, optional_dlsym[i].name); + *optional_dlsym[i].func = dlsym_print_fail(self->handle, optional_dlsym[i].name, 0); } return 0; diff --git a/src/graphics/font.c b/src/graphics/font.c index 9a99f22..4fd9840 100644 --- a/src/graphics/font.c +++ b/src/graphics/font.c @@ -39,13 +39,13 @@ int mgl_font_load_from_file(mgl_font *self, const mgl_memory_mapped_file *mapped self->font_info = malloc(sizeof(stbtt_fontinfo)); if(!self->font_info) { - fprintf(stderr, "Error: failed to load font, error: out of memory\n"); + fprintf(stderr, "mgl error: failed to load font, error: out of memory\n"); return -1; } /* TODO: Handle font offset with ttc */ if(!stbtt_InitFont(self->font_info, mapped_file->data, stbtt_GetFontOffsetForIndex(mapped_file->data, 0))) { - fprintf(stderr, "Error: failed to load font, error: stbtt_InitFont failed\n"); + fprintf(stderr, "mgl error: failed to load font, error: stbtt_InitFont failed\n"); mgl_font_unload(self); return -1; } @@ -137,7 +137,7 @@ static void mgl_font_handle_new_render_position(mgl_font *self, int glyph_width) mgl_font_char_iterator_next(&font_char_it); } } else { - fprintf(stderr, "Error: failed to resize font atlas\n"); + fprintf(stderr, "mgl error: failed to resize font atlas\n"); } } else if(self->font_atlas.render_section == MGL_ATLAS_SECTION_RIGHT && self->font_atlas.pointer_position.y + self->current_line_max_height + (int)self->character_size + GLYPH_PADDING >= self->font_atlas.prev_height) { self->font_atlas.right_section_height = self->font_atlas.pointer_position.y + self->current_line_max_height; @@ -174,7 +174,7 @@ int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph if(mgl_texture_load_from_memory(&self->texture, NULL, initial_atlas_size, initial_atlas_size, MGL_IMAGE_FORMAT_ALPHA, &load_options) != 0) { return -1; } else { - /*fprintf(stderr, "Error: failed to create font atlas texture, error: mgl_texture_load_from_memory failed\n");*/ + /*fprintf(stderr, "mgl error: failed to create font atlas texture, error: mgl_texture_load_from_memory failed\n");*/ self->font_atlas.width = initial_atlas_size; self->font_atlas.height = initial_atlas_size; } diff --git a/src/graphics/image.c b/src/graphics/image.c index eeee2ad..bb11334 100644 --- a/src/graphics/image.c +++ b/src/graphics/image.c @@ -46,7 +46,7 @@ int mgl_image_load_from_file(mgl_image *self, const char *filepath) { 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()); + fprintf(stderr, "mgl error: failed to load image %s, error: %s\n", filepath, stbi_failure_reason()); mgl_image_unload(self); return -1; } @@ -65,7 +65,7 @@ int mgl_image_load_from_memory(mgl_image *self, const unsigned char *data, size_ 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()); + fprintf(stderr, "mgl error: failed to load image from memory, error: %s\n", stbi_failure_reason()); mgl_image_unload(self); return -1; } diff --git a/src/graphics/shader.c b/src/graphics/shader.c index 8f44f0f..83c8407 100644 --- a/src/graphics/shader.c +++ b/src/graphics/shader.c @@ -25,7 +25,7 @@ static void print_compile_log(mgl_context *context, unsigned int shader_id, cons if(log_length > 0) { char *log_str = malloc(log_length + 1); if(!log_str) { - fprintf(stderr, "Error: failed to allocate memory for shader compile log\n"); + fprintf(stderr, "mgl error: failed to allocate memory for shader compile log\n"); return; } @@ -47,7 +47,7 @@ static int mgl_shader_load_from_memory(mgl_shader *self, const unsigned char *sh mgl_context *context = mgl_get_context(); self->id = context->gl.glCreateShader(mgl_shader_type_to_gl_shader_type(shader_type)); if(self->id == 0) { - fprintf(stderr, "Error: failed to load shader, error: glCreateShader failed\n"); + fprintf(stderr, "mgl error: failed to load shader, error: glCreateShader failed\n"); return -1; } @@ -57,12 +57,12 @@ static int mgl_shader_load_from_memory(mgl_shader *self, const unsigned char *sh int compiled_successfully = GL_FALSE; context->gl.glGetShaderiv(self->id, GL_COMPILE_STATUS, &compiled_successfully); if(compiled_successfully == GL_FALSE) { - print_compile_log(context, self->id, "Error"); + print_compile_log(context, self->id, "mgl error"); mgl_shader_unload(self); return -1; } - print_compile_log(context, self->id, "Warning"); + print_compile_log(context, self->id, "mgl warning"); return 0; } @@ -72,12 +72,12 @@ static int mgl_shader_load_from_file(mgl_shader *self, const char *filepath, mgl mgl_filedata filedata; if(mgl_load_file(filepath, &filedata, NULL) != 0) { - fprintf(stderr, "Error: failed to load shader %s, error: mgl_load_file failed\n", filepath); + fprintf(stderr, "mgl error: failed to load shader %s, error: mgl_load_file failed\n", filepath); return -1; } if(filedata.size > INT32_MAX) { - fprintf(stderr, "Error: failed to load shader %s, error: shader size is too large\n", filepath); + fprintf(stderr, "mgl error: failed to load shader %s, error: shader size is too large\n", filepath); return -1; } @@ -100,7 +100,7 @@ int mgl_shader_program_init(mgl_shader_program *self) { mgl_context *context = mgl_get_context(); self->id = context->gl.glCreateProgram(); if(self->id == 0) { - fprintf(stderr, "Error: failed to create shader program: error glCreateProgram failed\n"); + fprintf(stderr, "mgl error: failed to create shader program: error glCreateProgram failed\n"); return -1; } @@ -143,7 +143,7 @@ static void print_link_log(mgl_context *context, unsigned int shader_id, const c if(log_length > 0) { char *log_str = malloc(log_length + 1); if(!log_str) { - fprintf(stderr, "Error: failed to allocate memory for shader link log\n"); + fprintf(stderr, "mgl error: failed to allocate memory for shader link log\n"); return; } @@ -163,11 +163,11 @@ int mgl_shader_program_finalize(mgl_shader_program *self) { int is_linked = GL_TRUE; context->gl.glGetProgramiv(self->id, GL_LINK_STATUS, &is_linked); if(is_linked == GL_FALSE) { - print_link_log(context, self->id, "Error"); + print_link_log(context, self->id, "mgl error"); return -1; } - print_link_log(context, self->id, "Warning"); + print_link_log(context, self->id, "mgl warning"); return 0; } @@ -179,7 +179,7 @@ int mgl_shader_program_set_uniform_float(mgl_shader_program *self, const char *u mgl_context *context = mgl_get_context(); int uniform_location = context->gl.glGetUniformLocation(self->id, uniform_name); if(uniform_location == -1) { - fprintf(stderr, "Error: no uniform by the name %s was found in the shader\n", uniform_name); + fprintf(stderr, "mgl error: no uniform by the name %s was found in the shader\n", uniform_name); return -1; } @@ -193,7 +193,7 @@ int mgl_shader_program_set_uniform_vec2f(mgl_shader_program *self, const char *u mgl_context *context = mgl_get_context(); int uniform_location = context->gl.glGetUniformLocation(self->id, uniform_name); if(uniform_location == -1) { - fprintf(stderr, "Error: no uniform by the name %s was found in the shader\n", uniform_name); + fprintf(stderr, "mgl error: no uniform by the name %s was found in the shader\n", uniform_name); return -1; } diff --git a/src/graphics/texture.c b/src/graphics/texture.c index fb8c1e5..128d910 100644 --- a/src/graphics/texture.c +++ b/src/graphics/texture.c @@ -63,7 +63,7 @@ int mgl_texture_init(mgl_texture *self) { mgl_context *context = mgl_get_context(); context->gl.glGenTextures(1, &self->id); if(self->id == 0) { - fprintf(stderr, "Error: failed to init texture (glGenTextures failed)\n"); + fprintf(stderr, "mgl error: failed to init texture (glGenTextures failed)\n"); return -1; } diff --git a/src/mgl.c b/src/mgl.c index dd5cccd..1fcbb4a 100644 --- a/src/mgl.c +++ b/src/mgl.c @@ -1,6 +1,7 @@ #include "../include/mgl/mgl.h" #include #include +#include #include #ifndef NDEBUG #include @@ -24,25 +25,47 @@ static int ignore_xioerror(Display *display) { static int glx_context_init() { const int attr[] = { - GLX_RGBA, - GLX_BUFFER_SIZE, 24, - GLX_DEPTH_SIZE, 0, - GLX_STENCIL_SIZE, 0, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_DOUBLEBUFFER, True, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, - GLX_ALPHA_SIZE, 0, - GLX_ACCUM_RED_SIZE, 0, - GLX_ACCUM_GREEN_SIZE, 0, - GLX_ACCUM_BLUE_SIZE, 0, - GLX_ACCUM_ALPHA_SIZE, 0, - GLX_DOUBLEBUFFER, /* TODO: Add option to turn this off? */ + GLX_ALPHA_SIZE, 8, + GLX_DEPTH_SIZE, 0, None }; - context.visual_info = context.gl.glXChooseVisual(context.connection, DefaultScreen(context.connection), (int*)attr); + context.visual_info = NULL; + context.fbconfig = NULL; + + int numfbconfigs = 0; + GLXFBConfig *fbconfigs = context.gl.glXChooseFBConfig(context.connection, DefaultScreen(context.connection), attr, &numfbconfigs); + for(int i = 0; i < numfbconfigs; i++) { + context.visual_info = context.gl.glXGetVisualFromFBConfig(context.connection, fbconfigs[i]); + if(!context.visual_info) + continue; + + XRenderPictFormat *pict_format = XRenderFindVisualFormat(context.connection, ((XVisualInfo*)context.visual_info)->visual); + if(!pict_format) { + XFree(context.visual_info); + context.visual_info = NULL; + continue; + } + + context.fbconfig = fbconfigs[i]; + if(pict_format->direct.alphaMask > 0) + break; + + XFree(context.visual_info); + context.visual_info = NULL; + } + + if(fbconfigs) + XFree(fbconfigs); + if(!context.visual_info) { - fprintf(stderr, "glXChooseVisual failed, no appropriate visual found\n"); + fprintf(stderr, "mgl error: no appropriate visual found\n"); return -1; } @@ -61,7 +84,7 @@ int mgl_init(void) { if(init_count == 1) { context.connection = XOpenDisplay(NULL); if(!context.connection) { - fprintf(stderr, "XOpenDisplay(NULL) failed\n"); + fprintf(stderr, "mgl error:XOpenDisplay(NULL) failed\n"); mgl_deinit(); return -1; } @@ -120,7 +143,7 @@ void mgl_deinit(void) { mgl_context* mgl_get_context(void) { #ifndef NDEBUG if(init_count == 0) { - fprintf(stderr, "Error: mgl_get_context was called before mgl_init\n"); + fprintf(stderr, "mgl error: mgl_get_context was called before mgl_init\n"); abort(); } #endif diff --git a/src/window/window.c b/src/window/window.c index 8acd428..eeb2e43 100644 --- a/src/window/window.c +++ b/src/window/window.c @@ -184,12 +184,12 @@ static void set_vertical_sync_enabled(Window window, int enabled) { static int warned = 0; if (!warned) { warned = 1; - fprintf(stderr, "Warning: setting vertical sync not supported\n"); + fprintf(stderr, "mgl warning: setting vertical sync not supported\n"); } } if(result != 0) - fprintf(stderr, "Warning: setting vertical sync failed\n"); + fprintf(stderr, "mgl warning: setting vertical sync failed\n"); } static void mgl_window_on_resize(mgl_window *self, int width, int height) { @@ -223,13 +223,13 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window self->context = malloc(sizeof(x11_context)); if(!self->context) { - fprintf(stderr, "Failed to allocate x11 context\n"); + fprintf(stderr, "mgl error: failed to allocate x11 context\n"); return -1; } x11_context *x11_context = self->context; if(x11_context_init(x11_context) != 0) { - fprintf(stderr, "x11_context_init failed\n"); + fprintf(stderr, "mgl error: x11_context_init failed\n"); mgl_window_deinit(self); return -1; } @@ -240,16 +240,16 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window if(parent_window == 0) parent_window = DefaultRootWindow(context->connection); - x11_context->glx_context = context->gl.glXCreateContext(context->connection, context->visual_info, NULL, 1); + x11_context->glx_context = context->gl.glXCreateNewContext(context->connection, context->fbconfig, GLX_RGBA_TYPE, 0, True); if(!x11_context->glx_context) { - fprintf(stderr, "glXCreateContext failed\n"); + fprintf(stderr, "mgl error: glXCreateContext failed\n"); mgl_window_deinit(self); return -1; } x11_context->color_map = XCreateColormap(context->connection, DefaultRootWindow(context->connection), ((XVisualInfo*)context->visual_info)->visual, AllocNone); if(!x11_context->color_map) { - fprintf(stderr, "XCreateColormap failed\n"); + fprintf(stderr, "mgl error: XCreateColormap failed\n"); mgl_window_deinit(self); return -1; } @@ -257,6 +257,8 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window XSetWindowAttributes window_attr; window_attr.override_redirect = params ? params->override_redirect : false; window_attr.colormap = x11_context->color_map; + window_attr.background_pixmap = None; + window_attr.border_pixel = 0; window_attr.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | @@ -266,8 +268,8 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window const bool hide_window = params ? params->hidden : false; if(existing_window) { - if(!XChangeWindowAttributes(context->connection, existing_window, CWColormap | CWEventMask | CWOverrideRedirect, &window_attr)) { - fprintf(stderr, "XChangeWindowAttributes failed\n"); + if(!XChangeWindowAttributes(context->connection, existing_window, CWColormap | CWEventMask | CWOverrideRedirect | CWBorderPixel | CWBackPixmap, &window_attr)) { + fprintf(stderr, "mgl error: XChangeWindowAttributes failed\n"); mgl_window_deinit(self); return -1; } @@ -279,9 +281,9 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window self->window = XCreateWindow(context->connection, parent_window, params->position.x, params->position.y, window_size.x, window_size.y, 0, ((XVisualInfo*)context->visual_info)->depth, InputOutput, ((XVisualInfo*)context->visual_info)->visual, - CWColormap | CWEventMask | CWOverrideRedirect, &window_attr); + CWColormap | CWEventMask | CWOverrideRedirect | CWBorderPixel | CWBackPixmap, &window_attr); if(!self->window) { - fprintf(stderr, "XCreateWindow failed\n"); + fprintf(stderr, "mgl error: XCreateWindow failed\n"); mgl_window_deinit(self); return -1; } @@ -310,7 +312,11 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window XFlush(context->connection); /* TODO: Check for failure? */ - context->gl.glXMakeCurrent(context->connection, self->window, x11_context->glx_context); + if(!context->gl.glXMakeContextCurrent(context->connection, self->window, self->window, x11_context->glx_context)) { + fprintf(stderr, "mgl error: failed to make opengl context current!\n"); + mgl_window_deinit(self); + return -1; + } set_vertical_sync_enabled(self->window, 1); context->gl.glEnable(GL_TEXTURE_2D); context->gl.glEnable(GL_BLEND); @@ -330,14 +336,14 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window x11_context->xim = XOpenIM(context->connection, NULL, NULL, NULL); if(!x11_context->xim) { - fprintf(stderr, "XOpenIM failed\n"); + fprintf(stderr, "mgl error: XOpenIM failed\n"); mgl_window_deinit(self); return -1; } x11_context->xic = XCreateIC(x11_context->xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, self->window, NULL); if(!x11_context->xic) { - fprintf(stderr, "XCreateIC failed\n"); + fprintf(stderr, "mgl error: XCreateIC failed\n"); mgl_window_deinit(self); return -1; } @@ -893,7 +899,7 @@ void mgl_window_set_size_limits(mgl_window *self, mgl_vec2i minimum, mgl_vec2i m XFree(size_hints); XSync(context->connection, False); } else { - fprintf(stderr, "Warning: failed to set window size hints\n"); + fprintf(stderr, "mgl warning: failed to set window size hints\n"); } } @@ -911,13 +917,13 @@ void mgl_window_set_clipboard(mgl_window *self, const char *str, size_t size) { /* Check if setting the selection owner was successful */ if(XGetSelectionOwner(context->connection, x11_context->clipboard_atom) != self->window) { - fprintf(stderr, "Error: mgl_window_set_clipboard failed\n"); + fprintf(stderr, "mgl error: mgl_window_set_clipboard failed\n"); return; } self->clipboard_string = malloc(size + 1); if(!self->clipboard_string) { - fprintf(stderr, "Error: failed to allocate string for clipboard\n"); + fprintf(stderr, "mgl error: failed to allocate string for clipboard\n"); return; } memcpy(self->clipboard_string, str, size); -- cgit v1.2.3