[GtkGLExt] GDK + GtkGLExt code example



Hello. I have written this code example, for using GDK, GtkGLExt, and without using GTK+. It might be useful if you include it in the examples directory.

Here's ya link:

http://www.gtkforums.com/viewtopic.php?p=10586#10586

Here's ya code: (in case you don't believe me :D )

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

#include "vec.h"

// uncomment this to enable blocking behavior
// that means that the cpu is used minimally (only when an event occurs)
// leave it disabled for full FPS (like most games)
//#define BLOCKING

GdkGLWindow *glwin = NULL;
GdkGLContext *glcontext = NULL;
#ifdef BLOCKING
GMainLoop *mainloop;
#else
gboolean done = false;
#endif
int width = 800, height = 600;

#define TILESIZE 32
int tilex, tiley;
#define XTILES 128
#define YTILES 128
unsigned char tiles[YTILES * XTILES];

void resize(int w, int h, GdkGLDrawable *drawable) {
    if(gdk_gl_drawable_gl_begin(drawable, glcontext)) {
        glViewport(0, 0, w, h);
        width = w; height = h;
        gdk_gl_drawable_gl_end(drawable);
    }
}

void draw(GdkGLDrawable *drawable) {
    if(!gdk_gl_drawable_gl_begin(drawable, glcontext)) return;

    glClearColor(.1, .3, .5, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, width, height, 0, -1, 1); // this corresponds to the window coordinates 1:1, so we don't have to do any coordinate translation
   
glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glBegin(GL_QUADS);
    glColor3f(.9, .5, .2);
    for(int x = 0; x < XTILES; x++) {
        for(int y = 0; y < YTILES; y++) {
            if(tiles[x + y * XTILES]) {
                glVertex2i(x * TILESIZE, y * TILESIZE);
                glVertex2i((x + 1) * TILESIZE, y * TILESIZE);
                glVertex2i((x + 1) * TILESIZE, (y + 1) * TILESIZE);
                glVertex2i(x * TILESIZE, (y + 1) * TILESIZE);
            }
        }
    }
    glEnd();
    glBegin(GL_LINE_LOOP);
        glVertex2i(tilex * TILESIZE, tiley * TILESIZE);
        glVertex2i((tilex + 1) * TILESIZE, tiley * TILESIZE);
        glVertex2i((tilex + 1) * TILESIZE, (tiley + 1) * TILESIZE);
        glVertex2i(tilex * TILESIZE, (tiley + 1) * TILESIZE);
    glEnd();

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

    gdk_gl_drawable_gl_end(drawable);
}

static void toggle_tile(int tx, int ty) {
    if(tx >= 0 && tx < XTILES && ty >= 0 && ty <= YTILES)
        tiles[tx + XTILES * ty] ^= 1;
}
static void event_func(GdkEvent *ev, gpointer data) {
    GdkGLDrawable *drawable = gdk_window_get_gl_drawable(ev->any.window);
    switch(ev->type) {
#ifdef BLOCKING
        case GDK_EXPOSE: // when in blocking mode, only redraw when the window is exposed (damaged)
           
draw(drawable);
            break;
#endif
       
case GDK_DELETE:
#ifdef BLOCKING
            g_main_loop_quit(mainloop);
#else
           
done = true;
#endif
           
break;
        case GDK_MOTION_NOTIFY:
       
{
            int tx = ev->motion.x / TILESIZE;
            int ty = ev->motion.y / TILESIZE;
            if(tilex != tx || tiley != ty) {
                tilex = tx; tiley = ty;
                if(ev->motion.state & GDK_BUTTON1_MASK) toggle_tile(tx, ty);
                draw(drawable);
            }
            break;
        }
        case GDK_BUTTON_PRESS:
           
if(ev->button.button == 1) {
                int tx = ev->button.x / TILESIZE;
                int ty = ev->button.y / TILESIZE;
                toggle_tile(tx, ty);
#ifdef BLOCKING
                draw(drawable);
#endif
           
}
            break;
        case GDK_CONFIGURE:
           
resize(ev->configure.width, ev->configure.height, drawable);
#ifdef BLOCKING
            draw(drawable);
#endif
           
break;
    }
}

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_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_STRUCTURE_MASK | GDK_EXPOSURE_MASK;
    attr.window_type = GDK_WINDOW_TOPLEVEL;
    attr.wclass = GDK_INPUT_OUTPUT;
    attr.width = width;
    attr.height = height;
    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);

#ifdef BLOCKING
    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);
#else
   
while(!done) {
        while(gdk_events_pending()) {
            GdkEvent *ev = gdk_event_get();
            if(ev) {
                event_func(ev, NULL);
                gdk_event_free(ev);
            }
        }
        draw(GDK_GL_DRAWABLE(glwin));
    }
#endif

   
gdk_gl_window_destroy(glwin);
    gdk_window_destroy(win);

    return 0;
}



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