Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

gears.c 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /* $Id: gears.c,v 1.6 2000/04/06 02:22:59 brianp Exp $ */
  2. /*
  3. * 3-D gear wheels. This program is in the public domain.
  4. *
  5. * Command line options:
  6. * -info print GL implementation information
  7. * -exit automatically exit after 30 seconds
  8. *
  9. *
  10. * Brian Paul
  11. */
  12. /* Conversion to GLUT by Mark J. Kilgard */
  13. #include <math.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <GL/glut.h>
  18. #ifndef M_PI
  19. #define M_PI 3.14159265
  20. #endif
  21. static GLint T0 = 0;
  22. static GLint Frames = 0;
  23. static GLint autoexit = 0;
  24. /**
  25. Draw a gear wheel. You'll probably want to call this function when
  26. building a display list since we do a lot of trig here.
  27. Input: inner_radius - radius of hole at center
  28. outer_radius - radius at center of teeth
  29. width - width of gear
  30. teeth - number of teeth
  31. tooth_depth - depth of tooth
  32. **/
  33. static void
  34. gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
  35. GLint teeth, GLfloat tooth_depth)
  36. {
  37. GLint i;
  38. GLfloat r0, r1, r2;
  39. GLfloat angle, da;
  40. GLfloat u, v, len;
  41. r0 = inner_radius;
  42. r1 = outer_radius - tooth_depth / 2.0;
  43. r2 = outer_radius + tooth_depth / 2.0;
  44. da = 2.0 * M_PI / teeth / 4.0;
  45. glShadeModel(GL_FLAT);
  46. glNormal3f(0.0, 0.0, 1.0);
  47. /* draw front face */
  48. glBegin(GL_QUAD_STRIP);
  49. for (i = 0; i <= teeth; i++) {
  50. angle = i * 2.0 * M_PI / teeth;
  51. glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  52. glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  53. if (i < teeth) {
  54. glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  55. glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  56. }
  57. }
  58. glEnd();
  59. /* draw front sides of teeth */
  60. glBegin(GL_QUADS);
  61. da = 2.0 * M_PI / teeth / 4.0;
  62. for (i = 0; i < teeth; i++) {
  63. angle = i * 2.0 * M_PI / teeth;
  64. glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  65. glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  66. glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
  67. glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  68. }
  69. glEnd();
  70. glNormal3f(0.0, 0.0, -1.0);
  71. /* draw back face */
  72. glBegin(GL_QUAD_STRIP);
  73. for (i = 0; i <= teeth; i++) {
  74. angle = i * 2.0 * M_PI / teeth;
  75. glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  76. glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  77. if (i < teeth) {
  78. glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  79. glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  80. }
  81. }
  82. glEnd();
  83. /* draw back sides of teeth */
  84. glBegin(GL_QUADS);
  85. da = 2.0 * M_PI / teeth / 4.0;
  86. for (i = 0; i < teeth; i++) {
  87. angle = i * 2.0 * M_PI / teeth;
  88. glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  89. glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
  90. glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  91. glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  92. }
  93. glEnd();
  94. /* draw outward faces of teeth */
  95. glBegin(GL_QUAD_STRIP);
  96. for (i = 0; i < teeth; i++) {
  97. angle = i * 2.0 * M_PI / teeth;
  98. glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  99. glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  100. u = r2 * cos(angle + da) - r1 * cos(angle);
  101. v = r2 * sin(angle + da) - r1 * sin(angle);
  102. len = sqrt(u * u + v * v);
  103. u /= len;
  104. v /= len;
  105. glNormal3f(v, -u, 0.0);
  106. glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  107. glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  108. glNormal3f(cos(angle), sin(angle), 0.0);
  109. glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
  110. glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
  111. u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
  112. v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
  113. glNormal3f(v, -u, 0.0);
  114. glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  115. glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  116. glNormal3f(cos(angle), sin(angle), 0.0);
  117. }
  118. glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
  119. glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
  120. glEnd();
  121. glShadeModel(GL_SMOOTH);
  122. /* draw inside radius cylinder */
  123. glBegin(GL_QUAD_STRIP);
  124. for (i = 0; i <= teeth; i++) {
  125. angle = i * 2.0 * M_PI / teeth;
  126. glNormal3f(-cos(angle), -sin(angle), 0.0);
  127. glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  128. glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  129. }
  130. glEnd();
  131. }
  132. static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
  133. static GLint gear1, gear2, gear3;
  134. static GLfloat angle = 0.0;
  135. static void
  136. draw(void)
  137. {
  138. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  139. glPushMatrix();
  140. glRotatef(view_rotx, 1.0, 0.0, 0.0);
  141. glRotatef(view_roty, 0.0, 1.0, 0.0);
  142. glRotatef(view_rotz, 0.0, 0.0, 1.0);
  143. glPushMatrix();
  144. glTranslatef(-3.0, -2.0, 0.0);
  145. glRotatef(angle, 0.0, 0.0, 1.0);
  146. glCallList(gear1);
  147. glPopMatrix();
  148. glPushMatrix();
  149. glTranslatef(3.1, -2.0, 0.0);
  150. glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
  151. glCallList(gear2);
  152. glPopMatrix();
  153. glPushMatrix();
  154. glTranslatef(-3.1, 4.2, 0.0);
  155. glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
  156. glCallList(gear3);
  157. glPopMatrix();
  158. glPopMatrix();
  159. glutSwapBuffers();
  160. Frames++;
  161. {
  162. GLint t = glutGet(GLUT_ELAPSED_TIME);
  163. if (t - T0 >= 5000) {
  164. GLfloat seconds = (t - T0) / 1000.0;
  165. GLfloat fps = Frames / seconds;
  166. printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps);
  167. T0 = t;
  168. Frames = 0;
  169. if ((t >= 999.0 * autoexit) && (autoexit))
  170. exit(0);
  171. }
  172. }
  173. }
  174. static void
  175. idle(void)
  176. {
  177. angle += 2.0;
  178. glutPostRedisplay();
  179. }
  180. /* change view angle, exit upon ESC */
  181. /* ARGSUSED1 */
  182. static void
  183. key(unsigned char k, int x, int y)
  184. {
  185. switch (k) {
  186. case 'z':
  187. view_rotz += 5.0;
  188. break;
  189. case 'Z':
  190. view_rotz -= 5.0;
  191. break;
  192. case 27: /* Escape */
  193. exit(0);
  194. break;
  195. default:
  196. return;
  197. }
  198. glutPostRedisplay();
  199. }
  200. /* change view angle */
  201. /* ARGSUSED1 */
  202. static void
  203. special(int k, int x, int y)
  204. {
  205. switch (k) {
  206. case GLUT_KEY_UP:
  207. view_rotx += 5.0;
  208. break;
  209. case GLUT_KEY_DOWN:
  210. view_rotx -= 5.0;
  211. break;
  212. case GLUT_KEY_LEFT:
  213. view_roty += 5.0;
  214. break;
  215. case GLUT_KEY_RIGHT:
  216. view_roty -= 5.0;
  217. break;
  218. default:
  219. return;
  220. }
  221. glutPostRedisplay();
  222. }
  223. /* new window size or exposure */
  224. static void
  225. reshape(int width, int height)
  226. {
  227. GLfloat h = (GLfloat) height / (GLfloat) width;
  228. glViewport(0, 0, (GLint) width, (GLint) height);
  229. glMatrixMode(GL_PROJECTION);
  230. glLoadIdentity();
  231. glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
  232. glMatrixMode(GL_MODELVIEW);
  233. glLoadIdentity();
  234. glTranslatef(0.0, 0.0, -40.0);
  235. }
  236. static void
  237. init(int argc, char *argv[])
  238. {
  239. static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0};
  240. static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0};
  241. static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0};
  242. static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
  243. GLint i;
  244. glLightfv(GL_LIGHT0, GL_POSITION, pos);
  245. glEnable(GL_CULL_FACE);
  246. glEnable(GL_LIGHTING);
  247. glEnable(GL_LIGHT0);
  248. glEnable(GL_DEPTH_TEST);
  249. /* make the gears */
  250. gear1 = glGenLists(1);
  251. glNewList(gear1, GL_COMPILE);
  252. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
  253. gear(1.0, 4.0, 1.0, 20, 0.7);
  254. glEndList();
  255. gear2 = glGenLists(1);
  256. glNewList(gear2, GL_COMPILE);
  257. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
  258. gear(0.5, 2.0, 2.0, 10, 0.7);
  259. glEndList();
  260. gear3 = glGenLists(1);
  261. glNewList(gear3, GL_COMPILE);
  262. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
  263. gear(1.3, 2.0, 0.5, 10, 0.7);
  264. glEndList();
  265. glEnable(GL_NORMALIZE);
  266. for ( i=1; i<argc; i++ ) {
  267. if (strcmp(argv[i], "-info")==0) {
  268. printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
  269. printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
  270. printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
  271. printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
  272. }
  273. else if ( strcmp(argv[i], "-exit")==0) {
  274. autoexit = 30;
  275. printf("Auto Exit after %i seconds.\n", autoexit );
  276. }
  277. }
  278. }
  279. static void
  280. visible(int vis)
  281. {
  282. if (vis == GLUT_VISIBLE)
  283. glutIdleFunc(idle);
  284. else
  285. glutIdleFunc(NULL);
  286. }
  287. int main(int argc, char *argv[])
  288. {
  289. glutInit(&argc, argv);
  290. glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  291. glutInitWindowPosition(0, 0);
  292. glutInitWindowSize(300, 300);
  293. glutCreateWindow("Gears");
  294. init(argc, argv);
  295. glutDisplayFunc(draw);
  296. glutReshapeFunc(reshape);
  297. glutKeyboardFunc(key);
  298. glutSpecialFunc(special);
  299. glutVisibilityFunc(visible);
  300. glutMainLoop();
  301. return 0; /* ANSI C requires main to return int. */
  302. }