This OpenGL program displays a 3d geometric object: glutSolidSphere, glutSolidCube, glutSolidCone, glutSolidTorus, gluCylinder, gluDisk, gluPartialDisk. To scale the object use the up and down arrow keys. To rotate the object about the Y axis, use the left and right arrow keys. To switch among the objects, use F1 though F7. The camera uses the same arcball method as that in example 06.
geodemo.cc:
// Peter Bui
// CSE 40166 Computer Graphics (Fall 2010)
// Example 14: geometric object demo
#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_MIN 1.0
#define CAMERA_DISTANCE_MAX 100.0
enum {
GEO_SPHERE,
GEO_CUBE,
GEO_CONE,
GEO_TORUS,
/*
GEO_DODECAHEDRON,
GEO_OCTAHEDRON,
GEO_TETRAHEDRON,
GEO_ICOSAHEDRON,
GEO_TEAPOT,
*/
GEO_CYLINDER,
GEO_DISK,
GEO_PARTIAL_DISK,
GEO_MAX
};
// Global variables ------------------------------------------------------------
static size_t WindowWidth = 640;
static size_t WindowHeight = 480;
static GLint MouseX = 0;
static GLint MouseY = 0;
static double CameraLatitude = 45.0;
static double CameraLongitude = 25.0;
static double CameraDistance = 50.0;
static double EyeX = -100.0;
static double EyeY = 50.0;
static double EyeZ = 100.0;
static int GeoMode = GEO_SPHERE;
static double GeoScale = 1.0;
static double GeoOrientation = 0.0;
static bool GeoWired = false;
static GLUquadric *GeoQuadric = NULL;
// Update camera ---------------------------------------------------------------
void
update_camera_location()
{
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();
}
// 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);
GLfloat diffuse0[] = { 0.8, 0.8, 0.8, 1.0 };
GLfloat ambient0[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat specular0[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat position0[] = { 100.0, 100.0, 100.0, 1.0 };
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular0);
glLightfv(GL_LIGHT0, GL_POSITION, position0);
glEnable(GL_COLOR_MATERIAL) ;
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_NORMALIZE);
glEnable(GL_SMOOTH);
if (!GeoQuadric) {
GeoQuadric = gluNewQuadric();
gluQuadricOrientation(GeoQuadric, GLU_OUTSIDE);
gluQuadricNormals(GeoQuadric, GLU_SMOOTH);
}
update_camera_location();
}
// Draw grid -------------------------------------------------------------------
void
draw_grid()
{
glPushMatrix(); glPushAttrib(GL_LIGHTING_BIT); {
glDisable(GL_LIGHTING);
glColor3f(1.0, 1.0, 1.0);
glScalef(5.0, 5.0, 5.0);
for(int k = 0; k < 2; k++) {
for(int i = -5; i < 6; i++) {
glBegin(GL_LINE_STRIP); {
for(int j = -5; j < 6; j++)
glVertex3f(k == 0 ? i : j, 0, k == 0 ? j : i);
} glEnd();
}
}
} glPopAttrib(); glPopMatrix();
}
// Display callback ------------------------------------------------------------
void
display()
{
//GLfloat position0[] = { EyeX, EyeY, EyeZ, 1.0 };
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(EyeX, EyeY, EyeZ, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
draw_grid();
glPushMatrix();
glRotatef(GeoOrientation, 0.0, 1.0, 0.0);
glScalef(GeoScale, GeoScale, GeoScale);
glColor3f(1.0, 0.0, 0.0);
gluQuadricDrawStyle(GeoQuadric, (GeoWired ? GLU_LINE : GLU_FILL));
switch (GeoMode) {
case GEO_SPHERE:
if (GeoWired)
glutWireSphere(1.0, 24, 24);
else
glutSolidSphere(1.0, 24, 24);
break;
case GEO_CUBE:
if (GeoWired)
glutWireCube(2.0);
else
glutSolidCube(2.0);
break;
case GEO_CONE:
if (GeoWired)
glutWireCone(1.0, 1.0, 24, 24);
else
glutSolidCone(1.0, 1.0, 24, 24);
break;
case GEO_TORUS:
if (GeoWired)
glutWireTorus(0.5, 1.0, 24, 24);
else
glutSolidTorus(0.5, 1.0, 24, 24);
break;
case GEO_CYLINDER:
gluCylinder(GeoQuadric, 1.0, 1.0, 2.0, 24, 24);
break;
case GEO_DISK:
gluDisk(GeoQuadric, 0.5, 1.0, 24, 24);
break;
case GEO_PARTIAL_DISK:
gluPartialDisk(GeoQuadric, 0.5, 1.0, 24, 24, 0.0, 180.0);
break;
}
glPopMatrix();
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)
{
switch (key) {
case 'q':
case 'Q':
exit(EXIT_SUCCESS);
break;
case 'w':
GeoWired = !GeoWired;
break;
}
glutPostRedisplay();
}
// Special callback -----------------------------------------------------------
void
special(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_LEFT: GeoOrientation -= 1.0; break;
case GLUT_KEY_RIGHT: GeoOrientation += 1.0; break;
case GLUT_KEY_UP: GeoScale += 1.0; break;
case GLUT_KEY_DOWN: GeoScale -= 1.0; break;
case GLUT_KEY_F1: GeoMode = GEO_SPHERE; break;
case GLUT_KEY_F2: GeoMode = GEO_CUBE; break;
case GLUT_KEY_F3: GeoMode = GEO_CONE; break;
case GLUT_KEY_F4: GeoMode = GEO_TORUS; break;
case GLUT_KEY_F5: GeoMode = GEO_CYLINDER; break;
case GLUT_KEY_F6: GeoMode = GEO_DISK; break;
case GLUT_KEY_F7: GeoMode = GEO_PARTIAL_DISK; break;
}
glutPostRedisplay();
}
// 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_MIN ? CameraDistance - 1.0 : CAMERA_DISTANCE_MIN);
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("geodemo");
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