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.5KB

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