Code:
/****************************************************************************
chapter1.cpp
A simple OpenGL/GLUT demonstration showing a texture mapped, lit, spinning
cube reflecting in a surface.
This demo should give you a general idea of what GLUT is. For more
information, visit the official GLUT page at:
http://reality.sgi.com/opengl/glut3/glut3.html
Author : Dave Astle
Date : 8/23/2000
Written for OpenGL Game Programming
*****************************************************************************/
/********************************* Includes *********************************/
#include <gl\glaux.h>
#include <gl\glut.h>
#include <iostream.h>
#include "HiResTimer.h"
/*************************** Macros and constants ***************************/
enum rendermode_t {
RENDER_REFLECTED,
RENDER_SHADOW,
RENDER_NORMAL
};
const GLfloat DEGREES_PER_SECOND = 60.0f;
/******************************** Prototypes ********************************/
void Initialize();
void MouseHandler(int button, int state, int x, int y);
void KeyboardHandler(unsigned char key, int x, int y);
void MainMenuHandler(int option);
void Animate();
void Reshape(int width, int height);
void Display();
void LoadTexture(char *filename, GLuint &texture);
void DrawScene(rendermode_t mode);
void DrawCube();
void DrawSurface();
/********************************* Globals **********************************/
// index for the texture we'll load for the cube
GLuint g_cubeTexture;
// how much to rotate the cube around an axis
GLfloat g_rotationAngle = 0.0;
CHiResTimer g_timer;
/****************************************************************************
main()
Setup GLUT and OpenGL, drop into the event loop
*****************************************************************************/
int main(int argc, char **argv)
{
// Setup the basic GLUT stuff
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL);
// Create the window
glutInitWindowSize(512, 512);
glutInitWindowPosition(400, 350);
glutCreateWindow("Chapter 1");
Initialize();
// Register the event callback functions
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutMouseFunc(MouseHandler);
glutKeyboardFunc(KeyboardHandler);
glutIdleFunc(Animate);
// At this point, control is relinquished to the GLUT event handler.
// Control is returned as events occur, via the callback functions.
glutMainLoop();
return 0;
} // end main()
/****************************************************************************
Initialize()
One time setup, including creating menus, creating a light, setting the
shading mode and clear color, and loading textures.
*****************************************************************************/
void Initialize()
{
// set up the only meny
int mainMenu;
mainMenu = glutCreateMenu(MainMenuHandler);
glutSetMenu(mainMenu);
glutAddMenuEntry("Exit", 0);
glutAttachMenu(GLUT_RIGHT_BUTTON);
g_timer.Init();
// set the background color
glClearColor(0.0, 0.0, 0.0, 0.0);
// set the shading model
glShadeModel(GL_SMOOTH);
// set up a single white light
GLfloat lightColor[] = { 1.0f, 1.0f, 1.0f, 1.0 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightColor);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
// load the texture for the cube
LoadTexture("opengl.bmp", g_cubeTexture);
// make the modelview matrix active, and initialize it
glMatrixMode(GL_MODELVIEW);
} // end Initialize()
/****************************************************************************
MouseHandler()
Handle mouse events. For this simple demo, just exit on a left click.
*****************************************************************************/
void MouseHandler(int button, int state, int x, int y)
{
switch (button)
{
case GLUT_LEFT_BUTTON:
{
exit(0);
} break;
default:
break;
}
// force a screen redraw
glutPostRedisplay();
} // end MouseHandler()
/****************************************************************************
KeyboardHandler()
Keyboard handler. Again, we'll just exit when q is pressed.
*****************************************************************************/
void KeyboardHandler(unsigned char key, int x, int y)
{
switch (key)
{
case 'q': // exit
{
exit(0);
} break;
default:
{
} break;
}
glutPostRedisplay();
} // end KeyboardHandler()
/****************************************************************************
MainMenuHandler()
Main menu callback.
*****************************************************************************/
void MainMenuHandler(int option)
{
switch(option)
{
case 0:
{
exit(0);
} break;
default:
break;
}
glutPostRedisplay();
} // end MainMenuHandler()
/****************************************************************************
Animate()
Rotate the cube by 4 degrees and force a redisplay.
*****************************************************************************/
void Animate()
{
glutPostRedisplay();
} // end Animate()
/****************************************************************************
Reshape()
Reset the viewport for window changes
*****************************************************************************/
void Reshape(int width, int height)
{
if (height == 0)
return;
glViewport(0, 0, (GLsizei) width, (GLsizei) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0, width/height, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
} // end Reshape
/****************************************************************************
Display()
Clear and redraw the scene.
*****************************************************************************/
void Display()
{
g_rotationAngle += (DEGREES_PER_SECOND * g_timer.GetElapsedSeconds());
static int s_frames = 0;
if (++s_frames > 100)
{
cout << g_timer.GetFPS(100) << endl;
s_frames = 0;
}
// set up the view orientation looking at the origin from slightly above
// and to the left
glLoadIdentity();
gluLookAt(0.0, 1.0, 6.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
// clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glRotatef(-g_rotationAngle/8.0, 0.0, 1.0, 0.0);
// draw the reflected cube first, with fog enable for a more realistic
// effect
glEnable(GL_FOG);
glFogf(GL_FOG_END, 5.0);
glFogf(GL_FOG_DENSITY, 0.4);
DrawScene(RENDER_REFLECTED);
glDisable(GL_FOG);
// now draw the scene with the shadow
DrawScene(RENDER_SHADOW);
// now draw the real cube
DrawScene(RENDER_NORMAL);
// draw everything and swap the display buffer
glFlush();
glutSwapBuffers();
} // end Display()
/****************************************************************************
LoadTexture()
Loads the texture from the specified file and stores it in iTexture. Note
that we're using the GLAUX library here, which is generally discouraged,
but in this case spares us having to write a bitmap loading routine.
*****************************************************************************/
void LoadTexture(char *filename, GLuint &texture)
{
AUX_RGBImageRec *image[1];
memset(image, 0, sizeof(void *));
// if the file can be read, load the texture
if (image[0] = auxDIBImageLoad(filename))
{
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
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_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, image[0]->sizeX, image[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image[0]->data);
}
/**** Edited out some of the program to not make this page too bulkly******/
/****************************************************************************
DrawSurface()
Draws a simple plane to provide a reflection surface.
*****************************************************************************/
void DrawSurface()
{
// make sure the light is positioned correctly
GLfloat lightPos[4] = {3.0, 3.0, 3.0, 1.0};
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
// set up the surface's color
GLfloat surfaceColor[] = { 0.2f, 0.4f, 0.2f, 0.5 };
glMaterialfv(GL_FRONT, GL_SPECULAR, surfaceColor);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, surfaceColor);
glMaterialf(GL_FRONT, GL_SHININESS, 200.0);
// set up blending so we can see the reflected cube through the
// surface, and thus create the illusion of reflection
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_QUADS);
glNormal3f(0.0, 1.0, 0.0);
// to have lighting effects show up at all, we need to draw the
// surface as a lot of quads, not just one
GLfloat x = -5.0, z = -5.0;
for (GLint i = 0; i < 10; i++, x += 1)
{
for (GLint j = 0; j < 10; j++, z += 1)
{
// draw the plane slightly offset so the shadow shows up
glVertex3f(x, -0.1, z);
glVertex3f(x + 1.0, -0.1, z);
glVertex3f(x + 1.0, -0.1, z + 1.0);
glVertex3f(x, -0.1, z + 1.0);
}
z = -5.0;
}
glEnd();
glDisable(GL_BLEND);
} // end DrawSurface()
Here is the Compiler log