From dccc3b445b3c67322eb4f071df46bff02fac89ed Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Mon, 24 Jan 2011 03:33:30 +0000 Subject: [PATCH] Add GritsTester for debugging GritsObjects The "tester" object is similar to a stripped down version of GisOpenGL/GisViewer. It is intended for debugging GisObjects during development. It displays one or more objects centered in the view and and supports panning/moving around to inspect various parts of the object. --- examples/tester.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++ examples/tester.h | 56 +++++++++++++ 2 files changed, 265 insertions(+) create mode 100644 examples/tester.c create mode 100644 examples/tester.h diff --git a/examples/tester.c b/examples/tester.c new file mode 100644 index 0000000..22032ee --- /dev/null +++ b/examples/tester.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2009-2010 Andy Spencer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tester.h" + +/************* + * Callbacks * + *************/ +static gboolean on_expose(GritsTester *tester, GdkEventExpose *event, gpointer _) +{ + g_debug("GritsTester: on_expose"); + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearDepth(1.0); + glEnable(GL_BLEND); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + //glDisable(GL_DEPTH_TEST); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + /* Lighting */ + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + float light_ambient[] = {0.1f, 0.1f, 0.1f, 1.0f}; + float light_diffuse[] = {0.6f, 0.6f, 0.8f, 1.0f}; + float light_position[] = {-40.0f, 80.0f, 40.0f, 1.0f}; + glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT0, GL_POSITION, light_position); + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glPopMatrix(); + + glColor4f(1.0f, 1.0f, 1.0f, 0.5f); + + /* Draw */ + gdk_gl_draw_cube(FALSE, 2); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + for (GList *cur = tester->objects; cur; cur = cur->next) + grits_object_draw(cur->data, NULL); + if (tester->wireframe) { + glDisable(GL_LIGHTING); + glEnable(GL_POLYGON_OFFSET_LINE); + glPolygonOffset(-1,0); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + for (GList *cur = tester->objects; cur; cur = cur->next) + grits_object_draw(cur->data, NULL); + } + + /* Flush */ + GdkGLDrawable *gldrawable = gdk_gl_drawable_get_current(); + gdk_gl_drawable_swap_buffers(gldrawable); + return FALSE; +} + +static gboolean on_key_press(GritsTester *tester, GdkEventKey *event, gpointer _) +{ + g_debug("GritsTester: on_key_press"); + guint kv = event->keyval; + gdouble model[16]; + glGetDoublev(GL_MODELVIEW_MATRIX, model); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + if (kv == GDK_q) gtk_main_quit(); + else if (kv == GDK_w) tester->wireframe = !tester->wireframe; + else if (kv == GDK_h) glTranslated( 0.1, 0, 0); + else if (kv == GDK_l) glTranslated(-0.1, 0, 0); + else if (kv == GDK_j) glTranslated( 0, 0.1, 0); + else if (kv == GDK_k) glTranslated( 0, -0.1, 0); + else if (kv == GDK_i) glTranslated( 0, 0, 0.1); + else if (kv == GDK_o) glTranslated( 0, 0, -0.1); + else if (kv == GDK_H) glRotated(-5, 0,1,0); + else if (kv == GDK_L) glRotated( 5, 0,1,0); + else if (kv == GDK_J) glRotated( 5, 1,0,0); + else if (kv == GDK_K) glRotated(-5, 1,0,0); + else if (kv == GDK_I) glRotated(-5, 0,0,1); + else if (kv == GDK_O) glRotated( 5, 0,0,1); + glMultMatrixd(model); + + gtk_widget_queue_draw(GTK_WIDGET(tester)); + return FALSE; +} + +static gboolean on_configure(GritsTester *tester, GdkEventConfigure *event, gpointer _) +{ + g_debug("GritsTester: on_configure"); + + double width = GTK_WIDGET(tester)->allocation.width; + double height = GTK_WIDGET(tester)->allocation.height; + + /* Setup OpenGL Window */ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + double ang = atan(height/FOV_DIST); + gluPerspective(rad2deg(ang)*2, width/height, 0.001, 100); + + return FALSE; +} + +static void on_realize(GritsTester *tester, gpointer _) +{ + g_debug("GritsTester: on_realize"); + + /* Start OpenGL */ + GdkGLContext *glcontext = gtk_widget_get_gl_context(GTK_WIDGET(tester)); + GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(tester)); + if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) + g_assert_not_reached(); + + /* Connect signals and idle functions now that opengl is fully initialized */ + g_object_set(tester, "can-focus", TRUE, NULL); + gtk_widget_add_events(GTK_WIDGET(tester), GDK_KEY_PRESS_MASK); + g_signal_connect(tester, "configure-event", G_CALLBACK(on_configure), NULL); + g_signal_connect(tester, "expose-event", G_CALLBACK(on_expose), NULL); + g_signal_connect(tester, "key-press-event", G_CALLBACK(on_key_press), NULL); + + /* Re-queue resize incase configure was triggered before realize */ + gtk_widget_queue_resize(GTK_WIDGET(tester)); + + /* Setup model view matrix */ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslated(0, 0, -2); +} + +/*********** + * Methods * + ***********/ +gpointer grits_tester_add(GritsTester *tester, GritsObject *object) +{ + g_debug("GritsTester: add"); + gtk_widget_queue_draw(GTK_WIDGET(tester)); + object->viewer = (void*)tester; + return tester->objects = g_list_prepend(tester->objects, object); +} + +GritsObject *grits_tester_remove(GritsTester *tester, gpointer _ref) +{ + g_debug("GritsTester: remove"); + GList *ref = _ref; + GritsObject *object = ref->data; + tester->objects = g_list_remove_link(tester->objects, ref); + return object; +} + +GritsTester *grits_tester_new() +{ + g_debug("GritsTester: new"); + GritsTester *tester = g_object_new(GRITS_TYPE_TESTER, NULL); + return tester; +} + +/**************** + * GObject code * + ****************/ +G_DEFINE_TYPE(GritsTester, grits_tester, GTK_TYPE_DRAWING_AREA); +static void grits_tester_init(GritsTester *tester) +{ + g_debug("GritsTester: init"); + tester->objects = NULL; + + /* Set OpenGL before "realize" */ + GdkGLConfig *glconfig = gdk_gl_config_new_by_mode( + GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH | + GDK_GL_MODE_DOUBLE | GDK_GL_MODE_ALPHA); + if (!glconfig) + g_error("Failed to create glconfig"); + if (!gtk_widget_set_gl_capability(GTK_WIDGET(tester), + glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE)) + g_error("GL lacks required capabilities"); + g_object_unref(glconfig); + + /* Finish OpenGL init after it's realized */ + g_signal_connect(tester, "realize", G_CALLBACK(on_realize), NULL); +} +static void grits_tester_class_init(GritsTesterClass *klass) +{ + g_debug("GritsTester: class_init"); +} diff --git a/examples/tester.h b/examples/tester.h new file mode 100644 index 0000000..74d84aa --- /dev/null +++ b/examples/tester.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009-2010 Andy Spencer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PUReOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GRITS_TESTER_H__ +#define __GRITS_TESTER_H__ + +#include +#include + +#include + +/* Type macros */ +#define GRITS_TYPE_TESTER (grits_tester_get_type()) +#define GRITS_TESTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GRITS_TYPE_TESTER, GritsTester)) +#define GRITS_IS_TESTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GRITS_TYPE_TESTER)) +#define GRITS_TESTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GRITS_TYPE_TESTER, GritsTesterClass)) +#define GRITS_IS_TESTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GRITS_TYPE_TESTER)) +#define GRITS_TESTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GRITS_TYPE_TESTER, GritsTesterClass)) + +typedef struct _GritsTester GritsTester; +typedef struct _GritsTesterClass GritsTesterClass; + +struct _GritsTester { + GtkDrawingArea parent_instance; + + /* instance members */ + gboolean wireframe; + GList *objects; +}; + +struct _GritsTesterClass { + GtkDrawingAreaClass parent_class; +}; + +GType grits_tester_get_type(void); + +/* Methods */ +GritsTester *grits_tester_new(); +gpointer grits_tester_add(GritsTester *tester, GritsObject *object); +GritsObject *grits_tester_remove(GritsTester *tester, gpointer ref); + +#endif -- 2.43.2