You are here

GtkGLArea3 for Windows (with Vala VAPI)

Objectives : display an OpenGL context in a GTK+ window, under Windows.

Some months ago, I needed to render a 3D scene (which was, of course, using OpenGL) in a GTK+3 window. I remembered very well it was possible -using some third-party libraries- and after a bit of googling, I found two libs :
- GtkGLExt, three years old
- GtkGLArea, four years old !

They both expose more or less the same API : you create a dedicated widget on which OpenGL rendering will be possible ; there's some automatic management for moving and resizing, however you're supposed to manage some cases (scaling e.g.) manually.
To my disappointment, however, they were both targeting good ol' GTK+2...

So I decided to make some modifications to the GtkGLArea code, and finally, look at what we have here :


GtkGLArea2/3 for Windows

I wrote the VAPIs, packaged the libs and made them available through the ValaWinPKG repository.
Here's how to use them.

Prerequisites

If not already present, we'll install the latest Vala bundle for Windows and ValaWinPKG :

- vala-0.20.1_(GTK+-3.6.4)(TARNYKO).exe (74.4 Mb)
- ValaWinPKG_0.9.d.exe (7.76 Mb)

1) Install GtkGLArea3

We run ValaWinPKG from the Windows start menu.
We then ckeck the GtkGLArea3 package and click on "Update !".



2) Compile a simple Vala example

We will first render a GL scene together with a control.
Have a look at the attached source code ; the important parts are :

var glarea = new GLArea (attrlist);
glarea.set_size_request (100, 100);
glarea.realize.connect (on_glarea_realize_event);
glarea.draw.connect (on_glarea_draw_event);

We create a GLArea widget, define its size to 100x100, and attach 2 callbacks to it : realize and draw.
The first one, realize, will be executed once, at the beginning, when the GLArea is rendered and will define the GL scene properties :

void on_glarea_realize_event (Widget widget)
{
[...]
   if (glarea.make_current () == true)
   {
    [...]
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glOrtho (0,100, 100,0, -1,1);
    glMatrixMode (GL_MODELVIEW);
   }

The second one, draw, will be called and re-called everytime the window is refreshed or resized. It's here that we are suposed to draw our scene :

bool on_glarea_draw_event (Widget widget, Cairo.Context cr)
{
[...]
   if (glarea.make_current () == true)
   {
    [...]
    // Draw simple triangle
    glBegin (GL_TRIANGLES);
    glVertex2f (10,10);
    glVertex2f (10,90);
    glVertex2f (90,90);
    glEnd ();
   
    // Swap backbuffer to front
    glarea.swap_buffers ();

Note the final call to glarea.swap_buffers (), which will refresh the screen. Nothing will be rendered without it.
Note that we, in both cases, use the glarea.make_current () both as a test (is the context still valid ?) and as a "refocus" (it's this context that we want to refresh later !).

Now just to compile and run it with :
valac --pkg gtkgl-3.0 gtkglarea3-simple.vala -o gtkglarea3-simple.exe
gtkglarea3-simple.exe


Here we go !

3) Compile a more complex Vala example (with fonts !)

This other source code is less spectacular but introduces the widely-used font feature. Look at :

GLuint fontbase;
fontbase = glGenLists (128);
Pango.FontDescription fontdesc = Pango.FontDescription.from_string ("Sans 10");
Gdk.gl_use_pango_font (fontdesc, 0, 128, fontbase);

We use a GLuint to refer to the OpenGL font list ; then we create a typical-GTK+ font, Sans with size 10, and link the two together.
Later, we'll really display a text with :

glColor3f (1,1,0);
glRasterPos2f ((100-charwidth*fonttext.length)/2, (100-charheight)/2);
glListBase (fontbase);
glCallLists (fonttext.length, GL_UNSIGNED_BYTE, (GL.GLvoid[])fonttext);

We define a font color (red + green = yellow), position the text in the center -thanks to a char width/height calculation we made before, and use glListBase/glCallLists () to display the fonttext string, which really contains the "GTKGLAREA" text.

And effectively, when compiling :
valac --pkg gtkgl-3.0 gtkglarea3-font.vala -o gtkglarea3-font.exe
gtkglarea3-font.exe


Nice !

Plans for the future

The Linux port is stll WIP (its font API is a lot more complicated) ; will be released soon. However, without saying too much, something that fast works...


:-)
Wayland, here we are !

(PS : During the meantime, I learnt that GtkGLExt had a work-in-progress GTK+3 port, too ! My bad)

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.