/************************************************************************** * scribble-gl.c * * This is an OpenGL version of the scribble program from the Gtk library. * All the drawing here is obviously done using OpenGL. * * This program is in the public domain and you are using it at * your own risk. * * Alif Wahid, * May 2003. **************************************************************************/ /************************************************************************** * Header file inclusions. **************************************************************************/ #include #include #include #include #include #include #include /*** Use OpenGL extensions. ***/ /* #include */ #ifdef G_OS_WIN32 #define WIN32_LEAN_AND_MEAN 1 #include #endif #include #include /************************************************************************** * 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 200 #define DEFAULT_HEIGHT 200 #define DEFAULT_TITLE "Scribble-GL" /************************************************************************** * Global variable declarations. **************************************************************************/ /* Structure for storing points of button clicks and drag motion. */ typedef struct _Point Point; struct _Point { gint x; gint y; }; /* List of all the brush stroke points. */ static GList* brushStrokeList = NULL; /* Thickness of the brush strokes. */ static gint thickness = 5; /************************************************************************** * The following section contains the function prototype declarations. **************************************************************************/ static GdkGLConfig *configure_gl (void); static GtkWidget *create_window (GdkGLConfig *glconfig); /************************************************************************** * 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); /*** OpenGL BEGIN ***/ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return; /*** Fill in the details here. ***/ glClearColor(1.0,1.0,1.0,1.0); glClearDepth(1.0); gdk_gl_drawable_gl_end (gldrawable); /*** OpenGL END ***/ return; } /*** *** 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 viewport 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); guint count; GLfloat w = widget->allocation.width; GLfloat h = widget->allocation.height; /*** OpenGL BEGIN ***/ if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) return FALSE; /* Reallocate the brush stroke list. */ for (count=0; countx + thickness, coord->y - thickness, coord->x - thickness, coord->y + thickness); } /* 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; } /*** *** 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) { Point* coord=NULL; if (event->state & GDK_BUTTON1_MASK) { coord = g_malloc(sizeof(Point)); coord->x = event->x; coord->y = widget->allocation.height - event->y; brushStrokeList = g_list_append(brushStrokeList, coord); gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE); return TRUE; } 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) { Point* coord=NULL; if (event->button == 1) { coord = g_malloc(sizeof(Point)); coord->x = event->x; coord->y = widget->allocation.height - event->y; brushStrokeList = g_list_append(brushStrokeList, coord); gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE); return TRUE; } return FALSE; } static void quit_cb (GtkWidget* widget, gpointer data) { guint count; /* Free the resources occupied by brushStrokeList. */ for (count=0; count