drahnr drahnr - 11 months ago 88
C Question

Gtk+ and OpenGL bindings

Simple and short: What is the most advanced OpenGL binding for GTK+?
I would prefer a widget which allows me to use it similar to QGLWidget.

Note: I stumbled upon gtkglext, gtkglarea and clutter. I read the first two have shortcomings/ serious issues.

Answer Source


Since Gtk+-3.16 any beyond do not use any of the below!

If you want to use the current state of the art, vertex/pixel shaders you should use the latest gnome and rely on its caps:

Extensively covered in https://www.bassi.io/articles/2015/02/17/using-opengl-with-gtk/

Ok, I read pretty much through the last 2 hours and my results are:

  • gtkglext will completly replace the backend by OpenGL, this was not my intention
  • clutter has all native gl calls boxed into objects and does not support native gl calls at all, though it provides many predifened filters and funny stuff
  • gtkglarea seems fine, its design is lovely. It has the same usage style as QGLWidget in Qt (as far as I can say) simple demo of gtkglarea:

    #include <math.h>
    #include <gtk/gtk.h>
    #include <GL/gl.h>
    #include <gtkgl/gtkglarea.h>
    int init (GtkWidget *widget)
    if (gtk_gl_area_make_current (GTK_GL_AREA(widget)))
      glViewport(0,0, widget->allocation.width, widget->allocation.height);
      glOrtho(0,100, 100,0, -1,1);
    return TRUE;
    int draw (GtkWidget *widget, GdkEventExpose *event)
    if (event->count > 0) return TRUE;
    if (gtk_gl_area_make_current (GTK_GL_AREA(widget)))
      gtk_gl_area_swap_buffers (GTK_GL_AREA(widget));
    return TRUE;
    int reshape (GtkWidget *widget, GdkEventConfigure *event)
    if (gtk_gl_area_make_current (GTK_GL_AREA(widget)))
      glViewport(0,0, widget->allocation.width, widget->allocation.height);
    return TRUE;
    int main (int argc, char **argv)
    GtkWidget *window, *glarea;
    int attrlist[] = {
    GDK_GL_NONE };
    gtk_init (&argc, &argv);
    if (gdk_gl_query () == FALSE) return 0;
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW(window), "Simple");
    gtk_container_set_border_width (GTK_CONTAINER(window), 10);
    g_signal_connect (window, "delete_event",
    G_CALLBACK (gtk_main_quit), NULL);
    /* You should always delete gtk_gl_area widgets before exit or else
       GLX contexts are left undeleted, this may cause problems (=core dump)
       in some systems.
       Destroy method of objects is not automatically called on exit.
       You need to manually enable this feature. Do gtk_quit_add_destroy()
       for all your top level windows unless you are certain that they get
       destroy signal by other means. */
    gtk_quit_add_destroy (1, GTK_OBJECT(window));
    glarea = GTK_WIDGET(gtk_gl_area_new (attrlist));
    gtk_widget_set_size_request (GTK_WIDGET(glarea), 100, 100);
    gtk_widget_set_events (GTK_WIDGET(glarea), GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
    g_signal_connect (glarea, "expose_event", G_CALLBACK(draw), NULL);
    g_signal_connect (glarea, "configure_event", G_CALLBACK(reshape), NULL);
    g_signal_connect (glarea, "realize", G_CALLBACK(init), NULL);
    gtk_container_add (GTK_CONTAINER(window), GTK_WIDGET(glarea));
    gtk_widget_show (GTK_WIDGET(glarea));
    gtk_widget_show (GTK_WIDGET(window));
    gtk_main ();
    return 0;

Note: gtkglarea has still some problems like core dump on exit (at least 1.99)

Note2: Version 2.0.1 fixes this issue

Edit: For those seeking for 2D only cairo seems to be most suitable.