Re: GDK + GLib main loop



I have found the way. Here is my code. Any idea where I can post it as a
tutorial?

#include <stdlib.h>
#include <glib.h>
#include <gdk/gdk.h>
#include <gdk/gdkgl.h>
#include <GL/gl.h>

GdkGLWindow *glwin = NULL;
GdkGLContext *glcontext = NULL;
GMainLoop *mainloop;

static void event_func(GdkEvent *ev, gpointer data) {
    printf("event func\n");
            switch(ev->type) {
                case GDK_MAP:
                    break;
                case GDK_DELETE:
                    g_main_loop_quit(mainloop);
                    break;
                case GDK_KEY_PRESS:
                    printf("key pressed\n");
                    break;
                case GDK_EXPOSE:
                    printf("got expose\n");
                    break;
                case GDK_CONFIGURE:

if(gdk_gl_drawable_gl_begin(gdk_window_get_gl_drawable(ev->configure.window),
glcontext)) {
                        glViewport(0, 0, ev->configure.width,
ev->configure.height);

if(gdk_gl_drawable_is_double_buffered(gdk_window_get_gl_drawable(ev->configure.window)))
{

gdk_gl_drawable_swap_buffers(gdk_window_get_gl_drawable(ev->configure.window));
                        } else
                            glFlush();

gdk_gl_drawable_gl_end(gdk_window_get_gl_drawable(ev->configure.window));
                    }
                    break;
            }

if(gdk_gl_drawable_gl_begin(gdk_window_get_gl_drawable(ev->any.window),
glcontext)) {
                        glClearColor(1.0, .5, .2, 1.0);
                        glClear(GL_COLOR_BUFFER_BIT);
                        glMatrixMode(GL_PROJECTION);
                        glLoadIdentity();
                        glOrtho(0, 800, 600, 0, -1, 1);
                        glMatrixMode(GL_MODELVIEW);
                        glLoadIdentity();
                        glBegin(GL_QUADS);
                        glVertex2i(100, 100);
                        glVertex2i(400, 100);
                        glVertex2i(400, 500);
                        glVertex2i(100, 500);
                        glEnd();


if(gdk_gl_drawable_is_double_buffered(gdk_window_get_gl_drawable(ev->any.window)))
{

gdk_gl_drawable_swap_buffers(gdk_window_get_gl_drawable(ev->any.window));
                        } else
                            glFlush();

gdk_gl_drawable_gl_end(gdk_window_get_gl_drawable(ev->any.window));
                    }
}

int main(int argc, char **argv) {
    gdk_init(&argc, &argv);
    gdk_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 *glc = gdk_gl_config_new(config_attributes);

    GdkWindowAttr attr;
    attr.title = argv[0];
    attr.event_mask = GDK_KEY_PRESS_MASK | GDK_STRUCTURE_MASK |
GDK_EXPOSURE_MASK;
    attr.window_type = GDK_WINDOW_TOPLEVEL;
    attr.wclass = GDK_INPUT_OUTPUT;
    attr.width = 800;
    attr.height = 600;
    GdkWindow *win = gdk_window_new(NULL, &attr, 0);

    gdk_window_show(win);

    glwin = gdk_window_set_gl_capability(win, glc, NULL);
    glcontext = gdk_gl_context_new(GDK_GL_DRAWABLE(glwin), NULL, true,
GDK_GL_RGBA_TYPE);

    gdk_event_handler_set(event_func, NULL, NULL); // this is used by GTK+
internally. We just use it for ourselves here

    mainloop = g_main_loop_new(g_main_context_default(), FALSE);
    g_main_loop_run(mainloop);

    gdk_gl_window_destroy(glwin);
    gdk_window_destroy(win);

    return 0;
}



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]