home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / demos / reflect.c < prev    next >
C/C++ Source or Header  |  2000-01-07  |  10KB  |  436 lines

  1. /* $Id: reflect.c,v 1.1.1.1 1999/08/19 00:55:40 jtg Exp $ */
  2.  
  3. /*
  4.  * Demo of a reflective, texture-mapped surface with OpenGL.
  5.  * Brian Paul   August 14, 1995   This file is in the public domain.
  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.  * $Log: reflect.c,v $
  34.  * Revision 1.1.1.1  1999/08/19 00:55:40  jtg
  35.  * Imported sources
  36.  *
  37.  * Revision 3.4  1999/03/28 18:22:05  brianp
  38.  * minor clean-up
  39.  *
  40.  * Revision 3.3  1998/11/22 02:54:29  brianp
  41.  * only draw one stack for gluCylinders
  42.  *
  43.  * Revision 3.2  1998/11/19 02:53:48  brianp
  44.  * changed texture image and background color
  45.  *
  46.  * Revision 3.1  1998/11/05 04:34:04  brianp
  47.  * moved image files to ../images/ directory
  48.  *
  49.  * Revision 3.0  1998/02/14 18:42:29  brianp
  50.  * initial rev
  51.  *
  52.  */
  53.  
  54.  
  55. #define USE_ZBUFFER
  56.  
  57.  
  58. /* OK, without hardware support this is overkill. */
  59. #define USE_TEXTURE
  60.  
  61. #include <math.h>
  62. #include <stdio.h>
  63. #include <stdlib.h>
  64. #include "GL/glut.h"
  65.  
  66. #include "../util/readtex.c"  /* a hack, I know */
  67.  
  68.  
  69. #define DEG2RAD (3.14159/180.0)
  70.  
  71.  
  72. #define TABLE_TEXTURE "../images/tile.rgb"
  73.  
  74. static int ImgWidth, ImgHeight;
  75. static GLenum ImgFormat;
  76. static GLubyte *Image = NULL;
  77.  
  78. #define MAX_OBJECTS 2
  79.  
  80. static GLint table_list;
  81. static GLint objects_list[MAX_OBJECTS];
  82.  
  83.  
  84. static GLfloat xrot, yrot;
  85. static GLfloat spin;
  86.  
  87.  
  88.  
  89. static void make_table( void )
  90. {
  91.    static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
  92.    static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
  93.  
  94.    table_list = glGenLists(1);
  95.    glNewList( table_list, GL_COMPILE );
  96.  
  97.    /* load table's texture */
  98.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
  99. /*   glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
  100.    glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
  101.    glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
  102.    
  103.    /* draw textured square for the table */
  104.    glPushMatrix();
  105.    glScalef( 4.0, 4.0, 4.0 );
  106.    glBegin( GL_POLYGON );
  107.    glNormal3f( 0.0, 1.0, 0.0 );
  108.    glTexCoord2f( 0.0, 0.0 );   glVertex3f( -1.0, 0.0,  1.0 );
  109.    glTexCoord2f( 1.0, 0.0 );   glVertex3f(  1.0, 0.0,  1.0 );
  110.    glTexCoord2f( 1.0, 1.0 );   glVertex3f(  1.0, 0.0, -1.0 );
  111.    glTexCoord2f( 0.0, 1.0 );   glVertex3f( -1.0, 0.0, -1.0 );
  112.    glEnd();
  113.    glPopMatrix();
  114.  
  115.    glDisable( GL_TEXTURE_2D );
  116.  
  117.    glEndList();
  118. }
  119.  
  120.  
  121. static void make_objects( void )
  122. {
  123.    GLUquadricObj *q;
  124.  
  125.    static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
  126.    static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
  127.    static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
  128.  
  129.    q = gluNewQuadric();
  130.    gluQuadricDrawStyle( q, GLU_FILL );
  131.    gluQuadricNormals( q, GLU_SMOOTH );
  132.  
  133.    objects_list[0] = glGenLists(1);
  134.    glNewList( objects_list[0], GL_COMPILE );
  135.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
  136.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  137.    gluCylinder( q, 0.5, 0.5,  1.0, 15, 1 );
  138.    glEndList();
  139.  
  140.    objects_list[1] = glGenLists(1);
  141.    glNewList( objects_list[1], GL_COMPILE );
  142.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
  143.    glMaterialfv( GL_FRONT, GL_EMISSION, black );
  144.    gluCylinder( q, 1.5, 0.0,  2.5, 15, 1 );
  145.    glEndList();
  146. }
  147.  
  148.  
  149. static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 };
  150.  
  151. static void init( void )
  152. {
  153.    make_table();
  154.    make_objects();
  155.  
  156.    /* Setup texture */
  157. #ifdef USE_TEXTURE
  158.  
  159.    Image = LoadRGBImage( TABLE_TEXTURE, &ImgWidth, &ImgHeight, &ImgFormat );
  160.    if (!Image) {
  161.       printf("Couldn't read %s\n", TABLE_TEXTURE);
  162.       exit(0);
  163.    }
  164.  
  165.    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, ImgWidth, ImgHeight,
  166.                      ImgFormat, GL_UNSIGNED_BYTE, Image);
  167.  
  168.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
  169.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
  170.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  171.    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  172. #endif
  173.  
  174.  
  175.    xrot = 30.0;
  176.    yrot = 50.0;
  177.    spin = 0.0;
  178.  
  179. #ifndef USE_ZBUFFER
  180.    glEnable( GL_CULL_FACE );
  181. #endif
  182.  
  183.    glShadeModel( GL_FLAT );
  184.    
  185.    glEnable( GL_LIGHT0 );
  186.    glEnable( GL_LIGHTING );
  187.  
  188.    glClearColor( 0.5, 0.5, 0.9, 1.0 );
  189.  
  190.    glEnable( GL_NORMALIZE );
  191. }
  192.  
  193.  
  194.  
  195. static void reshape(int w, int h)
  196. {
  197.    GLfloat aspect = (float) w / (float) h;
  198.  
  199.    glViewport(0, 0, w, h);
  200.    glMatrixMode(GL_PROJECTION);
  201.    glLoadIdentity();
  202.    glFrustum( -aspect, aspect, -1.0, 1.0, 4.0, 300.0 );
  203.    glMatrixMode(GL_MODELVIEW);
  204.    glLoadIdentity();
  205. }
  206.  
  207.  
  208.  
  209. static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
  210. {
  211.    (void) eyex;
  212.    (void) eyey;
  213.    (void) eyez;
  214. #ifndef USE_ZBUFFER
  215.     if (eyex<0.5)
  216.     {
  217. #endif
  218.        glPushMatrix();
  219.        glTranslatef( 1.0, 1.5, 0.0 );
  220.        glRotatef( spin, 1.0, 0.5, 0.0 );
  221.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  222.        glCallList( objects_list[0] );
  223.        glPopMatrix();
  224.     
  225.        glPushMatrix();
  226.        glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  227.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  228.        glRotatef( spin, 1.0, 0.5, 0.0 );
  229.        glScalef( 0.5, 0.5, 0.5 );
  230.        glCallList( objects_list[1] );
  231.        glPopMatrix();
  232. #ifndef USE_ZBUFFER
  233.     }
  234.     else
  235.     {    
  236.        glPushMatrix();
  237.        glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  238.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  239.        glRotatef( spin, 1.0, 0.5, 0.0 );
  240.        glScalef( 0.5, 0.5, 0.5 );
  241.        glCallList( objects_list[1] );
  242.        glPopMatrix();
  243.  
  244.        glPushMatrix();
  245.        glTranslatef( 1.0, 1.5, 0.0 );
  246.        glRotatef( spin, 1.0, 0.5, 0.0 );
  247.        glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  248.        glCallList( objects_list[0] );
  249.        glPopMatrix();
  250.     }
  251. #endif
  252. }
  253.  
  254.  
  255.  
  256. static void draw_table( void )
  257. {
  258.    glCallList( table_list );
  259. }
  260.  
  261.  
  262.  
  263. static void draw_scene( void )
  264. {
  265.    GLfloat dist = 20.0;
  266.    GLfloat eyex, eyey, eyez;
  267.  
  268.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  269.  
  270.  
  271.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  272.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  273.    eyey = dist * sin(xrot*DEG2RAD);
  274.  
  275.    /* view from top */
  276.    glPushMatrix();
  277.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  278.  
  279.    glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
  280.  
  281.    /* draw table into stencil planes */
  282.    glEnable( GL_STENCIL_TEST );
  283. #ifdef USE_ZBUFFER
  284.    glDisable( GL_DEPTH_TEST );
  285. #endif
  286.    glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
  287.    glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
  288.    glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
  289.    draw_table();
  290.    glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
  291.  
  292. #ifdef USE_ZBUFFER
  293.    glEnable( GL_DEPTH_TEST );
  294. #endif
  295.  
  296.  
  297.    /* render view from below (reflected viewport) */
  298.    /* only draw where stencil==1 */
  299.    if (eyey>0.0) {
  300.       glPushMatrix();
  301.  
  302.       glStencilFunc( GL_EQUAL, 1, 0xffffffff );  /* draw if ==1 */
  303.       glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  304.       glScalef( 1.0, -1.0, 1.0 );
  305.  
  306.       /* Reposition light in reflected space. */
  307.       glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  308.  
  309.       draw_objects(eyex, eyey, eyez);
  310.       glPopMatrix();
  311.  
  312.       /* Restore light's original unreflected position. */
  313.       glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  314.    }
  315.  
  316.    glDisable( GL_STENCIL_TEST );
  317.  
  318.    glEnable( GL_BLEND );
  319.    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  320.  
  321. #ifdef USE_TEXTURE
  322.    glEnable( GL_TEXTURE_2D );
  323. #endif
  324.    draw_table();
  325.    glDisable( GL_TEXTURE_2D );
  326.    glDisable( GL_BLEND );
  327.  
  328.    /* view from top */
  329.    glPushMatrix();
  330.  
  331.    draw_objects(eyex, eyey, eyez);
  332.  
  333.    glPopMatrix();
  334.  
  335.    glPopMatrix();
  336.  
  337.    glutSwapBuffers();
  338. }
  339.  
  340.  
  341.  
  342. #if 0
  343. void draw_scene(void)
  344. {
  345.    GLfloat dist = 20.0;
  346.    GLfloat eyex, eyey, eyez;
  347.  
  348.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  349.  
  350.  
  351.    eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  352.    eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  353.    eyey = dist * sin(xrot*DEG2RAD);
  354.  
  355.    /* view from top */
  356.    glPushMatrix();
  357.    gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0,  0.0, 1.0, 0.0 );
  358.  
  359.    draw_table();
  360.  
  361.    glPopMatrix();
  362.  
  363.    glutSwapBuffers();
  364. }
  365. #endif
  366.  
  367.  
  368. static void Key( unsigned char key, int x, int y )
  369. {
  370.    (void) x;
  371.    (void) y;
  372.    if (key==27)
  373.       exit(0);
  374. }
  375.  
  376.  
  377. static void SpecialKey( int key, int x, int y )
  378. {
  379.    (void) x;
  380.    (void) y;
  381.    switch (key) {
  382.       case GLUT_KEY_UP:
  383.          xrot += 3.0;
  384. #ifndef USE_ZBUFFER
  385.          if ( xrot > 180 )    xrot = 180;
  386. #endif
  387.          break;
  388.       case GLUT_KEY_DOWN:
  389.          xrot -= 3.0;
  390. #ifndef USE_ZBUFFER
  391.          if ( xrot < 0 )    xrot = 0;
  392. #endif
  393.          break;
  394.       case GLUT_KEY_LEFT:
  395.          yrot += 3.0;
  396.          break;
  397.       case GLUT_KEY_RIGHT:
  398.          yrot -= 3.0;
  399.          break;
  400.    }
  401.    glutPostRedisplay();
  402. }
  403.  
  404.  
  405.  
  406. static void idle( void )
  407. {
  408.    spin += 2.0;
  409.    yrot += 3.0;
  410.    glutPostRedisplay();
  411. }
  412.  
  413.  
  414.  
  415. int main( int argc, char *argv[] )
  416. {
  417.    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB 
  418. #ifdef USE_ZBUFFER
  419.         | GLUT_DEPTH 
  420. #endif
  421.         | GLUT_STENCIL);
  422.    glutInitWindowPosition( 0, 0 );
  423.    glutInitWindowSize(400, 300 );
  424.    glutCreateWindow(argv[0]);
  425.    glutReshapeFunc(reshape);
  426.    glutDisplayFunc(draw_scene);
  427.    glutKeyboardFunc(Key);
  428.    glutSpecialFunc(SpecialKey);
  429.    glutIdleFunc(idle);
  430.  
  431.    init();
  432.  
  433.    glutMainLoop();
  434.    return 0;
  435. }
  436.