From: Andy Spencer Date: Thu, 24 Nov 2011 10:40:50 +0000 (+0000) Subject: OpenGL debugging X-Git-Url: http://pileus.org/git/?p=aweather;a=commitdiff_plain;h=b5ebe63695923933e5bb964dfe66349b8ade09a4 OpenGL debugging --- diff --git a/configure.ac b/configure.ac index 9e072af..53f9330 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ # Init and options -AC_INIT([aweather], [0.6], [andy753421@gmail.com]) +AC_INIT([aweather], [0.6.1-p2], [andy753421@gmail.com]) AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability foreign]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) @@ -14,7 +14,7 @@ PKG_PROG_PKG_CONFIG # Check for required packages PKG_CHECK_MODULES(GLIB, glib-2.0) -PKG_CHECK_MODULES(GRITS, grits >= 0.6) +PKG_CHECK_MODULES(GRITS, grits >= 0.6.1) # Define odd RSL install location AC_CHECK_LIB(rsl, RSL_wsr88d_to_radar, RSL_LIBS="-lrsl") diff --git a/src/Makefile.am b/src/Makefile.am index fb2e6f5..18d6d9a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,7 +4,7 @@ AM_CFLAGS = -Wall --std=gnu99 $(GRITS_CFLAGS) AM_LDFLAGS = -Wl,--export-dynamic \ -Wl,--as-needed -Wl,--no-undefined -bin_PROGRAMS = aweather wsr88ddec +bin_PROGRAMS = aweather wsr88ddec gears aweather_SOURCES = main.c \ aweather-gui.c aweather-gui.h \ aweather-location.c aweather-location.h @@ -18,6 +18,9 @@ aweather_LDADD = $(GRITS_LIBS) wsr88ddec = wsr88ddec.c wsr88ddec_LDADD = $(GLIB_LIBS) -lbz2 +gears = gears.c +gears_LDADD = $(GRITS_LIBS) + if WIN32 dots = .. @@ -40,7 +43,8 @@ CLEANFILES = gmon.out valgrind.out MAINTAINERCLEANFILES = Makefile.in test: all - .libs/aweather -o -d 7 -s KOUN -t '2011-02-01 10:01Z' + .libs/aweather -o -d 7 +#.libs/aweather -o -d 7 -s KOUN -t '2011-02-01 10:01Z' #.libs/aweather -o -d 7 -s KLSX -t '2010-12-31 17:56Z' #.libs/aweather -o -d 7 -s KDGX -t '2010-12-31 23:10Z' #.libs/aweather -o -d 7 -s KDGX -t '1999-05-03 23:51Z' diff --git a/src/gears.c b/src/gears.c new file mode 100644 index 0000000..e41754f --- /dev/null +++ b/src/gears.c @@ -0,0 +1,570 @@ +/* + * 3-D gear wheels. This program is in the public domain. + * + * Brian Paul + */ + +/* Conversion to GLUT by Mark J. Kilgard */ + +/* Conversion to GtkGLExt by Naofumi Yasufuku */ + +#include +#include +#include + +#include +#include + +#include + +#ifdef G_OS_WIN32 +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#include +#include + +/* + * Draw a gear wheel. You'll probably want to call this function when + * building a display list since we do a lot of trig here. + * + * Input: inner_radius - radius of hole at center + * outer_radius - radius at center of teeth + * width - width of gear + * teeth - number of teeth + * tooth_depth - depth of tooth + */ + +static void +gear(GLfloat inner_radius, + GLfloat outer_radius, + GLfloat width, + GLint teeth, + GLfloat tooth_depth) +{ + GLint i; + GLfloat r0, r1, r2; + GLfloat angle, da; + GLfloat u, v, len; + + r0 = inner_radius; + r1 = outer_radius - tooth_depth / 2.0; + r2 = outer_radius + tooth_depth / 2.0; + + da = 2.0 * G_PI / teeth / 4.0; + + glShadeModel(GL_FLAT); + + glNormal3f(0.0, 0.0, 1.0); + + /* draw front face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * G_PI / teeth; + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + if (i < teeth) { + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); + } + } + glEnd(); + + /* draw front sides of teeth */ + glBegin(GL_QUADS); + da = 2.0 * G_PI / teeth / 4.0; + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * G_PI / teeth; + + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); + } + glEnd(); + + glNormal3f(0.0, 0.0, -1.0); + + /* draw back face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * G_PI / teeth; + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + if (i < teeth) { + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + } + } + glEnd(); + + /* draw back sides of teeth */ + glBegin(GL_QUADS); + da = 2.0 * G_PI / teeth / 4.0; + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * G_PI / teeth; + + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + } + glEnd(); + + /* draw outward faces of teeth */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * G_PI / teeth; + + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + u = r2 * cos(angle + da) - r1 * cos(angle); + v = r2 * sin(angle + da) - r1 * sin(angle); + len = sqrt(u * u + v * v); + u /= len; + v /= len; + glNormal3f(v, -u, 0.0); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); + glNormal3f(cos(angle), sin(angle), 0.0); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5); + u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da); + v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da); + glNormal3f(v, -u, 0.0); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); + glNormal3f(cos(angle), sin(angle), 0.0); + } + + glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5); + glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5); + + glEnd(); + + glShadeModel(GL_SMOOTH); + + /* draw inside radius cylinder */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * G_PI / teeth; + glNormal3f(-cos(angle), -sin(angle), 0.0); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + } + glEnd(); + +} + +static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; +static GLint gear1, gear2, gear3; +static GLfloat angle = 0.0; + +static GTimer *timer = NULL; +static gint frames = 0; + +static gboolean is_sync = TRUE; + +static gboolean +draw (GtkWidget *widget, + GdkEventExpose *event, + 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 FALSE; + + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix (); + glRotatef (view_rotx, 1.0, 0.0, 0.0); + glRotatef (view_roty, 0.0, 1.0, 0.0); + glRotatef (view_rotz, 0.0, 0.0, 1.0); + + glPushMatrix (); + glTranslatef (-3.0, -2.0, 0.0); + glRotatef (angle, 0.0, 0.0, 1.0); + glCallList (gear1); + glPopMatrix (); + + glPushMatrix (); + glTranslatef (3.1, -2.0, 0.0); + glRotatef (-2.0 * angle - 9.0, 0.0, 0.0, 1.0); + glCallList (gear2); + glPopMatrix (); + + glPushMatrix (); + glTranslatef (-3.1, 4.2, 0.0); + glRotatef (-2.0 * angle - 25.0, 0.0, 0.0, 1.0); + glCallList (gear3); + glPopMatrix (); + + glPopMatrix (); + + if (gdk_gl_drawable_is_double_buffered (gldrawable)) + gdk_gl_drawable_swap_buffers (gldrawable); + else + glFlush (); + + gdk_gl_drawable_gl_end (gldrawable); + /*** OpenGL END ***/ + + frames++; + + { + gdouble seconds = g_timer_elapsed (timer, NULL); + if (seconds >= 5.0) { + gdouble fps = frames / seconds; + g_print ("%d frames in %6.3f seconds = %6.3f FPS\n", frames, seconds, fps); + g_timer_reset (timer); + frames = 0; + } + } + + return TRUE; +} + +/* new window size or exposure */ +static gboolean +reshape (GtkWidget *widget, + GdkEventConfigure *event, + gpointer data) +{ + GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); + GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); + + GLfloat h = (GLfloat) (widget->allocation.height) / (GLfloat) (widget->allocation.width); + + /*** OpenGL BEGIN ***/ + if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) + return FALSE; + + glViewport (0, 0, widget->allocation.width, widget->allocation.height); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + glFrustum (-1.0, 1.0, -h, h, 5.0, 60.0); + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + glTranslatef (0.0, 0.0, -40.0); + + gdk_gl_drawable_gl_end (gldrawable); + /*** OpenGL END ***/ + + return TRUE; +} + +static void +init(GtkWidget *widget, + gpointer data) +{ + GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); + GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); + + static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0}; + static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0}; + static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0}; + static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0}; + + /*** OpenGL BEGIN ***/ + if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) + return; + + glLightfv (GL_LIGHT0, GL_POSITION, pos); + glEnable (GL_CULL_FACE); + glEnable (GL_LIGHTING); + glEnable (GL_LIGHT0); + glEnable (GL_DEPTH_TEST); + + /* make the gears */ + gear1 = glGenLists (1); + glNewList (gear1, GL_COMPILE); + glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); + gear (1.0, 4.0, 1.0, 20, 0.7); + glEndList (); + + gear2 = glGenLists (1); + glNewList (gear2, GL_COMPILE); + glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); + gear (0.5, 2.0, 2.0, 10, 0.7); + glEndList (); + + gear3 = glGenLists (1); + glNewList (gear3, GL_COMPILE); + glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + gear (1.3, 2.0, 0.5, 10, 0.7); + glEndList (); + + glEnable (GL_NORMALIZE); + + g_print ("\n"); + g_print ("GL_RENDERER = %s\n", (char *) glGetString (GL_RENDERER)); + g_print ("GL_VERSION = %s\n", (char *) glGetString (GL_VERSION)); + g_print ("GL_VENDOR = %s\n", (char *) glGetString (GL_VENDOR)); + g_print ("GL_EXTENSIONS = %s\n", (char *) glGetString (GL_EXTENSIONS)); + g_print ("\n"); + + gdk_gl_drawable_gl_end (gldrawable); + /*** OpenGL END ***/ + + /* create timer */ + if (timer == NULL) + timer = g_timer_new (); + + g_timer_start (timer); +} + +static gboolean +idle (GtkWidget *widget) +{ + angle += 2.0; + + /* Invalidate the whole window. */ + gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE); + + /* Update synchronously (fast). */ + if (is_sync) + gdk_window_process_updates (widget->window, FALSE); + + return TRUE; +} + +static guint idle_id = 0; + +static void +idle_add (GtkWidget *widget) +{ + if (idle_id == 0) + { + idle_id = g_idle_add_full (GDK_PRIORITY_REDRAW, + (GSourceFunc) idle, + widget, + NULL); + } +} + +static void +idle_remove (GtkWidget *widget) +{ + if (idle_id != 0) + { + g_source_remove (idle_id); + idle_id = 0; + } +} + +static gboolean +map (GtkWidget *widget, + GdkEventAny *event, + gpointer data) +{ + idle_add (widget); + + return TRUE; +} + +static gboolean +unmap (GtkWidget *widget, + GdkEventAny *event, + gpointer data) +{ + idle_remove (widget); + + return TRUE; +} + +static gboolean +visible (GtkWidget *widget, + GdkEventVisibility *event, + gpointer data) +{ + if (event->state == GDK_VISIBILITY_FULLY_OBSCURED) + idle_remove (widget); + else + idle_add (widget); + + return TRUE; +} + +/* change view angle, exit upon ESC */ +static gboolean +key (GtkWidget *widget, + GdkEventKey *event, + gpointer data) +{ + switch (event->keyval) + { + case GDK_z: + view_rotz += 5.0; + break; + case GDK_Z: + view_rotz -= 5.0; + break; + case GDK_Up: + view_rotx += 5.0; + break; + case GDK_Down: + view_rotx -= 5.0; + break; + case GDK_Left: + view_roty += 5.0; + break; + case GDK_Right: + view_roty -= 5.0; + break; + case GDK_Escape: + gtk_main_quit (); + break; + default: + return FALSE; + } + + gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE); + + return TRUE; +} + +int +main (int argc, + char *argv[]) +{ + GdkGLConfig *glconfig; + GtkWidget *window; + GtkWidget *vbox; + GtkWidget *drawing_area; + GtkWidget *button; + int i; + + /* + * Init GTK. + */ + + gtk_init (&argc, &argv); + + /* + * Init GtkGLExt. + */ + + gtk_gl_init (&argc, &argv); + + /* + * Command line options. + */ + + for (i = 0; i < argc; i++) + { + if (strcmp (argv[i], "--async") == 0) + is_sync = FALSE; + } + + /* + * Configure OpenGL-capable visual. + */ + + /* Try double-buffered visual */ + glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB | + GDK_GL_MODE_DEPTH | + GDK_GL_MODE_DOUBLE); + if (glconfig == NULL) + { + g_print ("*** Cannot find the double-buffered visual.\n"); + g_print ("*** Trying single-buffered visual.\n"); + + /* Try single-buffered visual */ + glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB | + GDK_GL_MODE_DEPTH); + if (glconfig == NULL) + { + g_print ("*** No appropriate OpenGL-capable visual found.\n"); + exit (1); + } + } + + /* + * Top-level window. + */ + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (window), "gears"); + + /* Get automatically redrawn if any of their children changed allocation. */ + gtk_container_set_reallocate_redraws (GTK_CONTAINER (window), TRUE); + + g_signal_connect (G_OBJECT (window), "delete_event", + G_CALLBACK (gtk_main_quit), NULL); + + /* + * VBox. + */ + + vbox = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (window), vbox); + gtk_widget_show (vbox); + + /* + * Drawing area for drawing OpenGL scene. + */ + + drawing_area = gtk_drawing_area_new (); + gtk_widget_set_size_request (drawing_area, 300, 300); + + /* Set OpenGL-capability to the widget. */ + gtk_widget_set_gl_capability (drawing_area, + glconfig, + NULL, + TRUE, + GDK_GL_RGBA_TYPE); + + gtk_widget_add_events (drawing_area, + GDK_VISIBILITY_NOTIFY_MASK); + + g_signal_connect_after (G_OBJECT (drawing_area), "realize", + G_CALLBACK (init), NULL); + g_signal_connect (G_OBJECT (drawing_area), "configure_event", + G_CALLBACK (reshape), NULL); + g_signal_connect (G_OBJECT (drawing_area), "expose_event", + G_CALLBACK (draw), NULL); + g_signal_connect (G_OBJECT (drawing_area), "map_event", + G_CALLBACK (map), NULL); + g_signal_connect (G_OBJECT (drawing_area), "unmap_event", + G_CALLBACK (unmap), NULL); + g_signal_connect (G_OBJECT (drawing_area), "visibility_notify_event", + G_CALLBACK (visible), NULL); + + g_signal_connect_swapped (G_OBJECT (window), "key_press_event", + G_CALLBACK (key), drawing_area); + + gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0); + + gtk_widget_show (drawing_area); + + /* + * Simple quit button. + */ + + button = gtk_button_new_with_label ("Quit"); + + g_signal_connect (G_OBJECT (button), "clicked", + G_CALLBACK (gtk_main_quit), NULL); + + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + + gtk_widget_show (button); + + /* + * Show window. + */ + + gtk_widget_show (window); + + /* + * Main loop. + */ + + gtk_main (); + + return 0; +} diff --git a/src/main.c b/src/main.c index 55d0ad9..1683023 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -117,16 +118,59 @@ int main(int argc, char *argv[]) {"fullscreen", 'f', 0, G_OPTION_ARG_NONE, &opt_fullscreen, "Open in fullscreen mode", NULL}, {NULL} }; + (void)entries; /* Init */ GError *error = NULL; + + gtk_init(&argc, &argv); + + gtk_gl_init(&argc, &argv); + + g_message("trying to get context - 1: %p\n", + gdk_gl_config_new_by_mode( + GDK_GL_MODE_RGB | + GDK_GL_MODE_DEPTH | + GDK_GL_MODE_DOUBLE)); + + g_message("trying to get context - 2: %p\n", + gdk_gl_config_new_by_mode( + GDK_GL_MODE_RGB | + GDK_GL_MODE_DEPTH | + GDK_GL_MODE_DOUBLE | + GDK_GL_MODE_ALPHA)); + + g_message("trying to get context - 3: %p\n", + gdk_gl_config_new_by_mode( + GDK_GL_MODE_RGBA | + GDK_GL_MODE_DEPTH | + GDK_GL_MODE_DOUBLE | + GDK_GL_MODE_ALPHA)); + + grits_init(&argc, &argv); + g_thread_init(NULL); gdk_threads_init(); - if (!gtk_init_with_args(&argc, &argv, "aweather", entries, NULL, &error)) { - g_print("%s\n", error->message); - g_error_free(error); - return -1; - } + + g_message("trying to get context - 4: %p\n", + gdk_gl_config_new_by_mode( + GDK_GL_MODE_RGB | + GDK_GL_MODE_DEPTH | + GDK_GL_MODE_DOUBLE)); + + g_message("trying to get context - 5: %p\n", + gdk_gl_config_new_by_mode( + GDK_GL_MODE_RGB | + GDK_GL_MODE_DEPTH | + GDK_GL_MODE_DOUBLE | + GDK_GL_MODE_ALPHA)); + + g_message("trying to get context - 6: %p\n", + gdk_gl_config_new_by_mode( + GDK_GL_MODE_RGBA | + GDK_GL_MODE_DEPTH | + GDK_GL_MODE_DOUBLE | + GDK_GL_MODE_ALPHA)); /* Use external handler for link buttons */ gtk_link_button_set_uri_hook(xdg_open, NULL, NULL);