[grits] Add GL bindings example program
- From: Andy Spencer <andys src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [grits] Add GL bindings example program
- Date: Sun, 26 Jun 2011 23:30:16 +0000 (UTC)
commit c1a7ca70d4397831cd24d6fcc544d276ae203c3b
Author: Andy Spencer <andy753421 gmail com>
Date: Sat Jun 18 22:16:27 2011 +0000
Add GL bindings example program
Basic standalone program that draws a circle using:
- Cairo
- GktGLExt
- GLX (X11)
- WGL (Win32)
- CGL (Mac OS, not implemented)
examples/gl/gl.c | 311 ++++++++++++++++++++++++++++++++++++++++++++++++++++
examples/gl/mkfile | 11 ++
2 files changed, 322 insertions(+), 0 deletions(-)
---
diff --git a/examples/gl/gl.c b/examples/gl/gl.c
new file mode 100644
index 0000000..39fd1e0
--- /dev/null
+++ b/examples/gl/gl.c
@@ -0,0 +1,311 @@
+#include <math.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+//#define USE_CAIRO
+#define USE_GTKGLEXT
+//#define USE_GLX
+//#define USE_WGL
+//#define USE_CGL
+
+/************************
+ * Cairo implementation *
+ ************************/
+#if defined(USE_CAIRO)
+#include <gdk/gdkwin32.h>
+gpointer expose_setup(GtkWidget *widget) { return NULL; }
+gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
+{
+ GtkAllocation alloc;
+ gtk_widget_get_allocation(widget, &alloc);
+ cairo_t *cairo = gdk_cairo_create(gtk_widget_get_window(widget));
+ cairo_set_source_rgb(cairo, 1, 1, 1);
+ cairo_arc(cairo,
+ alloc.x + alloc.width/2,
+ alloc.y + alloc.height/2,
+ MIN(alloc.width/2,alloc.height/2),
+ 0, 2*G_PI);
+ cairo_fill(cairo);
+ return FALSE;
+}
+
+
+/***************************
+ * GtkGlExt implementation *
+ ***************************/
+#elif defined(USE_GTKGLEXT)
+#include <gtk/gtkgl.h>
+#include <GL/gl.h>
+#include <gdk/gdkwin32.h>
+void realize(GtkWidget *widget, gpointer user_data)
+{
+ gdk_window_ensure_native(gtk_widget_get_window(widget));
+}
+gpointer expose_setup(GtkWidget *widget)
+{
+ //GdkGLConfig *glconfig = gdk_gl_config_new_by_mode(
+ // GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH |
+ // GDK_GL_MODE_ALPHA);
+ GdkGLConfig *glconfig = gdk_gl_config_new_by_mode(
+ GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH |
+ GDK_GL_MODE_ALPHA | GDK_GL_MODE_DOUBLE);
+ gtk_widget_set_gl_capability(widget,
+ glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
+ return NULL;
+}
+gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel(widget);
+ g_message("window: w=%x tl=%x",
+ (guint)GDK_WINDOW_HWND(gtk_widget_get_window(widget)),
+ (guint)GDK_WINDOW_HWND(gtk_widget_get_window(toplevel)));
+
+ GtkAllocation alloc;
+ gtk_widget_get_allocation(widget, &alloc);
+ GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
+ GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
+ gdk_gl_drawable_gl_begin(gldrawable, glcontext);
+ glViewport(0, 0, alloc.width, alloc.height);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor3f(1.0, 1.0, 1.0);
+ glBegin(GL_TRIANGLE_FAN);
+ glVertex2f(0.0, 0.0);
+ for (double i = 0; i < 2*G_PI; i+=(2*G_PI)/100)
+ glVertex2d(sin(i), cos(i));
+ glEnd();
+ gdk_gl_drawable_swap_buffers(gldrawable);
+ gdk_gl_drawable_gl_end(gldrawable);
+ return FALSE;
+}
+
+
+/**********************
+ * X11 implementation *
+ **********************/
+#elif defined(USE_GLX)
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <gdk/gdkx.h>
+void realize(GtkWidget *widget, gpointer user_data)
+{
+ gdk_window_ensure_native(gtk_widget_get_window(widget));
+}
+gpointer expose_setup(GtkWidget *widget)
+{
+ GdkScreen *screen = gdk_screen_get_default();
+ Display *xdisplay = GDK_SCREEN_XDISPLAY(screen);
+ gint nscreen = GDK_SCREEN_XNUMBER(screen);
+
+ /* Create context */
+ int attribs[] = {GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_ALPHA_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ GLX_DEPTH_SIZE, 1,
+ None};
+ XVisualInfo *xvinfo = glXChooseVisual(xdisplay, nscreen, attribs);
+ GLXContext context = glXCreateContext(xdisplay, xvinfo, 0, False);
+
+ /* Fix up colormap */
+ GdkVisual *visual = gdk_x11_screen_lookup_visual(screen, xvinfo->visualid);
+ GdkColormap *cmap = gdk_colormap_new(visual, FALSE);
+ gtk_widget_set_colormap(widget, cmap);
+
+ /* Disable GTK double buffering */
+ gtk_widget_set_double_buffered(widget, FALSE);
+
+ return context;
+}
+gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, GLXContext context)
+{
+ /* Make current */
+ Display *xdisplay = GDK_SCREEN_XDISPLAY(gdk_screen_get_default());
+ Window xwindow = GDK_WINDOW_XID(gtk_widget_get_window(widget));
+ glXMakeCurrent(xdisplay, xwindow, context);
+
+ GtkWidget *toplevel = gtk_widget_get_toplevel(widget);
+ g_message("window: w=%x tl=%x",
+ (guint)GDK_WINDOW_XID(gtk_widget_get_window(widget)),
+ (guint)GDK_WINDOW_XID(gtk_widget_get_window(toplevel)));
+
+ /* Drawing */
+ GtkAllocation alloc;
+ gtk_widget_get_allocation(widget, &alloc);
+ glViewport(0, 0, alloc.width, alloc.height);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor3f(1.0, 1.0, 1.0);
+ glBegin(GL_TRIANGLE_FAN);
+ glVertex2f(0.0, 0.0);
+ for (double i = 0; i < 2*G_PI; i+=(2*G_PI)/100)
+ glVertex2d(sin(i), cos(i));
+ glEnd();
+
+ /* Swap buffers */
+ glXSwapBuffers(xdisplay, xwindow);
+ return FALSE;
+}
+
+
+/************************
+ * Win32 implementation *
+ ************************/
+#elif defined(USE_WGL)
+#include <GL/gl.h>
+#include <windows.h>
+#include <gdk/gdkwin32.h>
+void realize(GtkWidget *widget, gpointer user_data)
+{
+ gdk_window_ensure_native(gtk_widget_get_window(widget));
+}
+gpointer expose_setup(GtkWidget *widget)
+{
+ /* Create context */
+ //HWND hwnd = GDK_WINDOW_HWND(gtk_widget_get_window(widget));
+ //HGLRC hDC = GetDC(hwnd); // get the device context for window
+ //HDC hRC = wglCreateContext(hDC); // create rendering context
+ //wglMakeCurrent(hDC,hRC); // make rendering context current
+
+ /* Delete context */
+ //wglMakeCurrent(hDC,NULL); // deselect rendering context
+ //wglDeleteContext(hRC); // delete rendering context
+ //PostQuitMessage(0); // send wm_quit
+
+ /* Disable GTK double buffering */
+ gtk_widget_set_double_buffered(widget, FALSE);
+ return FALSE;
+}
+gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel(widget);
+ GdkWindow *window = gtk_widget_get_window(widget);
+ GdkWindow *topwin = gtk_widget_get_window(toplevel);
+ gdk_window_ensure_native(window);
+
+ PIXELFORMATDESCRIPTOR pfo = {}, pfd = {
+ .nSize = sizeof(pfd),
+ .nVersion = 1,
+ .dwFlags = PFD_DRAW_TO_WINDOW // "Correct" way
+ | PFD_SUPPORT_OPENGL
+ | PFD_DOUBLEBUFFER,
+ //.dwFlags = PFD_SUPPORT_OPENGL // Works in wine
+ // | PFD_DRAW_TO_WINDOW,
+ .iPixelType = PFD_TYPE_RGBA,
+ .cColorBits = 24,
+ .cAlphaBits = 8,
+ .cDepthBits = 32,
+ .iLayerType = PFD_MAIN_PLANE,
+ };
+ HWND hwnd = GDK_WINDOW_HWND(window);
+ HDC hDC = GetDC(hwnd); // get the device context for window
+ int pf = ChoosePixelFormat(hDC, &pfd);
+ int st0 = DescribePixelFormat(hDC, pf, sizeof(pfd), &pfo);
+ int st1 = SetPixelFormat(hDC, pf, &pfd);
+ HGLRC hRC = wglCreateContext(hDC);
+ int st2 = wglMakeCurrent(hDC, hRC);
+
+ g_message("dc: %p, %p, %p", hDC, GetDC(hwnd), wglGetCurrentDC());
+
+ g_message("window: pf=%d st=%d,%d,%d dc=%p rc=%p wins=%x=%x!=%x",
+ pf, st0,st1,st2, hDC, hRC, (guint)hwnd,
+ (guint)GDK_WINDOW_HWND(window),
+ (guint)GDK_WINDOW_HWND(topwin));
+
+ g_message("pdfOut: dwFlags=%lx=%lx, ipt=%x=%x, layer=%x=%x, {c,a,d}bits=%d,%d,%d",
+ pfo.dwFlags, pfd.dwFlags,
+ pfo.iPixelType, pfd.iPixelType,
+ pfo.iLayerType, pfd.iLayerType,
+ pfo.cColorBits, pfo.cAlphaBits, pfo.cDepthBits);
+
+ /* Drawing */
+ GtkAllocation alloc = widget->allocation;
+ glViewport(0, 0, alloc.width, alloc.height);
+ g_message("alloc: %dx%d", alloc.width, alloc.height);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor3f(1.0, 1.0, 1.0);
+ glBegin(GL_TRIANGLE_FAN);
+ glVertex2f(0.0, 0.0);
+ for (double i = 0; i < 2*G_PI; i+=(2*G_PI)/100)
+ glVertex2d(sin(i), cos(i));
+ glEnd();
+
+ /* Swap buffers */
+ SwapBuffers(hDC);
+
+ /* Cleanup */
+ wglMakeCurrent(NULL, NULL);
+ wglDeleteContext(hRC);
+ return TRUE;
+}
+
+
+/**************************
+ * Mac OSX implementation *
+ **************************/
+#elif defined(USE_CGL)
+#include <GL/gl.h>
+gpointer expose_setup(GtkWidget *widget)
+{
+ return FALSE;
+}
+gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
+{
+ /* Drawing */
+ GtkAllocation alloc;
+ gtk_widget_get_allocation(widget, &alloc);
+ glViewport(0, 0, alloc.width, alloc.height);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor3f(1.0, 1.0, 1.0);
+ glBegin(GL_TRIANGLE_FAN);
+ glVertex2f(0.0, 0.0);
+ for (double i = 0; i < 2*G_PI; i+=(2*G_PI)/100)
+ glVertex2d(sin(i), cos(i));
+ glEnd();
+ return FALSE;
+}
+
+
+/****************************
+ * Undefined implementation *
+ ****************************/
+#else
+gpointer expose_setup(GtkWidget *widget) { return NULL; }
+gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
+{
+ g_message("unimplemented");
+ return FALSE;
+}
+#endif
+
+
+
+/***************
+ * Common code *
+ ***************/
+gboolean key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
+{
+ if (event->keyval == GDK_q)
+ gtk_main_quit();
+ return FALSE;
+}
+int main(int argc, char **argv)
+{
+ gtk_init_check(&argc, &argv);
+ GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ GtkWidget *box = gtk_vbox_new(FALSE, 5);
+ GtkWidget *draw = gtk_drawing_area_new();
+ GtkWidget *button = gtk_button_new_with_label("Hello, World");
+ gpointer data = expose_setup(draw);
+ g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
+ g_signal_connect(window, "key-press-event", G_CALLBACK(key_press_event), NULL);
+ g_signal_connect(draw, "expose-event", G_CALLBACK(expose_event), data);
+ gtk_widget_set_size_request(draw, 300, 300);
+ gtk_widget_set_size_request(button, -1, 50);
+ gtk_box_pack_start(GTK_BOX(box), draw, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(box), button, FALSE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(window), box);
+ gtk_widget_show_all(window);
+ gtk_main();
+ return 0;
+}
diff --git a/examples/gl/mkfile b/examples/gl/mkfile
new file mode 100644
index 0000000..319416f
--- /dev/null
+++ b/examples/gl/mkfile
@@ -0,0 +1,11 @@
+PROGS=gl
+PKGS=gtk+-2.0 gtkglext-1.0
+LIBS=-lm
+
+#default:V: run
+
+ARCH=i686-pc-mingw32-
+EXT=.exe
+default:V: gl.exe
+ wine $prereq
+<$HOME/lib/mkcommon
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]