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.

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