home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / demos / reflect.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  8KB  |  374 lines

  1. /* reflect.c */
  2.  
  3. /*
  4.  * Demo of a reflective, texture-mapped surface with OpenGL.
  5.  * Brian Paul  (brianp@ssec.wisc.edu)  August 14, 1995
  6.  *
  7.  * Hardware texture mapping is highly recommended!
  8.  *
  9.  * The basic steps are:
  10.  *    1. Render the reflective object (a polygon) from the normal viewpoint,
  11.  *       setting the stencil planes = 1.
  12.  *    2. Render the scene from a special viewpoint:  the viewpoint which
  13.  *       is on the opposite side of the reflective plane.  Only draw where
  14.  *       stencil = 1.  This draws the objects in the reflective surface.
  15.  *    3. Render the scene from the original viewpoint.  This draws the
  16.  *       objects in the normal fashion.  Use blending when drawing
  17.  *       the reflective, textured surface.
  18.  *
  19.  * This is a very crude demo.  It could be much better.
  20.  */
  21.  
  22. /*
  23.  * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
  24.  */
  25.  
  26.  
  27.  
  28. #define USE_ZBUFFER
  29.  
  30.  
  31. /* OK, without hardware support this is overkill. */
  32. #define USE_TEXTURE
  33.  
  34. #include <math.h>
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include "gltk.h"
  38.  
  39.  
  40. #define DEG2RAD (3.14159/180.0)
  41.  
  42.  
  43. #define TABLE_TEXTURE "../samples/1.rgb"
  44.  
  45.  
  46. #define MAX_OBJECTS 2
  47.  
  48. static GLint table_list;
  49. static GLint objects_list[MAX_OBJECTS];
  50.  
  51.  
  52. static GLfloat xrot, yrot;
  53. static GLfloat spin;
  54.  
  55.  
  56.  
  57. static void make_table( void )
  58. {
  59.    static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
  60.    static GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
  61.    static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
  62.    TK_RGBImageRec *image;
  63.  
  64.    table_list = glGenLists(1);
  65.    glNewList( table_list, GL_COMPILE );
  66.  
  67.    /* load table's texture */
  68.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
  69. /*   glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
  70.    glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
  71.    glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
  72.    
  73. #ifdef USE_TEXTURE
  74.    glEnable( GL_TEXTURE_2D );
  75.  
  76.    image = tkRGBImageLoad( TABLE_TEXTURE );
  77.    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY,
  78.                      GL_RGB, GL_UNSIGNED_BYTE, image->data);
  79.  
  80.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
  81.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
  82. #endif
  83.  
  84.    /* draw textured square for the table */
  85.    glPushMatrix();
  86.    glScalef( 4.0, 4.0, 4.0 );
  87.    glBegin( GL_POLYGON );
  88.    glNormal3f( 0.0, 1.0, 0.0 );
  89.    glTexCoord2f( 0.0, 0.0 );   glVertex3f( -1.0, 0.0,  1.0 );
  90.    glTexCoord2f( 1.0, 0.0 );   glVertex3f(  1.0, 0.0,  1.0 );
  91.    glTexCoord2f( 1.0, 1.0 );   glVertex3f(  1.0, 0.0, -1.0 );
  92.    glTexCoord2f( 0.0, 1.0 );   glVertex3f( -1.0, 0.0, -1.0 );
  93.    glEnd();
  94.    glPopMatrix();
  95.  
  96.    glDisable( GL_TEXTURE_2D );
  97.  
  98.    glEndList();
  99. }
  100.  
  101.  
  102. static void make_objects( void )
  103. {
  104.    GLUquadricObj *q;
  105.  
  106.    static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
  107.    static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
  108.    static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
  109.  
  110.    q = gluNewQuadric();
  111.    gluQuadricDrawStyle( q, GLU_FILL );
  112.    gluQuadricNormals( q, GLU_SMOOTH );
  113.  
  114.    objects_list[0] = glGenLists(1);
  115.    glNewList( objects_list[0], GL_COMPILE );
  116.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
  117.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  118.    gluCylinder( q, 0.5, 0.5,  1.0, 15, 10 );
  119.    glEndList();
  120.  
  121.    objects_list[1] = glGenLists(1);
  122.    glNewList( objects_list[1], GL_COMPILE );
  123.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
  124.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  125.    gluCylinder( q, 1.5, 0.0,  2.5, 15, 10 );
  126.    glEndList();
  127. }
  128.  
  129.  
  130.  
  131. static void init( void )
  132. {
  133.    static GLfloat light_pos[] = { 0.0, 0.0, 20.0, 1.0 };
  134.  
  135.    make_table();
  136.    make_objects();
  137.    xrot = 30.0;
  138.    yrot = 50.0;
  139.    spin = 0.0;
  140.  
  141. #ifndef USE_ZBUFFER
  142.    glEnable( GL_CULL_FACE );
  143. #endif
  144.  
  145.    glShadeModel( GL_FLAT );
  146.    
  147.    glEnable( GL_LIGHT0 );
  148.    glEnable( GL_LIGHTING );
  149.  
  150.    glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
  151.  
  152.    glClearColor( 0.5, 0.5, 0.5, 1.0 );
  153.  
  154.    glEnable( GL_NORMALIZE );
  155. }
  156.  
  157.  
  158.  
  159. static void reshape(int w, int h)
  160. {
  161.    GLfloat aspect = (float) w / (float) h;
  162.  
  163.    glViewport(0, 0, w, h);
  164.    glMatrixMode(GL_PROJECTION);
  165.    glLoadIdentity();
  166.    glFrustum( -aspect, aspect, -1.0, 1.0, 4.0, 300.0 );
  167.    glMatrixMode(GL_MODELVIEW);
  168.    glLoadIdentity();
  169. }
  170.  
  171.  
  172.  
  173. static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
  174. {
  175. #ifndef USE_ZUBFFER
  176.     if (eyex<0.5)
  177.     {
  178. #endif
  179.        glPushMatrix();
  180.        glTranslatef( 1.0, 1.5, 0.0 );
  181.        glRotatef( spin, 1.0, 0.5, 0.0 );
  182.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  183.        glCallList( objects_list[0] );
  184.        glPopMatrix();
  185.     
  186.        glPushMatrix();
  187.        glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  188.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  189.        glRotatef( spin, 1.0, 0.5, 0.0 );
  190.        glScalef( 0.5, 0.5, 0.5 );
  191.        glCallList( objects_list[1] );
  192.        glPopMatrix();
  193. #ifndef USE_ZUBFFER
  194.     }
  195.     else
  196.     {    
  197.        glPushMatrix();
  198.        glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  199.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  200.        glRotatef( spin, 1.0, 0.5, 0.0 );
  201.        glScalef( 0.5, 0.5, 0.5 );
  202.        glCallList( objects_list[1] );
  203.        glPopMatrix();
  204.  
  205.        glPushMatrix();
  206.        glTranslatef( 1.0, 1.5, 0.0 );
  207.        glRotatef( spin, 1.0, 0.5, 0.0 );
  208.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  209.        glCallList( objects_list[0] );
  210.        glPopMatrix();
  211.     }
  212. #endif
  213. }
  214.  
  215.  
  216.  
  217. static void draw_table( void )
  218. {
  219.    glCallList( table_list );
  220. }
  221.  
  222.  
  223. static void display( void )
  224. {
  225.    GLfloat dist = 20.0;
  226.    GLfloat eyex, eyey, eyez;
  227.  
  228.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  229.  
  230.  
  231.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  232.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  233.    eyey = dist * sin(xrot*DEG2RAD);
  234.  
  235.    /* view from top */
  236.    glPushMatrix();
  237.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  238.  
  239.  
  240.    /* draw table into stencil planes */
  241.    glEnable( GL_STENCIL_TEST );
  242. #ifdef USE_ZBUFFER
  243.    glDisable( GL_DEPTH_TEST );
  244. #endif
  245.    glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
  246.    glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
  247.    glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
  248.    draw_table();
  249.    glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
  250.  
  251. #ifdef USE_ZBUFFER
  252.    glEnable( GL_DEPTH_TEST );
  253. #endif
  254.  
  255.  
  256.    /* render view from below (reflected viewport) */
  257.    /* only draw where stencil==1 */
  258.    if (eyey>0.0) {
  259.       glPushMatrix();
  260.  
  261.       glStencilFunc( GL_EQUAL, 1, 0xffffffff );  /* draw if ==1 */
  262.       glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  263.       glScalef( 1.0, -1.0, 1.0 );
  264.       draw_objects(eyex, eyey, eyez);
  265.       glPopMatrix();
  266.    }
  267.  
  268.    glDisable( GL_STENCIL_TEST );
  269.  
  270.    glEnable( GL_BLEND );
  271.    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  272.  
  273.    draw_table();
  274.    glDisable( GL_BLEND );
  275.  
  276.    /* view from top */
  277.    glPushMatrix();
  278.  
  279.    draw_objects(eyex, eyey, eyez);
  280.  
  281.    glPopMatrix();
  282.  
  283.    glPopMatrix();
  284.  
  285.    tkSwapBuffers();
  286. }
  287.  
  288.  
  289. void disp(void)
  290. {
  291.    GLfloat dist = 20.0;
  292.    GLfloat eyex, eyey, eyez;
  293.  
  294.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  295.  
  296.  
  297.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  298.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  299.    eyey = dist * sin(xrot*DEG2RAD);
  300.  
  301.    /* view from top */
  302.    glPushMatrix();
  303.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  304.  
  305.    draw_table();
  306.  
  307.    glPopMatrix();
  308.  
  309.    tkSwapBuffers();
  310. }
  311.  
  312.  
  313.  
  314. GLenum key( int key, GLenum mask )
  315. {
  316.    switch (key) {
  317.       case 27:
  318.          exit(0);
  319.          break;
  320.  
  321.       case TK_UP:
  322.          xrot += 3.0;
  323. #ifndef USE_ZBUFFER
  324.          if ( xrot > 180 )    xrot = 180;
  325. #endif
  326.          break;
  327.       case TK_DOWN:
  328.          xrot -= 3.0;
  329. #ifndef USE_ZBUFFER
  330.          if ( xrot < 0 )    xrot = 0;
  331. #endif
  332.          break;
  333.       case TK_LEFT:
  334.          yrot += 3.0;
  335.          break;
  336.       case TK_RIGHT:
  337.          yrot -= 3.0;
  338.          break;
  339.    }
  340.    return 0;
  341. }
  342.  
  343.  
  344.  
  345. static void idle( void )
  346. {
  347.    spin += 2.0;
  348.    display();
  349. }
  350.  
  351.  
  352.  
  353. main( int argc, char *argv[] )
  354. {
  355.     tkInitDisplayMode(TK_DOUBLE | TK_RGB 
  356. #ifdef USE_ZBUFFER
  357.         | TK_DEPTH 
  358. #endif
  359.         | TK_STENCIL);
  360.     tkInitPosition( 0, 0, 400, 300 );
  361.     tkInitWindow(argv[0]);
  362.     tkReshapeFunc(reshape);
  363.     tkDisplayFunc(display);
  364.     tkKeyDownFunc(key);
  365.     tkIdleFunc(idle);
  366.  
  367.     init();
  368.  
  369.     tkExec();
  370. }
  371.  
  372.  
  373.  
  374.