home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #6
/
amigamamagazinepolishissue1998.iso
/
coders
/
mesa-1.2.8
/
demos
/
reflect.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-27
|
8KB
|
374 lines
/* reflect.c */
/*
* Demo of a reflective, texture-mapped surface with OpenGL.
* Brian Paul (brianp@ssec.wisc.edu) August 14, 1995
*
* Hardware texture mapping is highly recommended!
*
* The basic steps are:
* 1. Render the reflective object (a polygon) from the normal viewpoint,
* setting the stencil planes = 1.
* 2. Render the scene from a special viewpoint: the viewpoint which
* is on the opposite side of the reflective plane. Only draw where
* stencil = 1. This draws the objects in the reflective surface.
* 3. Render the scene from the original viewpoint. This draws the
* objects in the normal fashion. Use blending when drawing
* the reflective, textured surface.
*
* This is a very crude demo. It could be much better.
*/
/*
* Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
*/
#define USE_ZBUFFER
/* OK, without hardware support this is overkill. */
#define USE_TEXTURE
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "gltk.h"
#define DEG2RAD (3.14159/180.0)
#define TABLE_TEXTURE "../samples/1.rgb"
#define MAX_OBJECTS 2
static GLint table_list;
static GLint objects_list[MAX_OBJECTS];
static GLfloat xrot, yrot;
static GLfloat spin;
static void make_table( void )
{
static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
static GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
TK_RGBImageRec *image;
table_list = glGenLists(1);
glNewList( table_list, GL_COMPILE );
/* load table's texture */
glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
/* glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
#ifdef USE_TEXTURE
glEnable( GL_TEXTURE_2D );
image = tkRGBImageLoad( TABLE_TEXTURE );
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY,
GL_RGB, GL_UNSIGNED_BYTE, image->data);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
#endif
/* draw textured square for the table */
glPushMatrix();
glScalef( 4.0, 4.0, 4.0 );
glBegin( GL_POLYGON );
glNormal3f( 0.0, 1.0, 0.0 );
glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 0.0, 1.0 );
glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, -1.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 0.0, -1.0 );
glEnd();
glPopMatrix();
glDisable( GL_TEXTURE_2D );
glEndList();
}
static void make_objects( void )
{
GLUquadricObj *q;
static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
q = gluNewQuadric();
gluQuadricDrawStyle( q, GLU_FILL );
gluQuadricNormals( q, GLU_SMOOTH );
objects_list[0] = glGenLists(1);
glNewList( objects_list[0], GL_COMPILE );
glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
glMaterialfv( GL_FRONT, GL_EMISSION, black );
gluCylinder( q, 0.5, 0.5, 1.0, 15, 10 );
glEndList();
objects_list[1] = glGenLists(1);
glNewList( objects_list[1], GL_COMPILE );
glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
glMaterialfv( GL_FRONT, GL_EMISSION, black );
gluCylinder( q, 1.5, 0.0, 2.5, 15, 10 );
glEndList();
}
static void init( void )
{
static GLfloat light_pos[] = { 0.0, 0.0, 20.0, 1.0 };
make_table();
make_objects();
xrot = 30.0;
yrot = 50.0;
spin = 0.0;
#ifndef USE_ZBUFFER
glEnable( GL_CULL_FACE );
#endif
glShadeModel( GL_FLAT );
glEnable( GL_LIGHT0 );
glEnable( GL_LIGHTING );
glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
glClearColor( 0.5, 0.5, 0.5, 1.0 );
glEnable( GL_NORMALIZE );
}
static void reshape(int w, int h)
{
GLfloat aspect = (float) w / (float) h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum( -aspect, aspect, -1.0, 1.0, 4.0, 300.0 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
{
#ifndef USE_ZUBFFER
if (eyex<0.5)
{
#endif
glPushMatrix();
glTranslatef( 1.0, 1.5, 0.0 );
glRotatef( spin, 1.0, 0.5, 0.0 );
glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
glCallList( objects_list[0] );
glPopMatrix();
glPushMatrix();
glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
glRotatef( spin, 1.0, 0.5, 0.0 );
glScalef( 0.5, 0.5, 0.5 );
glCallList( objects_list[1] );
glPopMatrix();
#ifndef USE_ZUBFFER
}
else
{
glPushMatrix();
glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
glRotatef( spin, 1.0, 0.5, 0.0 );
glScalef( 0.5, 0.5, 0.5 );
glCallList( objects_list[1] );
glPopMatrix();
glPushMatrix();
glTranslatef( 1.0, 1.5, 0.0 );
glRotatef( spin, 1.0, 0.5, 0.0 );
glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
glCallList( objects_list[0] );
glPopMatrix();
}
#endif
}
static void draw_table( void )
{
glCallList( table_list );
}
static void display( void )
{
GLfloat dist = 20.0;
GLfloat eyex, eyey, eyez;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
eyey = dist * sin(xrot*DEG2RAD);
/* view from top */
glPushMatrix();
gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
/* draw table into stencil planes */
glEnable( GL_STENCIL_TEST );
#ifdef USE_ZBUFFER
glDisable( GL_DEPTH_TEST );
#endif
glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
draw_table();
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
#ifdef USE_ZBUFFER
glEnable( GL_DEPTH_TEST );
#endif
/* render view from below (reflected viewport) */
/* only draw where stencil==1 */
if (eyey>0.0) {
glPushMatrix();
glStencilFunc( GL_EQUAL, 1, 0xffffffff ); /* draw if ==1 */
glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
glScalef( 1.0, -1.0, 1.0 );
draw_objects(eyex, eyey, eyez);
glPopMatrix();
}
glDisable( GL_STENCIL_TEST );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
draw_table();
glDisable( GL_BLEND );
/* view from top */
glPushMatrix();
draw_objects(eyex, eyey, eyez);
glPopMatrix();
glPopMatrix();
tkSwapBuffers();
}
void disp(void)
{
GLfloat dist = 20.0;
GLfloat eyex, eyey, eyez;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
eyey = dist * sin(xrot*DEG2RAD);
/* view from top */
glPushMatrix();
gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
draw_table();
glPopMatrix();
tkSwapBuffers();
}
GLenum key( int key, GLenum mask )
{
switch (key) {
case 27:
exit(0);
break;
case TK_UP:
xrot += 3.0;
#ifndef USE_ZBUFFER
if ( xrot > 180 ) xrot = 180;
#endif
break;
case TK_DOWN:
xrot -= 3.0;
#ifndef USE_ZBUFFER
if ( xrot < 0 ) xrot = 0;
#endif
break;
case TK_LEFT:
yrot += 3.0;
break;
case TK_RIGHT:
yrot -= 3.0;
break;
}
return 0;
}
static void idle( void )
{
spin += 2.0;
display();
}
main( int argc, char *argv[] )
{
tkInitDisplayMode(TK_DOUBLE | TK_RGB
#ifdef USE_ZBUFFER
| TK_DEPTH
#endif
| TK_STENCIL);
tkInitPosition( 0, 0, 400, 300 );
tkInitWindow(argv[0]);
tkReshapeFunc(reshape);
tkDisplayFunc(display);
tkKeyDownFunc(key);
tkIdleFunc(idle);
init();
tkExec();
}