[Gtk-sharp-list] OpenGL... Eureka!

Luciano martorella@sssup.it
Mon, 27 Oct 2003 11:32:56 +0100


 Hi!!

  After days of GTK studies (i'm a newbie of GTK/GDK..), after long
hours of "printf debugging" at C, C++ and C# level, after shuffles of
Marilyn Manson... the Gl Extension work in GTK-Sharp!

 I have based my work *only* on GtkGlExt project
(http://gtkglext.sourceforge.net/): the GtkGlArea project (based on
GtkGlExt) is discontinued, the GtkGl-sharp project is based on GlArea.

-- THE MAIN PROBLEM:
 The GtkGl team have developed a great and complete OpenGl extension
for GTK: every GTK-widget can have GL extension for drawing. This, perhaps,
is *too much* complete...
 They modifies the GTK Widget interface, adding few methods for GL
interaction. Power of OOP in C... :)  This work is not so clean, direct
porting (1:1) in C# is nearly impossible.
 The GtkGlArea developers builds a special widget (GlArea), the only one
with OpenGl capabilities. But the project is not mantained and buggy...
 Mumble mumble...
 I want to find a solution similar to GlArea, without writing a single C
linecode, directly realized in C#.


-- TESTING AROUND:
 The GlExt has two layers: GTK (with the "extension" of GTK::Widget) and
GDK.
 I have feed the GAPI->Generator with *only* the GDK layer, and...
magically it works!! Now i have a "gdkgl-sharp.dll" with all the GL
extensions working... well.
 And for upper GTK level?


-- THE SOLUTION (alpha):
 I have wrote a small class (GlWidget) *not derived from any object*. The
constructor take a reference of associated (and well constructed) Widget:

----------- <CODE>
          public GlWidget (Widget widget,
                           GdkGLConfig glconfig,
                           GdkGLContext share_list,
                           bool direct,
                           GdkGLRenderType render_type);
</CODE> ---------

 and through this value "widget", the class initialize the GL portion of
widget with "gtk_widget_set_gl_capability".

  This class implements also various wrappings of major GL access function:

----------- <CODE>
 static extern IntPtr gtk_widget_get_gl_window (IntPtr raw);
 static extern IntPtr gtk_widget_get_gl_context (IntPtr raw);
 static extern IntPtr gtk_widget_get_gl_config (IntPtr o);
 static extern bool gdk_gl_drawable_gl_begin (IntPtr drawable, IntPtr
context);
 static extern void gdk_gl_drawable_gl_end (IntPtr drawable);
 static extern void gdk_gl_drawable_swap_buffers (IntPtr gldrawable);
 static extern bool gdk_gl_drawable_is_double_buffered (IntPtr gldrawable);
</CODE> ---------


 This solution is very similar at GlArea idea, but 1) is written
directly in C#, over GTK# and my porting of gdkgl-sharp; and 2) is
extendible at *all* widget classes.

 An example of "DrawingArea" GL-Widget:

----------- <CODE>

public class GlScene : Gtk.DrawingArea
{
  GlWidget m_glWidget;

  public GlScene (GdkGLConfig glconfig)
  {
     // Handle of GL wrapper class
     m_glWidget = new GlWidget (this, glconfig);

     // Events
     ExposeEvent += new ExposeEventHandler (OnExpose);
     ConfigureEvent += new ConfigureEventHandler (OnConfigure);
     Realized += new EventHandler (OnRealize);
  }

  static private void OnExpose (object o, ExposeEventArgs args)
  {
    GlScene owner = (GlScene)o;
    GdkGLContext glcontext = owner.m_glWidget.GlContext;
    owner.m_glWidget.GlStart (glcontext);

    [... GL calls through Tao ...]

    owner.m_glWidget.GlStop (glcontext);
  }

  ...
}

</CODE> ---------


 The OpenGL contexts are shareable each others (i.e.: for texture sharing),
and the "drawing" entity is a Gdk::GL::Window, which implement the interface
Gdk::GL::Drawable.
 I repeat, all the GDK layer is automagically generated, thanks to
GAPI->Generator.

 I write a small "gears" demo program, but i receive a crash after few
seconds (perhaps one hundred of frames):

Unhandled Exception: System.NullReferenceException: A null value was found
where an object instance was required
in (unmanaged) (wrapper managed-to-native) GLib.Object:g_object_unref
(intptr)
in <0x00004> (wrapper managed-to-native) GLib.Object:g_object_unref (intptr)
in <0x0014a> GLib.Object:PerformQueuedUnrefs ()
in <0x0001b> (wrapper native-to-managed) GLib.Object:PerformQueuedUnrefs ()
in (unmanaged) (wrapper managed-to-native) Gtk.Application:gtk_main ()
in <0x00004> (wrapper managed-to-native) Gtk.Application:gtk_main ()
in <0x00007> Gtk.Application:Run ()
in <0x00313> .Silly:Main (string[])

[MONO and MCS 0.28 on Linux]

 I think this is a nasty problem due to imperfect porting of GdkGl, or due
to errors using the GTK message queue, i'm working on this (and i'm studying
GTK *and* GTK#)...

 The question is:
 I'm on the right way? I shall continue? Suggestions?

 Happy GTK# at all!!


P.S: Excuse me for incorrect english! Someone want to "debug" my post? :)))

-----------------------
-| Luciano from PISA  \-
---------------------------------
http://net.supereva.it/noinetcorp
---------------------------------