test-shapes-gles1.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*! \file shapes.c
  2. \ingroup demos
  3. This program is a test harness for the various shapes
  4. in OpenGLUT. It may also be useful to see which
  5. parameters control what behavior in the OpenGLUT
  6. objects.
  7. Spinning wireframe and solid-shaded shapes are
  8. displayed. Some parameters can be adjusted.
  9. Keys:
  10. - <tt>Esc &nbsp;</tt> Quit
  11. - <tt>q Q &nbsp;</tt> Quit
  12. - <tt>i I &nbsp;</tt> Show info
  13. - <tt>p P &nbsp;</tt> Toggle perspective or orthographic projection
  14. - <tt>= + &nbsp;</tt> Increase \a slices
  15. - <tt>- _ &nbsp;</tt> Decreate \a slices
  16. - <tt>, < &nbsp;</tt> Decreate \a stacks
  17. - <tt>. > &nbsp;</tt> Increase \a stacks
  18. - <tt>9 ( &nbsp;</tt> Decreate \a depth (Sierpinski Sponge)
  19. - <tt>0 ) &nbsp;</tt> Increase \a depth (Sierpinski Sponge)
  20. - <tt>up&nbsp; &nbsp;</tt> Increase "outer radius"
  21. - <tt>down&nbsp;</tt> Decrease "outer radius"
  22. - <tt>left&nbsp;</tt> Decrease "inner radius"
  23. - <tt>right</tt> Increase "inner radius"
  24. - <tt>PgUp&nbsp;</tt> Next shape-drawing function
  25. - <tt>PgDn&nbsp;</tt> Prev shape-drawing function
  26. \author Written by Nigel Stewart November 2003
  27. \author Portions Copyright (C) 2004, the OpenGLUT project contributors. <br>
  28. OpenGLUT branched from freeglut in February, 2004.
  29. \image html openglut_shapes.png OpenGLUT Geometric Shapes Demonstration
  30. \include demos/shapes/shapes.c
  31. */
  32. #include <GL/freeglut.h>
  33. #include <GL/freeglut_ext.h>
  34. #include <stdarg.h>
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #ifdef _MSC_VER
  38. /* DUMP MEMORY LEAKS */
  39. #include <crtdbg.h>
  40. #endif
  41. /*
  42. * This macro is only intended to be used on arrays, of course.
  43. */
  44. #define NUMBEROF(x) ((sizeof(x))/(sizeof(x[0])))
  45. #define glRotated glRotatef
  46. #define glTranslated glTranslatef
  47. /*
  48. * These global variables control which object is drawn,
  49. * and how it is drawn. No object uses all of these
  50. * variables.
  51. */
  52. static int function_index;
  53. static int slices = 16;
  54. static int stacks = 16;
  55. static double irad = .25;
  56. static double orad = 1.0; /* doubles as size for objects other than Torus */
  57. static int depth = 4;
  58. static double offset[ 3 ] = { 0, 0, 0 };
  59. static GLboolean show_info = GL_TRUE;
  60. static float ar;
  61. static GLboolean persProject = GL_TRUE;
  62. static GLboolean animateXRot = GL_FALSE;
  63. /*
  64. * These one-liners draw particular objects, fetching appropriate
  65. * information from the above globals. They are just thin wrappers
  66. * for the FreeGLUT objects.
  67. */
  68. static void drawSolidTetrahedron(void) { glutSolidTetrahedron (); }
  69. static void drawWireTetrahedron(void) { glutWireTetrahedron (); }
  70. static void drawSolidCube(void) { glutSolidCube(orad); } /* orad doubles as size input */
  71. static void drawWireCube(void) { glutWireCube(orad); } /* orad doubles as size input */
  72. static void drawSolidOctahedron(void) { glutSolidOctahedron (); }
  73. static void drawWireOctahedron(void) { glutWireOctahedron (); }
  74. static void drawSolidDodecahedron(void) { glutSolidDodecahedron (); }
  75. static void drawWireDodecahedron(void) { glutWireDodecahedron (); }
  76. static void drawSolidRhombicDodecahedron(void) { glutSolidRhombicDodecahedron (); }
  77. static void drawWireRhombicDodecahedron(void) { glutWireRhombicDodecahedron (); }
  78. static void drawSolidIcosahedron(void) { glutSolidIcosahedron (); }
  79. static void drawWireIcosahedron(void) { glutWireIcosahedron (); }
  80. static void drawSolidSierpinskiSponge(void) { glutSolidSierpinskiSponge (depth, offset, orad);} /* orad doubles as size input */
  81. static void drawWireSierpinskiSponge(void) { glutWireSierpinskiSponge (depth, offset, orad); } /* orad doubles as size input */
  82. static void drawSolidTorus(void) { glutSolidTorus(irad,orad,slices,stacks); }
  83. static void drawWireTorus(void) { glutWireTorus (irad,orad,slices,stacks); }
  84. static void drawSolidSphere(void) { glutSolidSphere(orad,slices,stacks); } /* orad doubles as size input */
  85. static void drawWireSphere(void) { glutWireSphere(orad,slices,stacks); } /* orad doubles as size input */
  86. static void drawSolidCone(void) { glutSolidCone(orad,orad,slices,stacks); } /* orad doubles as size input */
  87. static void drawWireCone(void) { glutWireCone(orad,orad,slices,stacks); } /* orad doubles as size input */
  88. static void drawSolidCylinder(void) { glutSolidCylinder(orad,orad,slices,stacks); } /* orad doubles as size input */
  89. static void drawWireCylinder(void) { glutWireCylinder(orad,orad,slices,stacks); } /* orad doubles as size input */
  90. static void drawSolidTeapot(void)
  91. { glFrontFace(GL_CW); glutSolidTeapot(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
  92. static void drawWireTeapot(void)
  93. { glFrontFace(GL_CW); glutWireTeapot(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
  94. /*
  95. * This structure defines an entry in our function-table.
  96. */
  97. typedef struct
  98. {
  99. const char * const name;
  100. void (*solid) (void);
  101. void (*wire) (void);
  102. } entry;
  103. #define ENTRY(e) {#e, drawSolid##e, drawWire##e}
  104. static const entry table [] =
  105. {
  106. ENTRY (Tetrahedron),
  107. ENTRY (Cube),
  108. ENTRY (Octahedron),
  109. ENTRY (Dodecahedron),
  110. ENTRY (RhombicDodecahedron),
  111. ENTRY (Icosahedron),
  112. ENTRY (SierpinskiSponge),
  113. ENTRY (Teapot),
  114. ENTRY (Torus),
  115. ENTRY (Sphere),
  116. ENTRY (Cone),
  117. ENTRY (Cylinder),
  118. /* ENTRY (Cuboctahedron) */
  119. };
  120. #undef ENTRY
  121. /*!
  122. Does printf()-like work using freeglut
  123. glutBitmapString(). Uses a fixed font. Prints
  124. at the indicated row/column position.
  125. Limitation: Cannot address pixels.
  126. Limitation: Renders in screen coords, not model coords.
  127. */
  128. static void shapesPrintf (int row, int col, const char *fmt, ...)
  129. {
  130. }
  131. /* GLUT callback Handlers */
  132. static void
  133. resize(int width, int height)
  134. {
  135. ar = (float) width / (float) height;
  136. glViewport(0, 0, width, height);
  137. }
  138. static void display(void)
  139. {
  140. const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
  141. const double a = t*90.0;
  142. const double b = (animateXRot?t:1)*60.0;
  143. glMatrixMode(GL_PROJECTION);
  144. glLoadIdentity();
  145. glFrustumf(-ar, ar, -1.0, 1.0, 2.0, 100.0);
  146. glMatrixMode(GL_MODELVIEW);
  147. glLoadIdentity();
  148. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  149. glEnable(GL_LIGHTING);
  150. glColor4f(1,0,0,1);
  151. glPushMatrix();
  152. glTranslated(0,1.2,-6);
  153. glRotated(b,1,0,0);
  154. glRotated(a,0,0,1);
  155. table [function_index].solid ();
  156. glPopMatrix();
  157. glPushMatrix();
  158. glTranslated(0,-1.2,-6);
  159. glRotated(b,1,0,0);
  160. glRotated(a,0,0,1);
  161. table [function_index].wire ();
  162. glPopMatrix();
  163. glDisable(GL_LIGHTING);
  164. glColor4f(0.1,0.1,0.4,1.0);
  165. glutSwapBuffers();
  166. }
  167. static void
  168. key(unsigned char key, int x, int y)
  169. {
  170. switch (key)
  171. {
  172. case 27 :
  173. case 'Q':
  174. case 'q': glutLeaveMainLoop () ; break;
  175. case 'I':
  176. case 'i': show_info = ( show_info == GL_TRUE ) ? GL_FALSE : GL_TRUE; break;
  177. case '=':
  178. case '+': slices++; printf("%d,%d\n", slices, stacks); break;
  179. case '-':
  180. case '_': if( slices > -1 ) slices--; break;
  181. case ',':
  182. case '<': if( stacks > -1 ) stacks--; break;
  183. case '.':
  184. case '>': stacks++; break;
  185. case '9':
  186. case '(': if( depth > -1 ) depth--; break;
  187. case '0':
  188. case ')': ++depth; break;
  189. case 'P':
  190. case 'p': persProject=!persProject; break;
  191. case 'R':
  192. case 'r': animateXRot=!animateXRot; break;
  193. default:
  194. break;
  195. }
  196. glutPostRedisplay();
  197. }
  198. static void special (int key, int x, int y)
  199. {
  200. switch (key)
  201. {
  202. case GLUT_KEY_PAGE_UP: ++function_index; break;
  203. case GLUT_KEY_PAGE_DOWN: --function_index; break;
  204. case GLUT_KEY_UP: orad *= 2; break;
  205. case GLUT_KEY_DOWN: orad /= 2; break;
  206. case GLUT_KEY_RIGHT: irad *= 2; break;
  207. case GLUT_KEY_LEFT: irad /= 2; break;
  208. default:
  209. break;
  210. }
  211. if (0 > function_index)
  212. function_index = NUMBEROF (table) - 1;
  213. if (NUMBEROF (table) <= ( unsigned )function_index)
  214. function_index = 0;
  215. }
  216. static void
  217. idle(void)
  218. {
  219. glutPostRedisplay();
  220. }
  221. static void
  222. onMouseClick(int button, int state, int x, int y) {
  223. if (state == GLUT_DOWN)
  224. special(GLUT_KEY_PAGE_UP, 0, 0);
  225. }
  226. const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
  227. const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  228. const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  229. const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
  230. const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
  231. const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
  232. const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  233. const GLfloat high_shininess[] = { 100.0f };
  234. /* Program entry point */
  235. void init_context() {
  236. printf("init_context\n"); fflush(stdout);
  237. glClearColor(1,1,1,1);
  238. glEnable(GL_CULL_FACE);
  239. glCullFace(GL_BACK);
  240. glEnable(GL_DEPTH_TEST);
  241. glDepthFunc(GL_LESS);
  242. glEnable(GL_LIGHT0);
  243. glEnable(GL_NORMALIZE);
  244. glEnable(GL_COLOR_MATERIAL);
  245. glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
  246. glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
  247. glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
  248. glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  249. glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
  250. glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
  251. glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
  252. glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
  253. }
  254. int
  255. main(int argc, char *argv[])
  256. {
  257. glutInitWindowSize(640,480);
  258. glutInitWindowPosition(40,40);
  259. glutInit(&argc, argv);
  260. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
  261. glutCreateWindow("FreeGLUT Shapes");
  262. glutReshapeFunc(resize);
  263. glutDisplayFunc(display);
  264. glutKeyboardFunc(key);
  265. glutSpecialFunc(special);
  266. glutIdleFunc(idle);
  267. glutMouseFunc(onMouseClick);
  268. glutInitContextFunc(init_context);
  269. glutSetOption ( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION ) ;
  270. glutMainLoop();
  271. #ifdef _MSC_VER
  272. /* DUMP MEMORY LEAK INFORMATION */
  273. _CrtDumpMemoryLeaks () ;
  274. #endif
  275. return EXIT_SUCCESS;
  276. }