This OpenGL program display a 3D wireframe teapot and some axis and allows the user to use both the mouse and keyboard to move the camera in orbit around the teapot.
teapot.cc:
// Peter Bui
// CSE 40166 Computer Graphics (Fall 2010)
// Example 6: teapot
#include <cmath>
#include <cstdio>
#include <cstdlib>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
using namespace std;
// Constants -------------------------------------------------------------------
#define WHEEL_UP 3
#define WHEEL_DOWN 4
#define CAMERA_DISTANCE_MAX 100.0
// Global variables ------------------------------------------------------------
static size_t WindowWidth = 640;
static size_t WindowHeight = 480;
static GLint MouseX = 0;
static GLint MouseY = 0;
static double CameraLatitude = 5.0;
static double CameraLongitude = 10.0;
static double CameraDistance = 50.0;
static double EyeX = 50.0;
static double EyeY = 50.0;
static double EyeZ = 50.0;
// Update camera ---------------------------------------------------------------
void
update_camera_location()
{
// Based on some magical math:
// http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_spherical_coordinates
// and some help from Dr. John Stewman
double L = CameraDistance * cos(M_PI*CameraLongitude/180.0);
EyeX = L * -sin(M_PI*CameraLatitude/180.0);
EyeY = CameraDistance * sin(M_PI*CameraLongitude/180.0);
EyeZ = L * cos(M_PI*CameraLatitude/180.0);
glutPostRedisplay();
}
// Draw scene ------------------------------------------------------------------
void
draw_scene()
{
glLoadIdentity();
gluLookAt(EyeX, EyeY, EyeZ, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushAttrib(GL_ALL_ATTRIB_BITS);
glLineWidth(4.0);
glBegin(GL_LINES); {
glColor3f(1.0, 0.0, 0.0); // X Axis
glVertex3f(-CAMERA_DISTANCE_MAX, 0.0, 0.0);
glVertex3f( CAMERA_DISTANCE_MAX, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0); // Y Axis
glVertex3f(0.0, -CAMERA_DISTANCE_MAX, 0.0);
glVertex3f(0.0, CAMERA_DISTANCE_MAX, 0.0);
glColor3f(0.0, 0.0, 1.0); // Z Axis
glVertex3f(0.0, 0.0, -CAMERA_DISTANCE_MAX);
glVertex3f(0.0, 0.0, CAMERA_DISTANCE_MAX);
} glEnd();
glPopAttrib();
// Teapot
glColor3f(1.0, 1.0, 1.0);
glScalef(5.0, 5.0, 5.0);
glutWireTeapot(1.0);
}
// Initialize scene ------------------------------------------------------------
void
init_scene()
{
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, WindowWidth, WindowHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLdouble)WindowWidth/(GLdouble)WindowHeight, 1.0, 750.0);
glMatrixMode(GL_MODELVIEW);
update_camera_location();
}
// Display callback ------------------------------------------------------------
void
display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_scene();
glutSwapBuffers();
}
// Reshape callback ------------------------------------------------------------
void
reshape(GLsizei nw, GLsizei nh)
{
WindowWidth = nw;
WindowHeight = nh;
init_scene();
}
// Keyboard callback -----------------------------------------------------------
void
keyboard(unsigned char key, int x, int y)
{
if (key == 'q' || key == 'Q')
exit(EXIT_SUCCESS);
}
// Special callback -----------------------------------------------------------
void
special(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_LEFT: CameraLatitude -= 1.0; break;
case GLUT_KEY_RIGHT: CameraLatitude += 1.0; break;
case GLUT_KEY_UP: CameraLongitude -= 1.0; break;
case GLUT_KEY_DOWN: CameraLongitude += 1.0; break;
}
update_camera_location();
}
// Mouse callback --------------------------------------------------------------
void
mouse(int button, int state, int x, int y)
{
MouseX = x;
MouseY = y;
switch (button) {
case WHEEL_UP:
CameraDistance = (CameraDistance > -CAMERA_DISTANCE_MAX ? CameraDistance - 1.0 : -CAMERA_DISTANCE_MAX);
break;
case WHEEL_DOWN:
CameraDistance = (CameraDistance < CAMERA_DISTANCE_MAX ? CameraDistance + 1.0 : CAMERA_DISTANCE_MAX);
break;
}
update_camera_location();
}
// Motion callback -------------------------------------------------------------
void
motion(int x, int y)
{
CameraLatitude += 180.0*(double)(x - MouseX)/WindowWidth;
CameraLongitude += 180.0*(double)(y - MouseY)/WindowHeight;
update_camera_location();
MouseX = x;
MouseY = y;
}
// Main execution --------------------------------------------------------------
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(WindowWidth, WindowHeight);
glutCreateWindow("teapot");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutMouseFunc(mouse);
glutMotionFunc(motion);
init_scene();
glutMainLoop();
return (EXIT_SUCCESS);
}
// vim: sts=4 sw=4 ts=8 ft=cpp