Created
November 3, 2019 09:08
-
-
Save acaly/495c153e928c7c3fc93fe766aee95d61 to your computer and use it in GitHub Desktop.
Transparent OpenGL with Gtk+.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* For details see: https://stackoverflow.com/a/58678719/3622514 */ | |
#include <gtk/gtk.h> | |
#include <gdk/gdkscreen.h> | |
#include <gdk/gdkkeysyms.h> | |
#include <gtk/gtkgl.h> | |
#include <GL/gl.h> | |
#include <GL/glu.h> | |
static gboolean supports_alpha = FALSE; | |
/*** | |
*** Configure the OpenGL framebuffer. | |
***/ | |
static GdkGLConfig* configure_gl(void) | |
{ | |
GdkGLConfig* glconfig; | |
/* Try double-buffered visual */ | |
glconfig = gdk_gl_config_new_by_mode(GDK_GL_MODE_RGBA | | |
GDK_GL_MODE_ALPHA | | |
GDK_GL_MODE_DEPTH | | |
GDK_GL_MODE_DOUBLE); | |
if (glconfig == NULL) | |
{ | |
printf("Cannot find the double-buffered visual.\n"); | |
printf("No appropriate OpenGL-capable visual found.\n"); | |
exit(1); | |
} | |
printf("Find GLConfig with alpha channel.\n"); | |
return glconfig; | |
} | |
static void screen_changed(GtkWidget* widget, GdkScreen* old_screen, gpointer userdata) | |
{ | |
/* To check if the display supports alpha channels, get the colormap */ | |
GdkScreen* screen = gtk_widget_get_screen(widget); | |
GdkColormap* colormap = gdk_screen_get_rgba_colormap(screen); | |
if (!colormap) | |
{ | |
printf("Your screen does not support alpha channels!\n"); | |
colormap = gdk_screen_get_rgb_colormap(screen); | |
supports_alpha = FALSE; | |
} | |
else | |
{ | |
printf("Your screen supports alpha channels!\n"); | |
supports_alpha = TRUE; | |
} | |
gtk_widget_set_colormap(widget, colormap); | |
} | |
static gboolean expose(GtkWidget* widget, GdkEventExpose* event, gpointer userdata) | |
{ | |
GdkGLContext* glcontext = gtk_widget_get_gl_context(widget); | |
GdkGLDrawable* gldrawable = gtk_widget_get_gl_drawable(widget); | |
if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) | |
{ | |
return FALSE; | |
} | |
glDrawBuffer(GL_BACK); | |
glClearColor(0.5, 0.0, 0.0, 0.5); | |
glClear(GL_COLOR_BUFFER_BIT); | |
gdk_gl_drawable_swap_buffers(gldrawable); | |
gdk_gl_drawable_gl_end(gldrawable); | |
return TRUE; | |
} | |
int main(int argc, char** argv) | |
{ | |
gtk_init(&argc, &argv); | |
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
/* Added to config GLConfig */ | |
GdkGLConfig* glconfig = configure_gl(); | |
gtk_widget_set_gl_capability(window, | |
glconfig, | |
NULL, | |
TRUE, | |
GDK_GL_RGBA_TYPE); | |
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); | |
gtk_window_set_default_size(GTK_WINDOW(window), 400, 400); | |
gtk_window_set_title(GTK_WINDOW(window), "Alpha Demo"); | |
g_signal_connect(G_OBJECT(window), "delete-event", gtk_main_quit, NULL); | |
gtk_widget_set_app_paintable(window, TRUE); | |
g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(expose), NULL); | |
g_signal_connect(G_OBJECT(window), "screen-changed", G_CALLBACK(screen_changed), NULL); | |
screen_changed(window, NULL, NULL); | |
gtk_widget_show_all(window); | |
gtk_main(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment