⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gears.c

📁 some animation source files ..
💻 C
字号:
/* * 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 <stdlib.h>#include <string.h>#include <math.h>#include <gtk/gtk.h>#include <gdk/gdkkeysyms.h>#include <gtk/gtkgl.h>#ifdef G_OS_WIN32#define WIN32_LEAN_AND_MEAN 1#include <windows.h>#endif#include <GL/gl.h>#include <GL/glu.h>/* * 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 voidgear(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 gbooleandraw (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 gbooleanreshape (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 voidinit(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 gbooleanidle (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 voididle_add (GtkWidget *widget){  if (idle_id == 0)    {      idle_id = gtk_idle_add_priority (GDK_PRIORITY_REDRAW,				       (GtkFunction) idle,				       widget);    }}static voididle_remove (GtkWidget *widget){  if (idle_id != 0)    {      gtk_idle_remove (idle_id);      idle_id = 0;    }}static gbooleanmap (GtkWidget   *widget,     GdkEventAny *event,     gpointer     data){  idle_add (widget);  return TRUE;}static gbooleanunmap (GtkWidget   *widget,       GdkEventAny *event,       gpointer     data){  idle_remove (widget);  return TRUE;}static gbooleanvisible (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 gbooleankey (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;}intmain (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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -