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 8.8KB

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