#include "GL/glut.h"
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include "tgaload.h"
#define MAX_NO_TEXTURES 1
#define CUBE_TEXTURE 0
#define TIMER 33
#ifdef WIN32
#pragma warning( disable : 4305)
#endif
using namespace std;
static float xrot;
static float fStart = 3.;
static float fEnd = 0.;
GLUquadric *quad;
GLuint texture_id[MAX_NO_TEXTURES];
void drawScene (GLenum order)
{
GLfloat pos[4] = {-2.8, 5., 1.8, 1.};
glLightfv (GL_LIGHT1, GL_POSITION, pos);
glPushMatrix();
glEnable (GL_CULL_FACE);
glCullFace (GL_BACK);
glFrontFace (order);
glPushMatrix();
glBindTexture ( GL_TEXTURE_2D, texture_id[0] );
glTranslatef(2.,-1.,-1.5);
glBegin ( GL_QUADS );
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glDisable (GL_TEXTURE_2D);
glPopMatrix();
/* Draw the walls */
glColor3f (1., 1., 1.);
glBegin(GL_QUADS);
//left wall
glNormal3f (1., 0., 0.);
glVertex3f (-3., 3., 4.);
glVertex3f (-3., -3., 4.);
glVertex3f (-3., -3., -3.);
glVertex3f (-3., 3., -3.);
//behind wall
glNormal3f (0., 0., 1.);
glVertex3f (-3., 3., -3.);
glVertex3f (-3., -3., -3.);
glVertex3f (3., -3., -3.);
glVertex3f (3., 3., -3.);
//right wall
glNormal3f (-1., 0., 0.);
glVertex3f (3., 3., -3.);
glVertex3f (3., -3., -3.);
glVertex3f (3., -3., 3.);
glVertex3f (3., 3., 3.);
//wall
glNormal3f (0., -1., 0.);
glVertex3f (3., -3., -3.);
glVertex3f (3., -3., 3.);
glVertex3f (-3., -3., 3.);
glVertex3f (-3., -3., -3.);
glEnd();
glDisable (GL_CULL_FACE);
/* Draw the cylinder */
glRotatef (xrot, 1., 0., 0.);
glTranslatef (0., 0., -1.);
glColor3f (.5, .5, 1.);
glPushMatrix ();
glTranslatef (0., 0., 2.);
gluDisk (quad, 0., .25, 18, 1);
glPopMatrix ();
gluCylinder (quad, .25, .25, 2., 18, 8);
glPushMatrix ();
glScalef (1., 1., -1.);
gluDisk (quad, 0., .25, 18, 1);
glPopMatrix ();
glPopMatrix();
}
static void display( void )
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();
GLfloat fogColor[] = {0.5f, 0.5f, 0.5f, 1};
glFogfv(GL_FOG_COLOR, fogColor);
glFogi(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, fStart);
glFogf(GL_FOG_END, fEnd);
gluLookAt (0., 1., 7.,
-1., 0., 0.,
0., 1., 0.);
glRotatef (-xrot*.35, 0., 1., 0.);
/* Draw reflected scene first */
glPushMatrix ();
/* Mirrors lies in YZ plane, so scale by -1.0 in X axis */
glScalef (-1., 1., 1.);
/* Mirror is 2.0 units from origin, so translate by 4.0 */
glTranslatef (4., 0., 0.);
drawScene(GL_CW);
glPopMatrix ();
/* draw mirror */
glClear (GL_DEPTH_BUFFER_BIT);
glPushAttrib (0xffffffff);
glDisable (GL_LIGHTING);
/* Create imperfect reflector effect by blending a black
mirror over the reflected scene with alpha of 0.05 */
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f (0., 0., 0., 0.05);
glBegin (GL_QUADS);
glVertex3f (-2.5, 1., 3.);
glVertex3f (-2.5, -1., 3.);
glVertex3f (-2.5, -1., -2.5);
glVertex3f (-2.5, 1., -2.5);
glEnd ();
glPopAttrib();
/* Draw the real scene */
drawScene(GL_CCW);
glutSwapBuffers();
{
int err = glGetError();
if (err != GL_NO_ERROR)
printf ("Error %x\n", err);
}
}
void reshape(int w, int h)
{
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (50., (float)w/(float)h, 1., 20.);
}
static void cbMainMenu (int value)
{
if (value == 99) {
exit (0);
}
}
static void timer (int value)
{
xrot += 1.f;
if (xrot > 360.f) xrot -= 360.f;
glutPostRedisplay ();
glutTimerFunc (TIMER, timer, 0);
}
void myKeyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'x' : fStart = fStart + 0.1; break;
case 'X' : fStart = fStart - 0.1; break;
case 'z' : fEnd = fEnd + 0.1; break;
case 'Z' : fEnd = fEnd + 0.1; break;
}
glutPostRedisplay();
}
static void init ()
{
int mainMenu;
xrot = 0.;
glDisable (GL_DITHER);
glEnable (GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_FOG);
glClearColor(0.5f, 0.5f, 0.5f, 1);
{
GLfloat white[4] = {1., 1., 1., 1.};
GLfloat black[4] = {0., 0., 0., 0.};
/* Set up light1 */
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT1);
glLightfv (GL_LIGHT1, GL_DIFFUSE, white);
glLightfv (GL_LIGHT1, GL_SPECULAR, white);
/* ambient and diffuse will track glColor */
glEnable (GL_COLOR_MATERIAL);
glColorMaterial (GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv (GL_FRONT, GL_SPECULAR, white);
glMaterialf (GL_FRONT, GL_SHININESS, 20.);
glEnable ( GL_TEXTURE_2D );
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
glGenTextures (1, texture_id);
image_t temp_image;
glBindTexture ( GL_TEXTURE_2D, texture_id[CUBE_TEXTURE] );
tgaLoad ( "swirl.tga", &temp_image, TGA_FREE | TGA_LOW_QUALITY );
glEnable ( GL_CULL_FACE );
}
quad = gluNewQuadric ();
glutDisplayFunc (display);
glutReshapeFunc (reshape);
glutKeyboardFunc(myKeyboard);
glutTimerFunc (TIMER, timer, 0);
mainMenu = glutCreateMenu (cbMainMenu);
glutAddMenuEntry ("Quit", 99);
glutAttachMenu (GLUT_RIGHT_BUTTON);
}
int main(int argc, char** argv)
{
glutInit (&argc,argv);
glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize (300,300);
glutInitWindowPosition (0,0);
glutCreateWindow ("Two pass mirror");
init ();
glutMainLoop ();
return 0;
}