home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / demos / reflect.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-09  |  8.5 KB  |  396 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.  * August 1996 - A few optimizations by Brian
  26.  */
  27.  
  28. /*
  29.  * April, 1997 - Added Mark Kilgard's changes.
  30.  */
  31.  
  32.  
  33. #define USE_ZBUFFER
  34.  
  35.  
  36. /* OK, without hardware support this is overkill. */
  37. #define USE_TEXTURE
  38.  
  39. #include <math.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include "gltk.h"
  43.  
  44.  
  45. #define DEG2RAD (3.14159/180.0)
  46.  
  47.  
  48. #ifndef AMIGAWARP
  49. #define TABLE_TEXTURE "../samples/1.rgb"
  50. #else
  51. #define TABLE_TEXTURE "mesa:samples/1.rgb"
  52. #endif
  53.  
  54. #define MAX_OBJECTS 2
  55.  
  56. static GLint table_list;
  57. static GLint objects_list[MAX_OBJECTS];
  58.  
  59.  
  60. static GLfloat xrot, yrot;
  61. static GLfloat spin;
  62.  
  63.  
  64.  
  65. static void make_table( void )
  66. {
  67.    static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
  68.    static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
  69.  
  70.    table_list = glGenLists(1);
  71.    glNewList( table_list, GL_COMPILE );
  72.  
  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.    
  79.    /* draw textured square for the table */
  80.    glPushMatrix();
  81.    glScalef( 4.0, 4.0, 4.0 );
  82.    glBegin( GL_POLYGON );
  83.    glNormal3f( 0.0, 1.0, 0.0 );
  84.    glTexCoord2f( 0.0, 0.0 );   glVertex3f( -1.0, 0.0,  1.0 );
  85.    glTexCoord2f( 1.0, 0.0 );   glVertex3f(  1.0, 0.0,  1.0 );
  86.    glTexCoord2f( 1.0, 1.0 );   glVertex3f(  1.0, 0.0, -1.0 );
  87.    glTexCoord2f( 0.0, 1.0 );   glVertex3f( -1.0, 0.0, -1.0 );
  88.    glEnd();
  89.    glPopMatrix();
  90.  
  91.    glDisable( GL_TEXTURE_2D );
  92.  
  93.    glEndList();
  94. }
  95.  
  96.  
  97. static void make_objects( void )
  98. {
  99.    GLUquadricObj *q;
  100.  
  101.    static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
  102.    static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
  103.    static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
  104.  
  105.    q = gluNewQuadric();
  106.    gluQuadricDrawStyle( q, GLU_FILL );
  107.    gluQuadricNormals( q, GLU_SMOOTH );
  108.  
  109.    objects_list[0] = glGenLists(1);
  110.    glNewList( objects_list[0], GL_COMPILE );
  111.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
  112.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  113.    gluCylinder( q, 0.5, 0.5,  1.0, 15, 10 );
  114.    glEndList();
  115.  
  116.    objects_list[1] = glGenLists(1);
  117.    glNewList( objects_list[1], GL_COMPILE );
  118.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
  119.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  120.    gluCylinder( q, 1.5, 0.0,  2.5, 15, 10 );
  121.    glEndList();
  122. }
  123.  
  124.  
  125. static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 };
  126.  
  127. static void init( void )
  128. {
  129.    TK_RGBImageRec *image;
  130.  
  131.    make_table();
  132.    make_objects();
  133.  
  134.    /* Setup texture */
  135. #ifdef USE_TEXTURE
  136.    image = tkRGBImageLoad( TABLE_TEXTURE );
  137.    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY,
  138.              GL_RGB, GL_UNSIGNED_BYTE, image->data);
  139.  
  140.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
  141.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
  142.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  143.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  144. #endif
  145.  
  146.  
  147.    xrot = 30.0;
  148.    yrot = 50.0;
  149.    spin = 0.0;
  150.  
  151. #ifndef USE_ZBUFFER
  152.    glEnable( GL_CULL_FACE );
  153. #endif
  154.  
  155.    glShadeModel( GL_FLAT );
  156.    
  157.    glEnable( GL_LIGHT0 );
  158.    glEnable( GL_LIGHTING );
  159.  
  160.    glClearColor( 0.5, 0.5, 0.5, 1.0 );
  161.  
  162.    glEnable( GL_NORMALIZE );
  163. }
  164.  
  165.  
  166.  
  167. static void reshape(int w, int h)
  168. {
  169.    GLfloat aspect = (float) w / (float) h;
  170.  
  171.    glViewport(0, 0, w, h);
  172.    glMatrixMode(GL_PROJECTION);
  173.    glLoadIdentity();
  174.    glFrustum( -aspect, aspect, -1.0, 1.0, 4.0, 300.0 );
  175.    glMatrixMode(GL_MODELVIEW);
  176.    glLoadIdentity();
  177. }
  178.  
  179.  
  180.  
  181. static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
  182. {
  183. #ifndef USE_ZBUFFER
  184.     if (eyex<0.5)
  185.     {
  186. #endif
  187.        glPushMatrix();
  188.        glTranslatef( 1.0, 1.5, 0.0 );
  189.        glRotatef( spin, 1.0, 0.5, 0.0 );
  190.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  191.        glCallList( objects_list[0] );
  192.        glPopMatrix();
  193.     
  194.        glPushMatrix();
  195.        glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  196.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  197.        glRotatef( spin, 1.0, 0.5, 0.0 );
  198.        glScalef( 0.5, 0.5, 0.5 );
  199.        glCallList( objects_list[1] );
  200.        glPopMatrix();
  201. #ifndef USE_ZBUFFER
  202.     }
  203.     else
  204.     {       
  205.        glPushMatrix();
  206.        glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  207.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  208.        glRotatef( spin, 1.0, 0.5, 0.0 );
  209.        glScalef( 0.5, 0.5, 0.5 );
  210.        glCallList( objects_list[1] );
  211.        glPopMatrix();
  212.  
  213.        glPushMatrix();
  214.        glTranslatef( 1.0, 1.5, 0.0 );
  215.        glRotatef( spin, 1.0, 0.5, 0.0 );
  216.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  217.        glCallList( objects_list[0] );
  218.        glPopMatrix();
  219.     }
  220. #endif
  221. }
  222.  
  223.  
  224.  
  225. static void draw_table( void )
  226. {
  227.    glCallList( table_list );
  228. }
  229.  
  230.  
  231.  
  232. static void draw_scene( void )
  233. {
  234.    GLfloat dist = 20.0;
  235.    GLfloat eyex, eyey, eyez;
  236.  
  237.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  238.  
  239.  
  240.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  241.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  242.    eyey = dist * sin(xrot*DEG2RAD);
  243.  
  244.    /* view from top */
  245.    glPushMatrix();
  246.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  247.  
  248.    glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
  249.  
  250.    /* draw table into stencil planes */
  251.    glEnable( GL_STENCIL_TEST );
  252. #ifdef USE_ZBUFFER
  253.    glDisable( GL_DEPTH_TEST );
  254. #endif
  255.    glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
  256.    glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
  257.    glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
  258.    draw_table();
  259.    glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
  260.  
  261. #ifdef USE_ZBUFFER
  262.    glEnable( GL_DEPTH_TEST );
  263. #endif
  264.  
  265.  
  266.    /* render view from below (reflected viewport) */
  267.    /* only draw where stencil==1 */
  268.    if (eyey>0.0) {
  269.       glPushMatrix();
  270.  
  271.       glStencilFunc( GL_EQUAL, 1, 0xffffffff );  /* draw if ==1 */
  272.       glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  273.       glScalef( 1.0, -1.0, 1.0 );
  274.  
  275.       /* Reposition light in reflected space. */
  276.       glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  277.  
  278.       draw_objects(eyex, eyey, eyez);
  279.       glPopMatrix();
  280.  
  281.       /* Restore light's original unreflected position. */
  282.       glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  283.    }
  284.  
  285.    glDisable( GL_STENCIL_TEST );
  286.  
  287.    glEnable( GL_BLEND );
  288.    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  289.  
  290. #ifdef USE_TEXTURE
  291.    glEnable( GL_TEXTURE_2D );
  292. #endif
  293.    draw_table();
  294.    glDisable( GL_TEXTURE_2D );
  295.    glDisable( GL_BLEND );
  296.  
  297.    /* view from top */
  298.    glPushMatrix();
  299.  
  300.    draw_objects(eyex, eyey, eyez);
  301.  
  302.    glPopMatrix();
  303.  
  304.    glPopMatrix();
  305.  
  306.    tkSwapBuffers();
  307. }
  308.  
  309.  
  310.  
  311. #if 0
  312. void draw_scene(void)
  313. {
  314.    GLfloat dist = 20.0;
  315.    GLfloat eyex, eyey, eyez;
  316.  
  317.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  318.  
  319.  
  320.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  321.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  322.    eyey = dist * sin(xrot*DEG2RAD);
  323.  
  324.    /* view from top */
  325.    glPushMatrix();
  326.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  327.  
  328.    draw_table();
  329.  
  330.    glPopMatrix();
  331.  
  332.    tkSwapBuffers();
  333. }
  334. #endif
  335.  
  336.  
  337. GLenum key( int key, GLenum mask )
  338. {
  339.    switch (key) {
  340.       case 27:
  341.      exit(0);
  342.      break;
  343.  
  344.       case TK_UP:
  345.      xrot += 3.0;
  346. #ifndef USE_ZBUFFER
  347.          if ( xrot > 180 )      xrot = 180;
  348. #endif
  349.      break;
  350.       case TK_DOWN:
  351.      xrot -= 3.0;
  352. #ifndef USE_ZBUFFER
  353.          if ( xrot < 0 )        xrot = 0;
  354. #endif
  355.      break;
  356.       case TK_LEFT:
  357.      yrot += 3.0;
  358.      break;
  359.       case TK_RIGHT:
  360.      yrot -= 3.0;
  361.      break;
  362.    }
  363.    return 0;
  364. }
  365.  
  366.  
  367.  
  368. static void idle( void )
  369. {
  370.    spin += 2.0;
  371.    yrot += 3.0;
  372.    draw_scene();
  373. }
  374.  
  375.  
  376.  
  377. int main( int argc, char *argv[] )
  378. {
  379.     tkInitDisplayMode(TK_DOUBLE | TK_RGB 
  380. #ifdef USE_ZBUFFER
  381.         | TK_DEPTH 
  382. #endif
  383.         | TK_STENCIL);
  384.     tkInitPosition( 0, 0, 400, 300 );
  385.     tkInitWindow(argv[0]);
  386.     tkReshapeFunc(reshape);
  387.     tkDisplayFunc(draw_scene);
  388.     tkKeyDownFunc(key);
  389.     tkIdleFunc(idle);
  390.  
  391.     init();
  392.  
  393.     tkExec();
  394.     return 0;
  395. }
  396.