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.

spectex.c 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /*
  2. * GLUT demonstration of texturing with specular highlights.
  3. *
  4. * When drawing a lit, textured surface one usually wants the specular
  5. * highlight to override the texture colors. However, OpenGL applies
  6. * texturing after lighting so the specular highlight is modulated by
  7. * the texture.
  8. *
  9. * The solution here shown here is a two-pass algorithm:
  10. * 1. Draw the textured surface without specular lighting.
  11. * 2. Enable blending to add the next pass:
  12. * 3. Redraw the surface with a matte white material and only the
  13. * specular components of light sources enabled.
  14. *
  15. * Brian Paul February 1997
  16. */
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <math.h>
  20. #include <GL/glut.h>
  21. static GLUquadricObj *Quadric;
  22. static GLuint Sphere;
  23. static GLfloat LightPos[4] = {10.0, 10.0, 10.0, 1.0};
  24. static GLfloat Delta = 20.0;
  25. static GLint Mode = 4;
  26. /*static GLfloat Blue[4] = {0.0, 0.0, 1.0, 1.0};*/
  27. /*static GLfloat Gray[4] = {0.5, 0.5, 0.5, 1.0};*/
  28. static GLfloat Black[4] = {0.0, 0.0, 0.0, 1.0};
  29. static GLfloat White[4] = {1.0, 1.0, 1.0, 1.0};
  30. static GLboolean smooth = 1;
  31. static void
  32. Idle(void)
  33. {
  34. static double t0 = -1.;
  35. double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;;
  36. if (t0 < 0.0)
  37. t0 = t;
  38. dt = t - t0;
  39. t0 = t;
  40. LightPos[0] += Delta * dt;
  41. if (LightPos[0]>15.0 || LightPos[0]<-15.0)
  42. Delta = -Delta;
  43. glutPostRedisplay();
  44. }
  45. static void Display( void )
  46. {
  47. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  48. glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
  49. glPushMatrix();
  50. glRotatef(90.0, 1.0, 0.0, 0.0);
  51. if (Mode==0) {
  52. /* Typical method: diffuse + specular + texture */
  53. glEnable(GL_TEXTURE_2D);
  54. glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
  55. glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
  56. #ifdef GL_VERSION_1_2
  57. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  58. #endif
  59. glCallList(Sphere);
  60. }
  61. else if (Mode==1) {
  62. /* just specular highlight */
  63. glDisable(GL_TEXTURE_2D);
  64. glLightfv(GL_LIGHT0, GL_DIFFUSE, Black); /* disable diffuse */
  65. glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
  66. #ifdef GL_VERSION_1_2
  67. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  68. #endif
  69. glCallList(Sphere);
  70. }
  71. else if (Mode==2) {
  72. /* diffuse textured */
  73. glEnable(GL_TEXTURE_2D);
  74. glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
  75. glLightfv(GL_LIGHT0, GL_SPECULAR, Black); /* disable specular */
  76. #ifdef GL_VERSION_1_2
  77. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  78. #endif
  79. glCallList(Sphere);
  80. }
  81. else if (Mode==3) {
  82. /* 2-pass: diffuse textured then add specular highlight*/
  83. glEnable(GL_TEXTURE_2D);
  84. glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
  85. glLightfv(GL_LIGHT0, GL_SPECULAR, Black); /* disable specular */
  86. #ifdef GL_VERSION_1_2
  87. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  88. #endif
  89. glCallList(Sphere);
  90. /* specular highlight */
  91. glDepthFunc(GL_EQUAL); /* redraw same pixels */
  92. glDisable(GL_TEXTURE_2D);
  93. glEnable(GL_BLEND); /* add */
  94. glLightfv(GL_LIGHT0, GL_DIFFUSE, Black); /* disable diffuse */
  95. glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
  96. glCallList(Sphere);
  97. glDepthFunc(GL_LESS);
  98. glDisable(GL_BLEND);
  99. }
  100. else if (Mode==4) {
  101. /* OpenGL 1.2's separate diffuse and specular color */
  102. glEnable(GL_TEXTURE_2D);
  103. glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
  104. glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
  105. #ifdef GL_VERSION_1_2
  106. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
  107. #endif
  108. glCallList(Sphere);
  109. }
  110. glPopMatrix();
  111. glutSwapBuffers();
  112. }
  113. static void Reshape( int width, int height )
  114. {
  115. glViewport( 0, 0, width, height );
  116. glMatrixMode( GL_PROJECTION );
  117. glLoadIdentity();
  118. glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
  119. glMatrixMode( GL_MODELVIEW );
  120. glLoadIdentity();
  121. glTranslatef( 0.0, 0.0, -12.0 );
  122. }
  123. static void Key( unsigned char key, int x, int y )
  124. {
  125. (void) x;
  126. (void) y;
  127. switch (key) {
  128. case 27:
  129. exit(0);
  130. break;
  131. case 's':
  132. smooth = !smooth;
  133. if (smooth)
  134. glShadeModel(GL_SMOOTH);
  135. else
  136. glShadeModel(GL_FLAT);
  137. break;
  138. }
  139. glutPostRedisplay();
  140. }
  141. static void SpecialKey( int key, int x, int y )
  142. {
  143. (void) x;
  144. (void) y;
  145. switch (key) {
  146. case GLUT_KEY_UP:
  147. break;
  148. case GLUT_KEY_DOWN:
  149. break;
  150. }
  151. glutPostRedisplay();
  152. }
  153. static void Init( void )
  154. {
  155. int i, j;
  156. GLubyte texImage[64][64][3];
  157. glEnable(GL_LIGHTING);
  158. glEnable(GL_LIGHT0);
  159. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
  160. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Black);
  161. glShadeModel(GL_SMOOTH);
  162. glMaterialfv(GL_FRONT, GL_DIFFUSE, White);
  163. glMaterialfv(GL_FRONT, GL_SPECULAR, White);
  164. glMaterialf(GL_FRONT, GL_SHININESS, 20.0);
  165. /* Actually, these are set again later */
  166. glLightfv(GL_LIGHT0, GL_DIFFUSE, White);
  167. glLightfv(GL_LIGHT0, GL_SPECULAR, White);
  168. Quadric = gluNewQuadric();
  169. gluQuadricTexture( Quadric, GL_TRUE );
  170. Sphere= glGenLists(1);
  171. glNewList( Sphere, GL_COMPILE );
  172. gluSphere( Quadric, 1.0, 24, 24 );
  173. glEndList();
  174. glEnable(GL_DEPTH_TEST);
  175. glEnable(GL_CULL_FACE);
  176. for (i=0;i<64;i++) {
  177. for (j=0;j<64;j++) {
  178. int k = ((i>>3)&1) ^ ((j>>3)&1);
  179. texImage[i][j][0] = 255*k;
  180. texImage[i][j][1] = 255*(1-k);
  181. texImage[i][j][2] = 0;
  182. }
  183. }
  184. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  185. glTexImage2D( GL_TEXTURE_2D,
  186. 0,
  187. 3,
  188. 64, 64,
  189. 0,
  190. GL_RGB, GL_UNSIGNED_BYTE,
  191. texImage );
  192. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  193. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  194. glEnable(GL_TEXTURE_2D);
  195. glBlendFunc(GL_ONE, GL_ONE);
  196. }
  197. static void ModeMenu(int entry)
  198. {
  199. if (entry==99)
  200. exit(0);
  201. Mode = entry;
  202. }
  203. int main( int argc, char *argv[] )
  204. {
  205. glutInit( &argc, argv );
  206. glutInitWindowPosition( 0, 0 );
  207. glutInitWindowSize( 300, 300 );
  208. glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
  209. glutCreateWindow( "spectex" );
  210. Init();
  211. glutReshapeFunc( Reshape );
  212. glutKeyboardFunc( Key );
  213. glutSpecialFunc( SpecialKey );
  214. glutDisplayFunc( Display );
  215. glutIdleFunc( Idle );
  216. glutCreateMenu( ModeMenu );
  217. glutAddMenuEntry("1-pass lighting + texturing", 0);
  218. glutAddMenuEntry("specular lighting", 1);
  219. glutAddMenuEntry("diffuse lighting + texturing", 2);
  220. glutAddMenuEntry("2-pass lighting + texturing", 3);
  221. #ifdef GL_VERSION_1_2
  222. glutAddMenuEntry("OpenGL 1.2 separate specular", 4);
  223. #endif
  224. glutAddMenuEntry("Quit", 99);
  225. glutAttachMenu(GLUT_RIGHT_BUTTON);
  226. glutMainLoop();
  227. return 0;
  228. }