martini.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:6k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Mark J. Kilgard, 1997.  */
  2. /* This program is freely distributable without licensing fees  and is
  3.    provided without guarantee or warrantee expressed or  implied. This
  4.    program is -not- in the public domain. */
  5. /* compile: cc -o martini martini.c trackball.c -lgle -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <math.h>       /* for cos(), sin(), and sqrt() */
  10. #include <GL/glut.h>
  11. #include <GL/tube.h>
  12. #include "trackball.h"
  13. int spinning = 0, moving = 0;
  14. int beginx, beginy;
  15. int W = 300, H = 300;
  16. float curquat[4];
  17. float lastquat[4];
  18. int newModel = 1;
  19. /* *INDENT-OFF* */
  20. GLfloat lightZeroPosition[] = {10.0, 4.0, 10.0, 1.0};
  21. GLfloat lightZeroColor[] = {0.8, 1.0, 0.8, 1.0}; /* green-tinted */
  22. GLfloat lightOnePosition[] = {-1.0, -2.0, 1.0, 0.0};
  23. GLfloat lightOneColor[] = {0.6, 0.3, 0.2, 1.0}; /* red-tinted */
  24. /* *INDENT-ON* */
  25. void
  26. recalcModelView(void)
  27. {
  28.   GLfloat m[4][4];
  29.   glPopMatrix();
  30.   glPushMatrix();
  31.   build_rotmatrix(m, curquat);
  32.   glMultMatrixf(&m[0][0]);
  33.   newModel = 0;
  34. }
  35. /* the arrays in which we will store out polyline */
  36. #define NPTS 25
  37. double points[NPTS][3];
  38. double radii[NPTS];
  39. int idx = 0;
  40. #define REV(r, y) { 
  41.   points[idx][0] = 0.0; 
  42.   points[idx][1] = y - 3.0; 
  43.   points[idx][2] = 0.0; 
  44.   radii[idx] = r; 
  45.   idx ++; 
  46. }
  47. void 
  48. InitStuff(void)
  49. {
  50.   /* Initialize the join style here, no capping. */
  51.   gleSetJoinStyle(TUBE_NORM_EDGE | TUBE_JN_ANGLE);
  52.   gleSetNumSlices(30);
  53.   REV(0.0, 5.0);
  54.   REV(0.0, 4.0);
  55.   REV(2.5, 6.1);
  56.   REV(2.75, 6.0);
  57.   REV(2.75, 5.75);
  58.   REV(0.25, 3.75);
  59.   REV(0.25, 2.66);
  60.   REV(0.4, 2.5);
  61.   REV(0.3, 2.2);
  62.   REV(0.4, 1.9);
  63.   REV(0.25, 1.7);
  64.   REV(0.25, 0.6);
  65.   REV(0.25, 0.101);
  66.   REV(2.0, 0.1);
  67.   REV(2.0, 0.0);
  68.   REV(0.0, 0.05);
  69.   REV(0.0, -1.0);
  70.   /* Capture rendering of martini glass in a display list. */
  71.   glNewList(1, GL_COMPILE);
  72.   glFrontFace(GL_CW);
  73.   glePolyCone(4, points, NULL, radii);
  74.   glFrontFace(GL_CCW);
  75.   glePolyCone(15, &points[1], NULL, &radii[1]);
  76.   glFrontFace(GL_CW);
  77.   glePolyCone(4, &points[13], NULL, &radii[13]);
  78.   glEndList();
  79. }
  80. void
  81. redraw(void)
  82. {
  83.   if (newModel)
  84.     recalcModelView();
  85.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  86.   /* Draw the martini glass. */
  87.   glCallList(1);
  88.   glutSwapBuffers();
  89. }
  90. void
  91. myReshape(int w, int h)
  92. {
  93.   glViewport(0, 0, w, h);
  94.   W = w;
  95.   H = h;
  96. }
  97. void
  98. mouse(int button, int state, int x, int y)
  99. {
  100.   if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  101.     spinning = 0;
  102.     glutIdleFunc(NULL);
  103.     moving = 1;
  104.     beginx = x;
  105.     beginy = y;
  106.   }
  107.   if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
  108.     moving = 0;
  109.   }
  110. }
  111. void
  112. animate(void)
  113. {
  114.   add_quats(lastquat, curquat, curquat);
  115.   newModel = 1;
  116.   glutPostRedisplay();
  117. }
  118. void
  119. motion(int x, int y)
  120. {
  121.   if (moving) {
  122.     trackball(lastquat,
  123.       (2.0 * beginx - W) / W,
  124.       (H - 2.0 * beginy) / H,
  125.       (2.0 * x - W) / W,
  126.       (H - 2.0 * y) / H
  127.       );
  128.     beginx = x;
  129.     beginy = y;
  130.     spinning = 1;
  131.     glutIdleFunc(animate);
  132.   }
  133. }
  134. GLboolean lightZeroSwitch = GL_TRUE, lightOneSwitch = GL_TRUE;
  135. void
  136. controlLights(int value)
  137. {
  138.   switch (value) {
  139.   case 1:
  140.     lightZeroSwitch = !lightZeroSwitch;
  141.     if (lightZeroSwitch) {
  142.       glEnable(GL_LIGHT0);
  143.     } else {
  144.       glDisable(GL_LIGHT0);
  145.     }
  146.     break;
  147.   case 2:
  148.     lightOneSwitch = !lightOneSwitch;
  149.     if (lightOneSwitch) {
  150.       glEnable(GL_LIGHT1);
  151.     } else {
  152.       glDisable(GL_LIGHT1);
  153.     }
  154.     break;
  155. #ifdef GL_MULTISAMPLE_SGIS
  156.   case 3:
  157.     if (glIsEnabled(GL_MULTISAMPLE_SGIS)) {
  158.       glDisable(GL_MULTISAMPLE_SGIS);
  159.     } else {
  160.       glEnable(GL_MULTISAMPLE_SGIS);
  161.     }
  162.     break;
  163. #endif
  164.   case 4:
  165.     glutFullScreen();
  166.     break;
  167.   case 5:
  168.     exit(0);
  169.     break;
  170.   }
  171.   glutPostRedisplay();
  172. }
  173. void
  174. vis(int visible)
  175. {
  176.   if (visible == GLUT_VISIBLE) {
  177.     if (spinning)
  178.       glutIdleFunc(animate);
  179.   } else {
  180.     if (spinning)
  181.       glutIdleFunc(NULL);
  182.   }
  183. }
  184. int
  185. main(int argc, char **argv)
  186. {
  187.   glutInit(&argc, argv);
  188.   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
  189.   trackball(curquat, 0.0, 0.0, 0.0, 0.0);
  190.   glutCreateWindow("martini");
  191.   glutDisplayFunc(redraw);
  192.   glutReshapeFunc(myReshape);
  193.   glutVisibilityFunc(vis);
  194.   glutMouseFunc(mouse);
  195.   glutMotionFunc(motion);
  196.   glutCreateMenu(controlLights);
  197.   glutAddMenuEntry("Toggle right light", 1);
  198.   glutAddMenuEntry("Toggle left light", 2);
  199.   if (glutGet(GLUT_WINDOW_NUM_SAMPLES) > 0) {
  200.     glutAddMenuEntry("Toggle multisampling", 3);
  201.     glutSetWindowTitle("martini (multisample capable)");
  202.   }
  203.   glutAddMenuEntry("Full screen", 4);
  204.   glutAddMenuEntry("Quit", 5);
  205.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  206.   glEnable(GL_CULL_FACE);
  207.   glEnable(GL_DEPTH_TEST);
  208.   glEnable(GL_LIGHTING);
  209.   glMatrixMode(GL_PROJECTION);
  210.   gluPerspective( /* field of view in degree */ 40.0,
  211.   /* aspect ratio */ 1.0,
  212.     /* Z near */ 1.0, /* Z far */ 40.0);
  213.   glMatrixMode(GL_MODELVIEW);
  214.   gluLookAt(0.0, 0.0, 15.0,  /* eye is at (0,0,15) */
  215.     0.0, 0.0, 0.0,      /* center is at (0,0,0) */
  216.     0.0, 1.0, 0.);      /* up is in positive Y direction */
  217.   glPushMatrix();       /* dummy push so we can pop on model recalc */
  218.   glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
  219.   glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition);
  220.   glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
  221.   glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
  222.   glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
  223.   glLightfv(GL_LIGHT1, GL_POSITION, lightOnePosition);
  224.   glLightfv(GL_LIGHT1, GL_DIFFUSE, lightOneColor);
  225.   glEnable(GL_LIGHT0);
  226.   glEnable(GL_LIGHT1);
  227.   InitStuff();
  228.   glutMainLoop();
  229.   return 0;             /* ANSI C requires main to return int. */
  230. }