/* $Id: reflect.c,v 3.0 1998/02/14 18:42:29 brianp Exp $ */
/*
* 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.
*/
/*
* Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
*
* August 1996 - A few optimizations by Brian
*/
/*
* April, 1997 - Added Mark Kilgard's changes.
*/
/*
* $Log: reflect.c,v $
* Revision 3.0 1998/02/14 18:42:29 brianp
* initial rev
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "ReadTex.h"
#include "ModuleManipulateur.h"
#include "ModuleMenus.h"
#include "ModuleReshape.h"
#define USE_ZBUFFER
#define USE_TEXTURE
#define DEG2RAD (3.14159/180.0)
#define TABLE_TEXTURE "reflect.rgb"
#define MAX_OBJECTS 2
static int ImgWidth,ImgHeight;
static GLenum ImgFormat;
static GLubyte *Image = NULL;
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.0F,1.0F,1.0F,0.6F };
static GLfloat gray[] = { 0.4F,0.4F,0.4F,1.0F };
table_list = glGenLists(1);
glNewList(table_list,GL_COMPILE);
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,table_mat);
glMaterialfv(GL_FRONT,GL_DIFFUSE,table_mat);
glMaterialfv(GL_FRONT,GL_AMBIENT,gray);
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.0F,1.0F,1.0F,1.0F };
static GLfloat green[] = { 0.2F,1.0F,0.2F,1.0F };
static GLfloat black[] = { 0.0F,0.0F,0.0F,0.0F };
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 GLfloat light_pos[] = { 0.0,20.0,0.0,1.0 };
static void init(void) {
make_table();
make_objects();
#ifdef USE_TEXTURE
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);
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);
#endif
xrot = 30.0;
yrot = 50.0;
spin = 0.0;
#ifndef USE_ZBUFFER
glEnable(GL_CULL_FACE);
#endif
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glClearColor(0.5,0.5,0.5,1.0);
glEnable(GL_NORMALIZE);
}
static void draw_objects(GLfloat eyex,GLfloat eyey,GLfloat eyez) {
#ifndef USE_ZBUFFER
if(eyex<0.5) {
#endif
glPushMatrix();
glTranslatef(1.0,1.5,0.0);
glRotatef(spin,1.0,0.5,0.0);
glRotatef(0.5F*spin,0.0,0.5,1.0);
glCallList(objects_list[0]);
glPopMatrix();
glPushMatrix();
glTranslatef(-1.0,(float) (0.85+3.0*fabs(cos(0.01*spin))),0.0);
glRotatef(0.5F*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_ZBUFFER
}
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 =(float) (dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD));
eyez =(float) (dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD));
eyey =(float) (dist * sin(xrot*DEG2RAD));
glPushMatrix();
gluLookAt(eyex,eyey,eyez,0.0,0.0,0.0, 0.0,1.0,0.0);
manipulateurSouris();
manipulateurClavier();
glLightfv(GL_LIGHT0,GL_POSITION,light_pos);
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
if(eyey>0.0) {
glPushMatrix();
glStencilFunc(GL_EQUAL,1,0xffffffff);
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
glScalef(1.0,-1.0,1.0);
glLightfv(GL_LIGHT0,GL_POSITION,light_pos);
draw_objects(eyex,eyey,eyez);
glPopMatrix();
glLightfv(GL_LIGHT0,GL_POSITION,light_pos); }
glDisable(GL_STENCIL_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
#ifdef USE_TEXTURE
glEnable(GL_TEXTURE_2D);
#endif
draw_table();
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glPushMatrix();
draw_objects(eyex,eyey,eyez);
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
}
#if 0
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);
glPushMatrix();
gluLookAt(eyex,eyey,eyez,0.0,0.0,0.0, 0.0,1.0,0.0);
manipulateurSouris();
manipulateurClavier();
draw_table();
glPopMatrix();
auxSwapBuffers(); }
#endif
static void idle(void) {
spin += 2.0;
yrot += 3.0;
glutPostRedisplay() ;
}
int main(int argc,char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE|GLUT_STENCIL);
glutInitWindowSize(400,300);
glutInitWindowPosition(50,50);
glutCreateWindow("Réflexions par mappage de texture");
init();
creationMenuBasique();
setParametresFrustumBasique(-1.0F,1.0F,-1.0,1.0F,4.0F,300.0F,0.0F,0.0F,0.0F);
setManipulateurDistance(20.0F);
glutReshapeFunc(reshapeFrustumBasique);
glutIdleFunc(idle);
glutKeyboardFunc(keyBasique);
glutSpecialFunc(specialBasique);
glutMotionFunc(motionBasique);
glutMouseFunc(sourisBasique);
glutDisplayFunc(display);
glutMainLoop();
return(0);
}