Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Graphics > Inventor API > gtkglext bug
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 1 Topic 476 of 501
Post > Topic >>

gtkglext bug

by Bernard Cupic <Bernard.Cupic@[EMAIL PROTECTED] > Dec 14, 2006 at 03:04 PM

I'm learning wxWidgets (wxgtk 2.6.3) along with OpenInventor API (Coin
1.4.5).

I started with glutiv.cpp and tried to implement the same thing using
wxwidgets. It was a simple task, but things went complicated.
SoShuttle, SoPendulum or any other Transformation,
except SoRotor did not work well - at least there were no any visual
feedback. I have noticed that there was a stream of expose events
in correspondence to the scene change, but without animation.

I have noticed that this behavior is closely related to the gtkglext
library, since wxgtk uses it internally. So I made a simple example
similar to the glutiv.cpp but using gtkglext library. As expected,
this does not work as expected. Since there is no any group related
to the gtkglext library, I supose that this topic is not so off topic
for this groups.

Any help is welcome.

Here is the example (since it is rather small) along with Makefile I'm
using to build it.

/**************************************************************************
 * glextiv.cpp
 *
 * Copyright (c) 2002 Alif Wahid <awah005@[EMAIL PROTECTED]
>
 *
 * This is a template of the essential source code to write useful but
 * simple programs using GtkGLExt and Gtk. It compiles into an executable
 * but obviously the lack of any OpenGL functions in this demonstrates
 * the generic nature. It's heavily commented to aid beginners (especially
 * tertiary students like myself). So use/change it at will.
 *
 * This program is in the public domain and you are using it at
 * your own risk.
 *

**************************************************************************/

/*
 * Follow the GTK coding style.
 * Changed idle function management codes.
 * Added popup menu.
 * Added quit button.
 *   Naofumi Yasufuku  <naofumi@[EMAIL PROTECTED]
>
 */

// FIXME: note that there are some limitations to this example:
//
//  * The most im****tant one is that events are not translated from
//    native X11 events to Coin events (to be sent to the scene
//    graph). This means that for instance draggers and manipulators in
//    the scene graph will not respond to attempts at interaction.
//
//  * The sensor queue processing is just a hack. Don't use this
//    in production code.


// glextiv.cpp -- example demonstrating Coin (or Open Inventor) bound
// to the gtkglext user interface abstraction.
//
// based on the glutiv.cpp example

/**************************************************************************
 * Header file inclusions.

**************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

#include <gtk/gtkgl.h>
/*** Use OpenGL extensions. ***/
/* #include <gdk/gdkglglext.h> */

#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif

#include <GL/gl.h>
#include <GL/glu.h>

#include <Inventor/SoDB.h>
#include <Inventor/SoInteraction.h>
#include <Inventor/SoSceneManager.h>
#include <Inventor/nodekits/SoNodeKit.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoRotor.h>
#include <Inventor/nodes/SoShuttle.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/nodes/SoTransform.h>

/**************************************************************************
 * The following section contains all the macro definitions.

**************************************************************************/

/***
 *** Change these three macros to customise the
 *** default width and height of the drawing
 *** area, plus the default title of the window.
 ***/
#define DEFAULT_WIDTH  400
#define DEFAULT_HEIGHT 400
#define DEFAULT_TITLE  "GtkGLExt Template"

#define TIMEOUT_INTERVAL 10


/**************************************************************************
 * Global variable declarations.

**************************************************************************/

static gboolean animate = FALSE;
SoSceneManager* scenemanager = NULL;


/**************************************************************************
 * The following section contains the function prototype declarations.

**************************************************************************/

static void         timeout_add       (GtkWidget   *widget);

static void         timeout_remove    (GtkWidget   *widget);

static void         toggle_animation  (GtkWidget   *widget);

static GdkGLConfig *configure_gl      (void);

static GtkWidget   *create_popup_menu (GtkWidget   *drawing_area);

static GtkWidget   *create_window     (GdkGLConfig *glconfig);

//
*************************************************************************
// Make the common scenegraph. Just a little silly something to show
// off some geometry nodes and simple animation.
//
*************************************************************************

SoSeparator *
commongraph()
{
  SoSeparator * root = NULL;

  if (!root) {
    root = new SoSeparator;

    SoMaterial * material = new SoMaterial;
    material->diffuseColor.setValue(0.5f, 0.0f, 0.5f);
    root->addChild(material);

    SoShuttle * shuttle = new SoShuttle;
    shuttle->translation0.setValue(0.0f, 5.0f, 0.0f);
    shuttle->translation1.setValue(0.0f, -5.0f, 0.0f);
    shuttle->on.setValue(TRUE);
    root->addChild(shuttle);

//   SoRotor* rotor = new SoRotor;
//   rotor->speed.setValue(0.5f);
//   root->addChild(rotor);

    root->addChild(new SoCone);
  }

  return root;
}

/**************************************************************************
 * The following section contains all the callback function definitions.

**************************************************************************/

/***
 *** The "realize" signal handler. All the OpenGL initialization
 *** should be performed here, such as default background colour,
 *** certain states etc.
 ***/
static void
realize (GtkWidget *widget,
         gpointer   data)
{
  GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
  GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

  g_print ("%s: \"realize\"\n", gtk_widget_get_name (widget));

  /*** OpenGL BEGIN ***/

  if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
    return;

  /*** Fill in the details here. ***/

  gdk_gl_drawable_gl_end (gldrawable);

  /*** OpenGL END ***/
}

/***
 *** The "configure_event" signal handler. Any processing required when
 *** the OpenGL-capable drawing area is re-configured should be done here.
 *** Almost always it will be used to resize the OpenGL view****t when
 *** the window is resized.
 ***/
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);

  GLint w = widget->allocation.width;
  GLint h = widget->allocation.height;

  g_print ("%s: \"configure_event\"\n", gtk_widget_get_name (widget));

  /*** OpenGL BEGIN ***/

  if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
    return FALSE;

  /*** Fill in the details here. ***/
  SbVec2s size = SbVec2s(w, h);
  scenemanager->setWindowSize(size);
  scenemanager->setSize(size);
  scenemanager->setView****tRegion(SbView****tRegion(size));
  scenemanager->scheduleRedraw();

  glView****t (0, 0, w, h);

  gdk_gl_drawable_gl_end (gldrawable);

  /*** OpenGL END ***/

  return TRUE;
}

/***
 *** The "expose_event" signal handler. All the OpenGL re-drawing should
 *** be done here. This is repeatedly called as the painting routine
 *** every time the 'expose'/'draw' event is signalled.
 ***/
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);

  g_print ("%s: \"expose_event\"\n", gtk_widget_get_name (widget));

  /*** OpenGL BEGIN ***/

  if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
    return FALSE;

  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glEnable(GL_DEPTH_TEST);
  scenemanager->render();

  /*** Fill in the details here. ***/

  /* Swap buffers */
  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;
}

// Redraw on scenegraph changes.
void
redraw_cb(void * user, SoSceneManager * manager)
{
  GtkWidget *widget = (GtkWidget *)user;
  gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
}

/***
 *** The timeout function. Often in animations,
 *** timeout functions are suitable for continous
 *** frame updates.
 ***/
static gboolean
timeout (GtkWidget *widget)
{
  g_print (".");

  /*** Fill in the details here ***/

  /* Invalidate the whole window. */
  SoDB::getSensorManager()->processTimerQueue();
  SoDB::getSensorManager()->processDelayQueue(TRUE);
  gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);

  /* Update synchronously. */
  gdk_window_process_updates (widget->window, FALSE);

  return TRUE;
}

/***
 *** The "unrealize" signal handler. Any processing required when
 *** the OpenGL-capable window is unrealized should be done here.
 ***/
static void
unrealize (GtkWidget *widget,
           gpointer   data)
{
  GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
  GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

  g_print ("%s: \"unrealize\"\n", gtk_widget_get_name (widget));

  /*** OpenGL BEGIN ***/

  if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
    return;

  /*** Fill in the details here. ***/

  gdk_gl_drawable_gl_end (gldrawable);

  /*** OpenGL END ***/
}

/***
 *** The "motion_notify_event" signal handler. Any processing required
when
 *** the OpenGL-capable drawing area is under drag motion should be done
here.
 ***/
static gboolean
motion_notify_event (GtkWidget      *widget,
                     GdkEventMotion *event,
                     gpointer        data)
{
  g_print ("%s: \"motion_notify_event\": button", gtk_widget_get_name
(widget));

  /*** Fill in the details here. ***/

  if (event->state & GDK_BUTTON1_MASK) {
    g_print (" 1");
  }

  if (event->state & GDK_BUTTON2_MASK) {
    g_print (" 2");
  }

  if (event->state & GDK_BUTTON3_MASK) {
    g_print (" 3");
  }

  g_print ("\n");

  return FALSE;
}

/***
 *** The "button_press_event" signal handler. Any processing required when
 *** mouse buttons (only left and middle buttons) are pressed on the
OpenGL-
 *** capable drawing area should be done here.
 ***/
static gboolean
button_press_event (GtkWidget      *widget,
                    GdkEventButton *event,
                    gpointer        data)
{
  g_print ("%s: \"button_press_event\": ", gtk_widget_get_name (widget));

  if (event->button == 1) {
    /*** Fill in the details here. ***/
    g_print ("button 1\n");

    return TRUE;
  }

  if (event->button == 2) {
    /*** Fill in the details here. ***/
    g_print ("button 2\n");

    return TRUE;
  }

  g_print ("\n");

  return FALSE;
}

/* For popup menu. */
static gboolean
button_press_event_popup_menu (GtkWidget      *widget,
                               GdkEventButton *event,
                               gpointer        data)
{
  g_print ("%s: \"button_press_event_popup\": ", gtk_widget_get_name
(widget));

  if (event->button == 3) {
    g_print ("button 3\n");

    /* Popup menu. */
    gtk_menu_popup (GTK_MENU (widget), NULL, NULL, NULL, NULL,
                    event->button, event->time);
    return TRUE;
  }

  g_print ("\n");

  return FALSE;
}

/***
 *** The "key_press_event" signal handler. Any processing required when
key
 *** presses occur should be done here.
 ***/
static gboolean
key_press_event (GtkWidget   *widget,
                 GdkEventKey *event,
                 gpointer     data)
{
  g_print ("%s: \"key_press_event\": ", gtk_widget_get_name (widget));

  switch (event->keyval) {
      /*** Fill in the details here. ***/

    case GDK_a:
      g_print ("a key\n");

      toggle_animation (widget);

      break;

    case GDK_Escape:
      g_print ("Escape key\n");

      gtk_main_quit ();

      break;

    default:
      g_print("\n");

      return FALSE;
  }

  return TRUE;
}


/**************************************************************************
 * The following section contains the timeout function management
routines.

**************************************************************************/

/***
 *** Helper functions to add or remove the timeout function.
 ***/

static guint timeout_id = 0;

static void
timeout_add (GtkWidget *widget)
{
  if (timeout_id == 0) {
    timeout_id = g_timeout_add (TIMEOUT_INTERVAL,
                                (GSourceFunc) timeout,
                                widget);
  }
}

static void
timeout_remove (GtkWidget *widget)
{
  if (timeout_id != 0) {
    g_source_remove (timeout_id);
    timeout_id = 0;
  }
}

/***
 *** The "map_event" signal handler. Any processing required when the
 *** OpenGL-capable drawing area is mapped should be done here.
 ***/
static gboolean
map_event (GtkWidget *widget,
           GdkEvent  *event,
           gpointer   data)
{
  g_print ("%s: \"map_event\":\n", gtk_widget_get_name (widget));

  if (animate)
    timeout_add (widget);

  return TRUE;
}

/***
 *** The "unmap_event" signal handler. Any processing required when the
 *** OpenGL-capable drawing area is unmapped should be done here.
 ***/
static gboolean
unmap_event (GtkWidget *widget,
             GdkEvent  *event,
             gpointer   data)
{
  g_print ("%s: \"unmap_event\":\n", gtk_widget_get_name (widget));
  timeout_remove (widget);

  return TRUE;
}

/***
 *** The "visibility_notify_event" signal handler. Any processing required
 *** when the OpenGL-capable drawing area is visually obscured should be
 *** done here.
 ***/
static gboolean
visibility_notify_event (GtkWidget          *widget,
                         GdkEventVisibility *event,
                         gpointer            data)
{
  if (animate) {
    if (event->state == GDK_VISIBILITY_FULLY_OBSCURED)
      timeout_remove (widget);
    else
      timeout_add (widget);
  }

  return TRUE;
}


/**************************************************************************
 * The following section contains some miscellaneous utility functions.

**************************************************************************/

/***
 *** Toggle animation.
 ***/
static void
toggle_animation (GtkWidget *widget)
{
  animate = !animate;

  if (animate) {
    timeout_add (widget);
  } else {
    timeout_remove (widget);
    gdk_window_invalidate_rect (widget->window, &widget->allocation,
FALSE);
  }
}


/**************************************************************************
 * The following section contains the GUI building function definitions.

**************************************************************************/

/***
 *** Creates the popup menu to be displayed.
 ***/
static GtkWidget *
create_popup_menu (GtkWidget *drawing_area)
{
  GtkWidget *menu;
  GtkWidget *menu_item;

  menu = gtk_menu_new ();

  /* Toggle animation */
  menu_item = gtk_menu_item_new_with_label ("Toggle Animation");
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
  g_signal_connect_swapped (G_OBJECT (menu_item), "activate",
                            G_CALLBACK (toggle_animation), drawing_area);
  gtk_widget_show (menu_item);

  /* Quit */
  menu_item = gtk_menu_item_new_with_label ("Quit");
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
  g_signal_connect (G_OBJECT (menu_item), "activate",
                    G_CALLBACK (gtk_main_quit), NULL);
  gtk_widget_show (menu_item);

  return menu;
}

/***
 *** Creates the simple application window with one
 *** drawing area that has an OpenGL-capable visual.
 ***/
static GtkWidget *
create_window (GdkGLConfig *glconfig)
{
  GtkWidget *window;
  GtkWidget *vbox;
  GtkWidget *drawing_area;
  GtkWidget *menu;
  GtkWidget *button;

  /*
   * Top-level window.
   */

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), DEFAULT_TITLE);

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

  /* Connect signal handlers to the window */
  g_signal_connect (G_OBJECT (window), "delete_event",
                    G_CALLBACK (gtk_main_quit), NULL);

  /*
   * VBox.
   */

  vbox = gtk_vbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (window), vbox);
  gtk_widget_show (vbox);

  /*
   * Drawing area to draw OpenGL scene.
   */

  drawing_area = gtk_drawing_area_new ();
  gtk_widget_set_size_request (drawing_area, DEFAULT_WIDTH,
DEFAULT_HEIGHT);

  /* Set OpenGL-capability to the widget */
  gtk_widget_set_gl_capability (drawing_area,
                                glconfig,
                                NULL,
                                TRUE,
                                GDK_GL_RGBA_TYPE);

  gtk_widget_add_events (drawing_area,
                         GDK_BUTTON1_MOTION_MASK    |
                         GDK_BUTTON2_MOTION_MASK    |
                         GDK_BUTTON_PRESS_MASK      |
                         GDK_VISIBILITY_NOTIFY_MASK);

  /* Connect signal handlers to the drawing area */
  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);
  g_signal_connect (G_OBJECT (drawing_area), "unrealize",
                    G_CALLBACK (unrealize), NULL);

  g_signal_connect (G_OBJECT (drawing_area), "motion_notify_event",
                    G_CALLBACK (motion_notify_event), NULL);
  g_signal_connect (G_OBJECT (drawing_area), "button_press_event",
                    G_CALLBACK (button_press_event), NULL);

  /* key_press_event handler for top-level window */
  g_signal_connect_swapped (G_OBJECT (window), "key_press_event",
                            G_CALLBACK (key_press_event), drawing_area);

  /* For timeout function. */
  g_signal_connect (G_OBJECT (drawing_area), "map_event",
                    G_CALLBACK (map_event), NULL);
  g_signal_connect (G_OBJECT (drawing_area), "unmap_event",
                    G_CALLBACK (unmap_event), NULL);
  g_signal_connect (G_OBJECT (drawing_area), "visibility_notify_event",
                    G_CALLBACK (visibility_notify_event), NULL);

  gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);

  gtk_widget_show (drawing_area);

  /*
   * Popup menu.
   */

  menu = create_popup_menu (drawing_area);

  g_signal_connect_swapped (G_OBJECT (drawing_area), "button_press_event",
                            G_CALLBACK (button_press_event_popup_menu),
menu);

  /*
   * Simple quit button.
   */

  button = gtk_button_new_with_label ("Quit");

  g_signal_connect (G_OBJECT (button), "clicked",
                    G_CALLBACK (gtk_main_quit), NULL);

  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);

  gtk_widget_show (button);

  return window;
}


/**************************************************************************
 * The following section contains utility function definitions.

**************************************************************************/

/***
 *** Configure the OpenGL framebuffer.
 ***/
static GdkGLConfig *
configure_gl (void)
{
  GdkGLConfig *glconfig;

  /* Try double-buffered visual */
  glconfig = gdk_gl_config_new_by_mode (
               static_cast<GdkGLConfigMode>(
                 GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE
               )
             );

  if (glconfig == NULL) {
    g_print ("\n*** Cannot find the double-buffered visual.\n");
    g_print ("\n*** Trying single-buffered visual.\n");

    /* Try single-buffered visual */
    glconfig = gdk_gl_config_new_by_mode (
                 static_cast<GdkGLConfigMode>(
                   GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH
                 )
               );

    if (glconfig == NULL) {
      g_print ("*** No appropriate OpenGL-capable visual found.\n");
      exit (1);
    }
  }

  return glconfig;
}


/**************************************************************************
 * The main function is rather trivial.

**************************************************************************/

int main(int argc, char *argv[])
{
  GtkWidget *window;
  GdkGLConfig *glconfig;

  SoDB::init();
  SoNodeKit::init();
  SoInteraction::init();

  /* Initialize GTK. */
  gtk_init (&argc, &argv);

  /* Initialize GtkGLExt. */
  gtk_gl_init (&argc, &argv);

  /* Configure OpenGL framebuffer. */
  glconfig = configure_gl ();

  SoSeparator* root = new SoSeparator;
  root->ref();
  SoPerspectiveCamera * camera = new SoPerspectiveCamera;
  root->addChild(camera);
  SoDirectionalLight* light = new SoDirectionalLight;
  light->direction.setValue(0.0f, 0.0f, -100.0f);
  root->addChild(light);
  SoDrawStyle * drawstyle = new SoDrawStyle;
  drawstyle->style.setValue(0);
  root->addChild(drawstyle);
  root->addChild(commongraph());

  scenemanager = new SoSceneManager;
  scenemanager->setBackgroundColor(SbColor(0.2f, 0.2f, 0.2f));
  scenemanager->activate();
  camera->viewAll(root, scenemanager->getView****tRegion());
  scenemanager->setSceneGraph(root);

  SoDB::setRealTimeInterval(1/220.0);

  /* Create and show the application window. */
  window = create_window (glconfig);
  gtk_widget_show (window);
  scenemanager->setRenderCallback(redraw_cb, window);

  gtk_main ();

  root->unref();
  delete scenemanager;
  return 0;
}


/**************************************************************************
 * End of file.

**************************************************************************/

#-*-Makefile-*-
############################################################################
#
GTKGLEXTINCLUDES = -I/usr/include/gtkglext-1.0/gtk
-I/usr/include/gtkglext-1.0/gdk -I/usr/include/gtkglext-1.0
-I/usr/lib/gtkglext-1.0/include -I/usr/include/gtk-2.0
-I/usr/lib/gtk-2.0/include -I/usr/include/pango-1.0
-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/cairo
-I/usr/include/atk-1.0

GTKGLEXTDEFINES = -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED
-DGDK_PIXBUF_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED

GTKGLEXTCFLAGS = $(GTKGLEXTINCLUDES) $(GTKGLEXTDEFINES)

GTKGLEXTLIBS = $(shell pkg-config gtkglext-1.0 --libs)

COIN_CXXFLAGS = $(shell coin-config --cppflags)
COIN_LIBS = $(shell coin-config --libs)

CXXFLAGS = -ggdb -Wall $(GTKGLEXTCFLAGS) $(COIN_CXXFLAGS)
LIBS = -ggdb $(GTKGLEXTLIBS) $(COIN_LIBS)

CXX = g++

all:: glextiv

glextiv:: glextiv.o
	$(CXX) $(LIBS) -o glextiv glextiv.o
 




 1 Posts in Topic:
gtkglext bug
Bernard Cupic <Bernard  2006-12-14 15:04:51 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Fri Aug 29 13:11:36 CDT 2008.