[grits] Add GL bindings example program



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]