Re: GDK + GLib main loop



I'd rather avoid the overhead of GTK+. My other choices were SDL and glut
(and maybe others), but none of those offer the features of GDK (and GLib!).

I have thought about using GTK+, and it's just pointless overhead, because
I'm going to use my own (OpenGL-based) UI library. Besides, it's more fun
this way :)

Emmanuel: yes, i know about the examples directory, and I checked there for
a GDK-only example, but didn't find one... Thanks for the code, but it's not
what I need :P



On Thu, Jul 23, 2009 at 8:07 AM, Emmanuel Rodriguez <
emmanuel rodriguez gmail com> wrote:



On Thu, Jul 23, 2009 at 5:33 AM, Mihai Draghicioiu <
mihai draghicioiu gmail com> wrote:

Hi all! I'm making an OpenGL application based on GDK + GtkGLArea. My code
so far works, but it has two issues:

Do you really need to have your application based on GDK? Can't you use GTK
instead?
By using GTK you can simply connect to the wanted signals and start a main
loop. This is going to be easier.

The tar.gz of gtkglext has an examples directory and you should be able to
start from one of their sample programs.

You should consider modifying your code to use GTK instead of GDK:

#include <stdlib.h>
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#include <GL/gl.h>


static void
realize (GtkWidget *widget,
         gpointer   data)
{
  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;
  }

  glClearColor(1.0, .5, .2, 1.0);
  glClear(GL_COLOR_BUFFER_BIT);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, widget->allocation.width, widget->allocation.height, 0, -1,
1);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glColor3f(0.0, 1.0, 0.0);
  glBegin(GL_QUADS);
    glVertex2i(100, 100);
    glVertex2i(400, 100);
    glVertex2i(400, 500);
    glVertex2i(100, 500);
  glEnd();

  /* swap backbuffer to front */
  if (gdk_gl_drawable_is_double_buffered(gldrawable))
    gdk_gl_drawable_swap_buffers(gldrawable);
  else
    glFlush();

  gdk_gl_drawable_gl_end (gldrawable);
}

static gboolean
configure_event (GtkWidget         *widget,
                 GdkEventConfigure *event,
                 gpointer           data)
{
  GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
  GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

  /*** OpenGL BEGIN ***/
  if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
    return FALSE;

  glViewport (0, 0,
              widget->allocation.width, widget->allocation.height);

  gdk_gl_drawable_gl_end (gldrawable);
  /*** OpenGL END ***/

  return TRUE;
}

static gboolean
expose_event (GtkWidget      *widget,
              GdkEventExpose *event,
              gpointer        data)
{
  GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
  GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

  /*** OpenGL BEGIN ***/
  if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
    return FALSE;

  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glCallList (1);

  if (gdk_gl_drawable_is_double_buffered (gldrawable))
    gdk_gl_drawable_swap_buffers (gldrawable);
  else
    glFlush ();

  gdk_gl_drawable_gl_end (gldrawable);
  /*** OpenGL END ***/

  return TRUE;
}


int main(int argc, char **argv) {
  gtk_init(&argc, &argv);
  gtk_gl_init(&argc, &argv);

  int config_attributes[] = {
    GDK_GL_DOUBLEBUFFER,
    GDK_GL_RGBA,
    GDK_GL_RED_SIZE,        1,
    GDK_GL_GREEN_SIZE,      1,
    GDK_GL_BLUE_SIZE,       1,
    GDK_GL_DEPTH_SIZE,      12,
    GDK_GL_ATTRIB_LIST_NONE
  };
  GdkGLConfig *glconfig = gdk_gl_config_new(config_attributes);


  GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
  g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK
(gtk_main_quit), NULL);

  // Get automatically redrawn if any of their children changed allocation
  gtk_container_set_reallocate_redraws (GTK_CONTAINER (window), TRUE);


  // The widget where the OpenGL drawing will be done
  GtkWidget *drawing_area = gtk_drawing_area_new ();
  gtk_widget_set_size_request (drawing_area, 200, 200);
  gtk_widget_set_gl_capability(drawing_area, glconfig, NULL, TRUE,
GDK_GL_RGBA_TYPE);
  gtk_widget_add_events(GTK_WIDGET(drawing_area), GDK_CONFIGURE);
  gtk_widget_add_events(GTK_WIDGET(drawing_area), GDK_KEY_PRESS_MASK);
  gtk_widget_add_events(GTK_WIDGET(drawing_area), GDK_STRUCTURE_MASK);
  gtk_widget_add_events(GTK_WIDGET(drawing_area), GDK_EXPOSURE_MASK);


  g_signal_connect_after (G_OBJECT (drawing_area), "realize", G_CALLBACK
(realize), NULL);
  g_signal_connect (G_OBJECT (drawing_area), "configure_event", G_CALLBACK
(configure_event), NULL);
  g_signal_connect (G_OBJECT (drawing_area), "expose_event", G_CALLBACK
(expose_event), NULL);


  gtk_container_add (GTK_CONTAINER (window), drawing_area);
  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}


This is a merge of your code and the example simple.c provided by
gtkglext.tar.gz. Your current drawing method doesn't work but I'm not that
good with OpenGL. Although if I substitue your drawing by the one of
simple.c it works. I'm sure that you will be able to figure this bit out for
me :)

--
Emmanuel Rodriguez




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]