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.

reflect.c 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /*
  2. * Demo of a reflective, texture-mapped surface with OpenGL.
  3. * Brian Paul August 14, 1995 This file is in the public domain.
  4. *
  5. * Hardware texture mapping is highly recommended!
  6. *
  7. * The basic steps are:
  8. * 1. Render the reflective object (a polygon) from the normal viewpoint,
  9. * setting the stencil planes = 1.
  10. * 2. Render the scene from a special viewpoint: the viewpoint which
  11. * is on the opposite side of the reflective plane. Only draw where
  12. * stencil = 1. This draws the objects in the reflective surface.
  13. * 3. Render the scene from the original viewpoint. This draws the
  14. * objects in the normal fashion. Use blending when drawing
  15. * the reflective, textured surface.
  16. *
  17. * This is a very crude demo. It could be much better.
  18. */
  19. /*
  20. * Authors:
  21. * Brian Paul
  22. * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
  23. * Mark Kilgard (April 1997)
  24. * Brian Paul (April 2000 - added keyboard d/s options)
  25. */
  26. #include <math.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include "GL/glut.h"
  30. #include "../util/showbuffer.c"
  31. #include "../util/readtex.c"
  32. #define DEG2RAD (3.14159/180.0)
  33. #define TABLE_TEXTURE "../images/tile.rgb"
  34. static GLint ImgWidth, ImgHeight;
  35. static GLenum ImgFormat;
  36. static GLubyte *Image = NULL;
  37. #define MAX_OBJECTS 2
  38. static GLint table_list;
  39. static GLint objects_list[MAX_OBJECTS];
  40. static GLfloat xrot, yrot;
  41. static GLfloat spin;
  42. static GLint Width = 400, Height = 300;
  43. static GLenum ShowBuffer = GL_NONE;
  44. static GLboolean Anim = GL_TRUE;
  45. /* performance info */
  46. static GLint T0 = 0;
  47. static GLint Frames = 0;
  48. static void make_table( void )
  49. {
  50. static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
  51. static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
  52. table_list = glGenLists(1);
  53. glNewList( table_list, GL_COMPILE );
  54. /* load table's texture */
  55. glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
  56. /* glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
  57. glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
  58. glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
  59. /* draw textured square for the table */
  60. glPushMatrix();
  61. glScalef( 4.0, 4.0, 4.0 );
  62. glBegin( GL_POLYGON );
  63. glNormal3f( 0.0, 1.0, 0.0 );
  64. glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 0.0, 1.0 );
  65. glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
  66. glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, -1.0 );
  67. glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 0.0, -1.0 );
  68. glEnd();
  69. glPopMatrix();
  70. glDisable( GL_TEXTURE_2D );
  71. glEndList();
  72. }
  73. static void make_objects( void )
  74. {
  75. GLUquadricObj *q;
  76. static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
  77. static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
  78. static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
  79. q = gluNewQuadric();
  80. gluQuadricDrawStyle( q, GLU_FILL );
  81. gluQuadricNormals( q, GLU_SMOOTH );
  82. objects_list[0] = glGenLists(1);
  83. glNewList( objects_list[0], GL_COMPILE );
  84. glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
  85. glMaterialfv( GL_FRONT, GL_EMISSION, black );
  86. gluCylinder( q, 0.5, 0.5, 1.0, 15, 1 );
  87. glEndList();
  88. objects_list[1] = glGenLists(1);
  89. glNewList( objects_list[1], GL_COMPILE );
  90. glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
  91. glMaterialfv( GL_FRONT, GL_EMISSION, black );
  92. gluCylinder( q, 1.5, 0.0, 2.5, 15, 1 );
  93. glEndList();
  94. }
  95. static void init( void )
  96. {
  97. make_table();
  98. make_objects();
  99. Image = LoadRGBImage( TABLE_TEXTURE, &ImgWidth, &ImgHeight, &ImgFormat );
  100. if (!Image) {
  101. printf("Couldn't read %s\n", TABLE_TEXTURE);
  102. exit(0);
  103. }
  104. gluBuild2DMipmaps(GL_TEXTURE_2D, 3, ImgWidth, ImgHeight,
  105. ImgFormat, GL_UNSIGNED_BYTE, Image);
  106. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
  107. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
  108. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  109. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  110. xrot = 30.0;
  111. yrot = 50.0;
  112. spin = 0.0;
  113. glShadeModel( GL_FLAT );
  114. glEnable( GL_LIGHT0 );
  115. glEnable( GL_LIGHTING );
  116. glClearColor( 0.5, 0.5, 0.9, 0.0 );
  117. glEnable( GL_NORMALIZE );
  118. }
  119. static void reshape(int w, int h)
  120. {
  121. GLfloat yAspect = 2.5;
  122. GLfloat xAspect = yAspect * (float) w / (float) h;
  123. Width = w;
  124. Height = h;
  125. glViewport(0, 0, w, h);
  126. glMatrixMode(GL_PROJECTION);
  127. glLoadIdentity();
  128. glFrustum( -xAspect, xAspect, -yAspect, yAspect, 10.0, 30.0 );
  129. glMatrixMode(GL_MODELVIEW);
  130. glLoadIdentity();
  131. }
  132. static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
  133. {
  134. (void) eyex;
  135. (void) eyey;
  136. (void) eyez;
  137. #ifndef USE_ZBUFFER
  138. if (eyex<0.5) {
  139. #endif
  140. glPushMatrix();
  141. glTranslatef( 1.0, 1.5, 0.0 );
  142. glRotatef( spin, 1.0, 0.5, 0.0 );
  143. glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  144. glCallList( objects_list[0] );
  145. glPopMatrix();
  146. glPushMatrix();
  147. glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  148. glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  149. glRotatef( spin, 1.0, 0.5, 0.0 );
  150. glScalef( 0.5, 0.5, 0.5 );
  151. glCallList( objects_list[1] );
  152. glPopMatrix();
  153. #ifndef USE_ZBUFFER
  154. }
  155. else {
  156. glPushMatrix();
  157. glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  158. glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  159. glRotatef( spin, 1.0, 0.5, 0.0 );
  160. glScalef( 0.5, 0.5, 0.5 );
  161. glCallList( objects_list[1] );
  162. glPopMatrix();
  163. glPushMatrix();
  164. glTranslatef( 1.0, 1.5, 0.0 );
  165. glRotatef( spin, 1.0, 0.5, 0.0 );
  166. glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  167. glCallList( objects_list[0] );
  168. glPopMatrix();
  169. }
  170. #endif
  171. }
  172. static void draw_table( void )
  173. {
  174. glCallList( table_list );
  175. }
  176. static void draw_scene( void )
  177. {
  178. static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 };
  179. GLfloat dist = 20.0;
  180. GLfloat eyex, eyey, eyez;
  181. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  182. eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  183. eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  184. eyey = dist * sin(xrot*DEG2RAD);
  185. /* view from top */
  186. glPushMatrix();
  187. gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
  188. glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
  189. /* draw table into stencil planes */
  190. glDisable( GL_DEPTH_TEST );
  191. glEnable( GL_STENCIL_TEST );
  192. glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
  193. glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
  194. glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
  195. draw_table();
  196. glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
  197. glEnable( GL_DEPTH_TEST );
  198. /* render view from below (reflected viewport) */
  199. /* only draw where stencil==1 */
  200. if (eyey>0.0) {
  201. glPushMatrix();
  202. glStencilFunc( GL_EQUAL, 1, 0xffffffff ); /* draw if ==1 */
  203. glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  204. glScalef( 1.0, -1.0, 1.0 );
  205. /* Reposition light in reflected space. */
  206. glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  207. draw_objects(eyex, eyey, eyez);
  208. glPopMatrix();
  209. /* Restore light's original unreflected position. */
  210. glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  211. }
  212. glDisable( GL_STENCIL_TEST );
  213. glEnable( GL_BLEND );
  214. glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  215. glEnable( GL_TEXTURE_2D );
  216. draw_table();
  217. glDisable( GL_TEXTURE_2D );
  218. glDisable( GL_BLEND );
  219. /* view from top */
  220. glPushMatrix();
  221. draw_objects(eyex, eyey, eyez);
  222. glPopMatrix();
  223. glPopMatrix();
  224. if (ShowBuffer == GL_DEPTH) {
  225. ShowDepthBuffer(Width, Height, 1.0, 0.0);
  226. }
  227. else if (ShowBuffer == GL_STENCIL) {
  228. ShowStencilBuffer(Width, Height, 255.0, 0.0);
  229. }
  230. else if (ShowBuffer == GL_ALPHA) {
  231. ShowAlphaBuffer(Width, Height);
  232. }
  233. glutSwapBuffers();
  234. {
  235. GLint t = glutGet(GLUT_ELAPSED_TIME);
  236. Frames++;
  237. if (t - T0 >= 5000) {
  238. GLfloat seconds = (t - T0) / 1000.0;
  239. GLfloat fps = Frames / seconds;
  240. printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
  241. T0 = t;
  242. Frames = 0;
  243. }
  244. }
  245. }
  246. static void idle( void )
  247. {
  248. spin += 2.0;
  249. yrot += 3.0;
  250. glutPostRedisplay();
  251. }
  252. static void Key( unsigned char key, int x, int y )
  253. {
  254. (void) x;
  255. (void) y;
  256. if (key == 'd') {
  257. ShowBuffer = GL_DEPTH;
  258. }
  259. else if (key == 's') {
  260. ShowBuffer = GL_STENCIL;
  261. }
  262. else if (key == 'a') {
  263. ShowBuffer = GL_ALPHA;
  264. }
  265. else if (key == ' ') {
  266. Anim = !Anim;
  267. if (Anim)
  268. glutIdleFunc(idle);
  269. else
  270. glutIdleFunc(NULL);
  271. }
  272. else if (key==27) {
  273. exit(0);
  274. }
  275. else {
  276. ShowBuffer = GL_NONE;
  277. }
  278. glutPostRedisplay();
  279. }
  280. static void SpecialKey( int key, int x, int y )
  281. {
  282. (void) x;
  283. (void) y;
  284. switch (key) {
  285. case GLUT_KEY_UP:
  286. xrot += 3.0;
  287. if ( xrot > 85 )
  288. xrot = 85;
  289. break;
  290. case GLUT_KEY_DOWN:
  291. xrot -= 3.0;
  292. if ( xrot < 5 )
  293. xrot = 5;
  294. break;
  295. case GLUT_KEY_LEFT:
  296. yrot += 3.0;
  297. break;
  298. case GLUT_KEY_RIGHT:
  299. yrot -= 3.0;
  300. break;
  301. }
  302. glutPostRedisplay();
  303. }
  304. int main( int argc, char *argv[] )
  305. {
  306. glutInit(&argc, argv);
  307. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL);
  308. glutInitWindowPosition( 0, 0 );
  309. glutInitWindowSize( Width, Height );
  310. glutCreateWindow(argv[0]);
  311. glutReshapeFunc(reshape);
  312. glutDisplayFunc(draw_scene);
  313. glutKeyboardFunc(Key);
  314. glutSpecialFunc(SpecialKey);
  315. glutIdleFunc(idle);
  316. init();
  317. glutMainLoop();
  318. return 0;
  319. }