Clone of mesa.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

singlebuffer.c 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * Demo of (nearly) flicker-free drawing with a single color buffer.
  3. *
  4. * Basically, draw the scene into the Z buffer first, then draw the
  5. * scene into the color buffer. Finally, "clear" the background by
  6. * setting the fragments we didn't hit earlier.
  7. *
  8. * This won't work if you need blending. The technique works best
  9. * when the scene is relatively simple and can be rendered quickly
  10. * (i.e. with hardware), and when the objects don't move too much from
  11. * one frame to the next.
  12. *
  13. * Brian Paul
  14. * 25 August 2005
  15. *
  16. * See Mesa license for terms.
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <GL/glut.h>
  21. #define FLICKER 0
  22. #define NO_FLICKER 1
  23. static GLint Mode = NO_FLICKER;
  24. static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
  25. static GLboolean Anim = GL_TRUE;
  26. static GLfloat ClearColor[4] = {0.2, 0.2, 0.9, 0.0};
  27. static GLfloat NearClip = 5.0, FarClip = 25.0, ViewDist = 7.0;
  28. static double PrevTime = -1;
  29. struct box {
  30. float tx, ty, tz;
  31. float rx, ry, rz, ra;
  32. float sx, sy, sz;
  33. float color[4];
  34. };
  35. #define NUM_BOXES 25
  36. struct box Boxes[NUM_BOXES];
  37. /* Return random float in [0,1] */
  38. static float
  39. Random(void)
  40. {
  41. int i = rand();
  42. return (float) (i % 1000) / 1000.0;
  43. }
  44. static void
  45. MakeBoxes(void)
  46. {
  47. int i;
  48. for (i = 0; i < NUM_BOXES; i++) {
  49. Boxes[i].tx = -1.0 + 2.0 * Random();
  50. Boxes[i].ty = -1.0 + 2.0 * Random();
  51. Boxes[i].tz = -1.0 + 2.0 * Random();
  52. Boxes[i].sx = 0.1 + Random() * 0.4;
  53. Boxes[i].sy = 0.1 + Random() * 0.4;
  54. Boxes[i].sz = 0.1 + Random() * 0.4;
  55. Boxes[i].rx = Random();
  56. Boxes[i].ry = Random();
  57. Boxes[i].rz = Random();
  58. Boxes[i].ra = Random() * 360.0;
  59. Boxes[i].color[0] = Random();
  60. Boxes[i].color[1] = Random();
  61. Boxes[i].color[2] = Random();
  62. Boxes[i].color[3] = 1.0;
  63. }
  64. }
  65. static void
  66. DrawBoxes(void)
  67. {
  68. int i;
  69. for (i = 0; i < NUM_BOXES; i++) {
  70. glPushMatrix();
  71. glTranslatef(Boxes[i].tx, Boxes[i].ty, Boxes[i].tz);
  72. glRotatef(Boxes[i].ra, Boxes[i].rx, Boxes[i].ry, Boxes[i].rz);
  73. glScalef(Boxes[i].sx, Boxes[i].sy, Boxes[i].sz);
  74. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, Boxes[i].color);
  75. glutSolidCube(1.0);
  76. glPopMatrix();
  77. }
  78. }
  79. static void
  80. Idle(void)
  81. {
  82. double dt, t = glutGet(GLUT_ELAPSED_TIME) * 0.001;
  83. if (PrevTime < 0.0)
  84. PrevTime = t;
  85. dt = t - PrevTime;
  86. PrevTime = t;
  87. Xrot += 16.0 * dt;
  88. Yrot += 12.0 * dt;
  89. Zrot += 8.0 * dt;
  90. glutPostRedisplay();
  91. }
  92. static void
  93. Draw(void)
  94. {
  95. if (Mode == FLICKER) {
  96. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  97. }
  98. else {
  99. /* don't clear color buffer */
  100. glClear(GL_DEPTH_BUFFER_BIT);
  101. /* update Z buffer only */
  102. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  103. }
  104. glPushMatrix();
  105. glRotatef(Xrot, 1, 0, 0);
  106. glRotatef(Yrot, 0, 1, 0);
  107. glRotatef(Zrot, 0, 0, 1);
  108. DrawBoxes();
  109. if (Mode == NO_FLICKER) {
  110. /* update color buffer now */
  111. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  112. glDepthFunc(GL_EQUAL);
  113. DrawBoxes();
  114. glDepthFunc(GL_LESS);
  115. }
  116. glPopMatrix();
  117. if (Mode == NO_FLICKER) {
  118. /* "clear" the untouched pixels now.
  119. * Note: if you comment-out this code you'll see something interesting.
  120. */
  121. GLfloat x = FarClip / NearClip;
  122. GLfloat z = -(FarClip - ViewDist - 1.0);
  123. glDisable(GL_LIGHTING);
  124. glColor4fv(ClearColor);
  125. glBegin(GL_POLYGON);
  126. glVertex3f(-x, -x, z);
  127. glVertex3f( x, -x, z);
  128. glVertex3f( x, x, z);
  129. glVertex3f(-x, x, z);
  130. glEnd();
  131. glEnable(GL_LIGHTING);
  132. }
  133. /* This is where you'd normally do SwapBuffers */
  134. glFinish();
  135. }
  136. static void
  137. Reshape(int width, int height)
  138. {
  139. glViewport(0, 0, width, height);
  140. glMatrixMode(GL_PROJECTION);
  141. glLoadIdentity();
  142. glFrustum(-1.0, 1.0, -1.0, 1.0, NearClip, FarClip);
  143. glMatrixMode(GL_MODELVIEW);
  144. glLoadIdentity();
  145. glTranslatef(0.0, 0.0, -ViewDist);
  146. }
  147. static void
  148. Key(unsigned char key, int x, int y)
  149. {
  150. (void) x;
  151. (void) y;
  152. switch (key) {
  153. case 'a':
  154. Anim = !Anim;
  155. if (Anim)
  156. glutIdleFunc(Idle);
  157. else
  158. glutIdleFunc(NULL);
  159. PrevTime = -1;
  160. break;
  161. case 'm':
  162. Mode = !Mode;
  163. break;
  164. case 'b':
  165. MakeBoxes();
  166. break;
  167. case 27:
  168. exit(0);
  169. break;
  170. }
  171. glutPostRedisplay();
  172. }
  173. static void
  174. SpecialKey(int key, int x, int y)
  175. {
  176. const GLfloat step = 3.0;
  177. (void) x;
  178. (void) y;
  179. switch (key) {
  180. case GLUT_KEY_UP:
  181. Xrot -= step;
  182. break;
  183. case GLUT_KEY_DOWN:
  184. Xrot += step;
  185. break;
  186. case GLUT_KEY_LEFT:
  187. Yrot -= step;
  188. break;
  189. case GLUT_KEY_RIGHT:
  190. Yrot += step;
  191. break;
  192. }
  193. glutPostRedisplay();
  194. }
  195. static void
  196. Init(void)
  197. {
  198. glClearColor(ClearColor[0], ClearColor[1], ClearColor[2], ClearColor[3]);
  199. glEnable(GL_DEPTH_TEST);
  200. glEnable(GL_LIGHTING);
  201. glEnable(GL_LIGHT0);
  202. glEnable(GL_CULL_FACE);
  203. glEnable(GL_NORMALIZE);
  204. MakeBoxes();
  205. }
  206. static void
  207. Usage(void)
  208. {
  209. printf("Keys:\n");
  210. printf(" m - toggle drawing mode (flicker vs. no flicker)\n");
  211. printf(" a - toggle animation\n");
  212. printf(" b - generate new boxes\n");
  213. printf(" ARROWS - rotate scene\n");
  214. printf(" ESC - exit\n");
  215. }
  216. int
  217. main(int argc, char *argv[])
  218. {
  219. glutInit(&argc, argv);
  220. glutInitWindowSize(800, 800);
  221. glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);
  222. glutCreateWindow(argv[0]);
  223. glutReshapeFunc(Reshape);
  224. glutKeyboardFunc(Key);
  225. glutSpecialFunc(SpecialKey);
  226. glutDisplayFunc(Draw);
  227. if (Anim)
  228. glutIdleFunc(Idle);
  229. Init();
  230. Usage();
  231. glutMainLoop();
  232. return 0;
  233. }