diff options
Diffstat (limited to 'progs/demos/reflect.c')
-rw-r--r-- | progs/demos/reflect.c | 591 |
1 files changed, 0 insertions, 591 deletions
diff --git a/progs/demos/reflect.c b/progs/demos/reflect.c deleted file mode 100644 index b72af12885..0000000000 --- a/progs/demos/reflect.c +++ /dev/null @@ -1,591 +0,0 @@ -/* - * Demo of a reflective, texture-mapped surface with OpenGL. - * Brian Paul August 14, 1995 This file is in the public domain. - * - * 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. - */ - -/* - * Authors: - * Brian Paul - * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code. - * Mark Kilgard (April 1997) - * Brian Paul (April 2000 - added keyboard d/s options) - * Brian Paul (August 2005 - added multi window feature) - */ - - -#include <assert.h> -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include "GL/glut.h" -#include "showbuffer.h" -#include "readtex.h" - - -#define DEG2RAD (3.14159/180.0) -#define TABLE_TEXTURE "../images/tile.rgb" -#define MAX_OBJECTS 2 -#define INIT_WIDTH 400 -#define INIT_HEIGHT 300 - -#ifdef _WIN32 -#undef CreateWindowA -#endif - -struct window { - int id; /* returned by glutCreateWindow() */ - int width, height; - GLboolean anim; - GLfloat xrot, yrot; - GLfloat spin; - GLenum showBuffer; - GLenum drawBuffer; - GLuint table_list; - GLuint objects_list[MAX_OBJECTS]; - double t0; - struct window *next; -}; - - -static struct window *FirstWindow = NULL; - - -static void -CreateWindow(void); - - -static struct window * -CurrentWindow(void) -{ - int id = glutGetWindow(); - struct window *w; - for (w = FirstWindow; w; w = w->next) { - if (w->id == id) - return w; - } - return NULL; -} - - -static GLboolean -AnyAnimating(void) -{ - struct window *w; - for (w = FirstWindow; w; w = w->next) { - if (w->anim) - return 1; - } - return 0; -} - - -static void -KillWindow(struct window *w) -{ - struct window *win, *prev = NULL; - for (win = FirstWindow; win; win = win->next) { - if (win == w) { - if (prev) { - prev->next = win->next; - } - else { - FirstWindow = win->next; - } - glutDestroyWindow(win->id); - win->next = NULL; - free(win); - return; - } - prev = win; - } -} - - -static void -KillAllWindows(void) -{ - while (FirstWindow) - KillWindow(FirstWindow); -} - - -static GLuint -MakeTable(void) -{ - static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 }; - static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 }; - GLuint table_list; - - 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 ); - - /* 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(); - return table_list; -} - - -static void -MakeObjects(GLuint *objects_list) -{ - 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, 1 ); - 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, 1 ); - glEndList(); - - gluDeleteQuadric(q); -} - - -static void -InitWindow(struct window *w) -{ - GLint imgWidth, imgHeight; - GLenum imgFormat; - GLubyte *image = NULL; - - w->table_list = MakeTable(); - MakeObjects(w->objects_list); - - image = LoadRGBImage( TABLE_TEXTURE, &imgWidth, &imgHeight, &imgFormat ); - if (!image) { - printf("Couldn't read %s\n", TABLE_TEXTURE); - exit(0); - } - - gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgWidth, imgHeight, - imgFormat, GL_UNSIGNED_BYTE, image); - free(image); - - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - - glShadeModel( GL_FLAT ); - - glEnable( GL_LIGHT0 ); - glEnable( GL_LIGHTING ); - - glClearColor( 0.5, 0.5, 0.9, 0.0 ); - - glEnable( GL_NORMALIZE ); -} - - -static void -Reshape(int width, int height) -{ - struct window *w = CurrentWindow(); - GLfloat yAspect = 2.5; - GLfloat xAspect = yAspect * (float) width / (float) height; - w->width = width; - w->height = height; - glViewport(0, 0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum( -xAspect, xAspect, -yAspect, yAspect, 10.0, 30.0 ); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); -} - - -static void -DrawObjects(struct window *w, GLfloat eyex, GLfloat eyey, GLfloat eyez) -{ - (void) eyex; - (void) eyey; - (void) eyez; -#ifndef USE_ZBUFFER - if (eyex<0.5) { -#endif - glPushMatrix(); - glTranslatef( 1.0, 1.5, 0.0 ); - glRotatef( w->spin, 1.0, 0.5, 0.0 ); - glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 ); - glCallList( w->objects_list[0] ); - glPopMatrix(); - - glPushMatrix(); - glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*w->spin) ), 0.0 ); - glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 ); - glRotatef( w->spin, 1.0, 0.5, 0.0 ); - glScalef( 0.5, 0.5, 0.5 ); - glCallList( w->objects_list[1] ); - glPopMatrix(); -#ifndef USE_ZBUFFER - } - else { - glPushMatrix(); - glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*w->spin) ), 0.0 ); - glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 ); - glRotatef( w->spin, 1.0, 0.5, 0.0 ); - glScalef( 0.5, 0.5, 0.5 ); - glCallList( w->objects_list[1] ); - glPopMatrix(); - - glPushMatrix(); - glTranslatef( 1.0, 1.5, 0.0 ); - glRotatef( w->spin, 1.0, 0.5, 0.0 ); - glRotatef( 0.5*w->spin, 0.0, 0.5, 1.0 ); - glCallList( w->objects_list[0] ); - glPopMatrix(); - } -#endif -} - - -static void -DrawTable(struct window *w) -{ - glCallList(w->table_list); -} - - -static void -DrawWindow(void) -{ - struct window *w = CurrentWindow(); - static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 }; - GLfloat dist = 20.0; - GLfloat eyex, eyey, eyez; - - if (w->drawBuffer == GL_NONE) { - glDrawBuffer(GL_BACK); - glReadBuffer(GL_BACK); - } - else { - glDrawBuffer(w->drawBuffer); - glReadBuffer(w->drawBuffer); - } - - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - - if (w->drawBuffer == GL_NONE) { - glDrawBuffer(GL_NONE); - } - - eyex = dist * cos(w->yrot * DEG2RAD) * cos(w->xrot * DEG2RAD); - eyez = dist * sin(w->yrot * DEG2RAD) * cos(w->xrot * DEG2RAD); - eyey = dist * sin(w->xrot * DEG2RAD); - - /* view from top */ - glPushMatrix(); - gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ); - - glLightfv( GL_LIGHT0, GL_POSITION, light_pos ); - - /* draw table into stencil planes */ - glDisable( GL_DEPTH_TEST ); - glEnable( GL_STENCIL_TEST ); - glStencilFunc( GL_ALWAYS, 1, 0xffffffff ); - glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE ); - glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); - DrawTable(w); - glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); - - glEnable( GL_DEPTH_TEST ); - - /* 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 ); - - /* Reposition light in reflected space. */ - glLightfv(GL_LIGHT0, GL_POSITION, light_pos); - - DrawObjects(w, eyex, eyey, eyez); - glPopMatrix(); - - /* Restore light's original unreflected position. */ - glLightfv(GL_LIGHT0, GL_POSITION, light_pos); - } - - glDisable( GL_STENCIL_TEST ); - - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - - glEnable( GL_TEXTURE_2D ); - DrawTable(w); - glDisable( GL_TEXTURE_2D ); - glDisable( GL_BLEND ); - - /* view from top */ - glPushMatrix(); - - DrawObjects(w, eyex, eyey, eyez); - - glPopMatrix(); - - glPopMatrix(); - - if (w->showBuffer == GL_DEPTH) { - ShowDepthBuffer(w->width, w->height, 1.0, 0.0); - } - else if (w->showBuffer == GL_STENCIL) { - ShowStencilBuffer(w->width, w->height, 255.0, 0.0); - } - else if (w->showBuffer == GL_ALPHA) { - ShowAlphaBuffer(w->width, w->height); - } - - if (w->drawBuffer == GL_FRONT) - glFinish(); - else - glutSwapBuffers(); - - /* calc/show frame rate */ - { - static GLint t0 = 0; - static GLint frames = 0; - GLint t = glutGet(GLUT_ELAPSED_TIME); - frames++; - if (t - t0 >= 5000) { - GLfloat seconds = (t - t0) / 1000.0; - GLfloat fps = frames / seconds; - printf("%d frames in %g seconds = %g FPS\n", frames, seconds, fps); - fflush(stdout); - t0 = t; - frames = 0; - } - } -} - - -static void -Idle(void) -{ - double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; - struct window *w; - for (w = FirstWindow; w; w = w->next) { - if (w->anim) { - double dt; - if (w->t0 < 0.0) - w->t0 = t; - dt = t - w->t0; - w->t0 = t; - w->spin += 60.0 * dt; - w->yrot += 90.0 * dt; - assert(w->id); - glutSetWindow(w->id); - glutPostRedisplay(); - } - } -} - - -static void -UpdateIdleFunc(void) -{ - if (AnyAnimating()) - glutIdleFunc(Idle); - else - glutIdleFunc(NULL); -} - -static void -Key(unsigned char key, int x, int y) -{ - struct window *w = CurrentWindow(); - (void) x; - (void) y; - - switch (key) { - case 'd': - w->showBuffer = GL_DEPTH; - glutPostRedisplay(); - break; - case 's': - w->showBuffer = GL_STENCIL; - glutPostRedisplay(); - break; - case 'a': - w->showBuffer = GL_ALPHA; - glutPostRedisplay(); - break; - case 'c': - w->showBuffer = GL_NONE; - glutPostRedisplay(); - break; - case 'f': - if (w->drawBuffer == GL_FRONT) - w->drawBuffer = GL_BACK; - else - w->drawBuffer = GL_FRONT; - glutPostRedisplay(); - break; - case '0': - w->drawBuffer = GL_NONE; - glutPostRedisplay(); - break; - case ' ': - w->anim = !w->anim; - w->t0 = -1; - UpdateIdleFunc(); - glutPostRedisplay(); - break; - case 'n': - CreateWindow(); - UpdateIdleFunc(); - break; - case 'k': - KillWindow(w); - if (FirstWindow == NULL) - exit(0); - break; - case 27: - KillAllWindows(); - exit(0); - break; - default: - ; - } -} - - -static void -SpecialKey(int key, int x, int y) -{ - struct window *w = CurrentWindow(); - (void) x; - (void) y; - switch (key) { - case GLUT_KEY_UP: - w->xrot += 3.0; - if (w->xrot > 85) - w->xrot = 85; - break; - case GLUT_KEY_DOWN: - w->xrot -= 3.0; - if (w->xrot < 5) - w->xrot = 5; - break; - case GLUT_KEY_LEFT: - w->yrot += 3.0; - break; - case GLUT_KEY_RIGHT: - w->yrot -= 3.0; - break; - } - glutPostRedisplay(); -} - - -static void -CreateWindow(void) -{ - char title[1000]; - struct window *w = (struct window *) calloc(1, sizeof(struct window)); - - glutInitWindowSize(INIT_WIDTH, INIT_HEIGHT); - w->id = glutCreateWindow("foo"); - sprintf(title, "reflect window %d", w->id); - glutSetWindowTitle(title); - assert(w->id); - w->width = INIT_WIDTH; - w->height = INIT_HEIGHT; - w->anim = GL_TRUE; - w->xrot = 30.0; - w->yrot = 50.0; - w->spin = 0.0; - w->showBuffer = GL_NONE; - w->drawBuffer = GL_BACK; - - InitWindow(w); - - glutReshapeFunc(Reshape); - glutDisplayFunc(DrawWindow); - glutKeyboardFunc(Key); - glutSpecialFunc(SpecialKey); - - /* insert at head of list */ - w->next = FirstWindow; - FirstWindow = w; -} - - -static void -Usage(void) -{ - printf("Keys:\n"); - printf(" a - show alpha buffer\n"); - printf(" d - show depth buffer\n"); - printf(" s - show stencil buffer\n"); - printf(" c - show color buffer\n"); - printf(" f - toggle rendering to front/back color buffer\n"); - printf(" n - create new window\n"); - printf(" k - kill window\n"); - printf(" SPACE - toggle animation\n"); - printf(" ARROWS - rotate scene\n"); -} - - -int -main(int argc, char *argv[]) -{ - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | - GLUT_STENCIL | GLUT_ALPHA); - CreateWindow(); - glutIdleFunc(Idle); - Usage(); - glutMainLoop(); - return 0; -} |