44#define GL_GLEXT_PROTOTYPES
53#include <Arcball/Arcball.hpp>
59#define M_PI_ 3.14159265358979323846
61#define checkImageWidth 128
63#define checkImageHeight 128
67#define farPlane (zobs+10*d)
71#define posAng(x) ((x) < 0.0 ? ((x)+TWOPI) : (x))
75#define toRad(x) ((x)*M_PI/180.0)
77#define toDeg(x) ((x)*180.0/M_PI)
79#define clamp(x) (fmin(fmax((x),0),1))
81#define LEN(x,y,z) (sqrt((x)*(x)+(y)*(y)+(z)*(z)))
83#define theAxes (2*nObjects)
85#define nObjects (sizeof(objNames)/sizeof(char*))
87#define scale (0.05*diag)
152const char *
objNames[] = {
"Torus",
"Cylinder",
"Cone",
"Ellipsoid",
"Paraboloid",
"Hyperbolic Paraboloid",
"Hyperboloid"};
183 (*bbox)[0].x = fmin(x,(*bbox)[0].x);
184 (*bbox)[1].x = fmax(x,(*bbox)[1].x);
185 (*bbox)[0].y = fmin(y,(*bbox)[0].y);
186 (*bbox)[1].y = fmax(y,(*bbox)[1].y);
187 (*bbox)[0].z = fmin(z,(*bbox)[0].z);
188 (*bbox)[1].z = fmax(z,(*bbox)[1].z);
202 *dx = (*bbox)[1].x - (*bbox)[0].x;
203 *dy = (*bbox)[1].y - (*bbox)[0].y;
204 *dz = (*bbox)[1].z - (*bbox)[0].z;
206 return LEN(*dx,*dy,*dz);
242void cone(
double h,
double r,
int vs,
int rs,
int normals) {
244 double z, th, x, y, ln, nx, ny, nz, u;
253 for (i = 0; i < vs; i++) {
254 glBegin(normals?GL_LINES:GL_QUAD_STRIP);
255 for (j = 0; j <= rs; j++) {
256 for (k = 1; k >= 0; k--) {
264 nx = x * hr; ny = y * hr; nz = u > 0 ? u : 1;
266 nx /= ln; ny /= ln; nz /= ln;
269 glNormal3d(nx, ny, nz);
270 glTexCoord2d(th,z/h);
313void cylinder(
double h,
double r,
int vs,
int rs,
int normals) {
315 double z0, z1, th, x, y, ln, nx, ny;
324 for (i = 0; i < vs; i++) {
327 glBegin(normals?GL_LINES:GL_QUAD_STRIP);
328 for (j = 0; j <= rs; j++) {
334 nx = x/ln; ny = y/ln;
337 glNormal3d(nx, ny, 0);
338 glTexCoord2d(th,z1/h);
339 glVertex3d(x, y, z1);
344 glNormal3d(nx, ny, 0);
345 glTexCoord2d(th,z0/h);
346 glVertex3d(x, y, z0);
387void paraboloid(
double h,
double r,
int vs,
int rs,
int normals) {
389 double z, th, x, y, ln, nx, ny, nz, u;
390 double hr2 = h/(r*r);
398 for (i = 0; i < vs; i++) {
399 glBegin(normals?GL_LINES:GL_QUAD_STRIP);
400 for (j = 0; j <= rs; j++) {
401 for (k = 1; k >= 0; k--) {
409 nx = 2 * x * hr2; ny = 2 * y * hr2; nz = 1;
411 nx /= ln; ny /= ln; nz /= ln;
414 glNormal3d(nx, ny, nz);
415 glTexCoord2d(th,z/h);
463void hyperboloid(
double h,
double a,
double r,
int vs,
int rs,
int normals) {
465 double z, th, x, y, ln, nx, ny, nz, u;
466 double c = sqrt( h*h / (4 * (r*r/(a*a) - 1)) );
468 printf (
"Hyperboloid: r < a -> invalid!\n" );
478 for (i = -vs; i < vs; i++) {
479 glBegin(normals?GL_LINES:GL_QUAD_STRIP);
480 for (j = 0; j <= rs; j++) {
481 for (k = 1; k >= 0; k--) {
490 nx = x * c; ny = y * c; nz = -z * a * a / c;
492 nx /= ln; ny /= ln; nz /= ln;
495 glNormal3d(nx, ny, nz);
496 glTexCoord2d(th,(z+h)/(2*h));
541 double u, v, z, x, y, ln, nx, ny, nz;
549 for (i = -hs; i < hs; i++) {
550 glBegin(normals?GL_LINES:GL_QUAD_STRIP);
551 for (j = -ws; j <= ws; j++) {
552 for (k = 1; k >= 0; k--) {
560 nx = y; ny = x; nz = -1;
562 nx /= ln; ny /= ln; nz /= ln;
564 glNormal3d(nx, ny, nz);
565 glTexCoord2d((u+w)/(2*w),(v+h)/(2*h));
622void torus(
double r1,
double r2,
int numc,
int numt,
int normals) {
624 double s, t, x, y, z;
625 double u, v, cu, cv, su, sv, nx, ny, nz;
634 for (i = 0; i < numc; i++) {
635 glBegin(normals?GL_LINES:GL_QUAD_STRIP);
636 for (j = 0; j <= numt; j++) {
637 for (k = 1; k >= 0; k--) {
639 s = (i + k) % numc + 0.5;
654 x = (r1 + r2 * cv) * cu;
655 y = (r1 + r2 * cv) * su;
664 nx /= ln; ny /= ln; nz /= ln;
671 glNormal3d(nx, ny, nz);
722void sphere(
double r1,
double r2,
double r3,
int numc,
int numt,
int normals) {
725 double u, v, cu, cv, su, sv, nx, ny, nz;
734 for (i = 0; i < numc; i++) {
735 glBegin(normals?GL_LINES:GL_QUAD_STRIP);
736 for (j = 0; j <= numt; j++) {
737 for (k = 1; k >= 0; k--) {
754 nx = r2*r3*r2*r3 * x;
755 ny = r1*r3*r1*r3 * y;
756 nz = r1*r2*r1*r2 * z;
759 nx /= ln; ny /= ln; nz /= ln;
766 glNormal3d(nx, ny, nz);
789 glColor3d(1.0,0.0,0.0);
790 glVertex3d(0.0,0.0,0.0);
791 glVertex3d(d,0.0,0.0);
792 glColor3d(0.0,1.0,0.0);
793 glVertex3d(0.0,0.0,0.0);
794 glVertex3d(0.0,d,0.0);
795 glColor3d(0.0,0.0,1.0);
796 glVertex3d(0.0,0.0,0.0);
797 glVertex3d(0.0,0.0,d);
807 glPushAttrib(GL_ENABLE_BIT);
808 glLineStipple(3, 0xAAAA);
809 glEnable(GL_LINE_STIPPLE);
811 glBegin(GL_LINE_LOOP);
812 glColor3d(1.0,1.0,1.0);
813 glVertex3d(BBOX[0].x, BBOX[0].y, BBOX[0].z);
814 glVertex3d(BBOX[1].x, BBOX[0].y, BBOX[0].z);
815 glVertex3d(BBOX[1].x, BBOX[1].y, BBOX[0].z);
816 glVertex3d(BBOX[0].x, BBOX[1].y, BBOX[0].z);
819 glBegin(GL_LINE_LOOP);
820 glVertex3d(BBOX[0].x, BBOX[0].y, BBOX[1].z);
821 glVertex3d(BBOX[1].x, BBOX[0].y, BBOX[1].z);
822 glVertex3d(BBOX[1].x, BBOX[1].y, BBOX[1].z);
823 glVertex3d(BBOX[0].x, BBOX[1].y, BBOX[1].z);
826 glBegin(GL_LINE_LOOP);
827 glVertex3d(BBOX[0].x, BBOX[0].y, BBOX[0].z);
828 glVertex3d(BBOX[1].x, BBOX[0].y, BBOX[0].z);
829 glVertex3d(BBOX[1].x, BBOX[0].y, BBOX[1].z);
830 glVertex3d(BBOX[0].x, BBOX[0].y, BBOX[1].z);
833 glBegin(GL_LINE_LOOP);
834 glVertex3d(BBOX[0].x, BBOX[1].y, BBOX[0].z);
835 glVertex3d(BBOX[1].x, BBOX[1].y, BBOX[0].z);
836 glVertex3d(BBOX[1].x, BBOX[1].y, BBOX[1].z);
837 glVertex3d(BBOX[0].x, BBOX[1].y, BBOX[1].z);
866 c = ( (i&0x8)==0 ) ^ ( (j&0x8)==0 );
890 ilGenImages(1, &imageName);
891 ilBindImage(imageName);
894 if ( !ilLoadImage(filename) )
899 if ( !ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE) )
917 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
922 glBindTexture(GL_TEXTURE_2D,
texName);
925 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
927 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
928 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
931 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
934 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
941 glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT),
942 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());
946 glGenerateMipmap(GL_TEXTURE_2D);
976 glEnable(GL_DEPTH_TEST);
980 glShadeModel (GL_SMOOTH);
982 glClearColor(1.0, 250/255.0, 205/255.0, 0.0);
984 glEnable(GL_RESCALE_NORMAL);
986 glDisable(GL_DEPTH_CLAMP);
989 GLfloat global_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
990 GLfloat ambient[] = { 0.05, 0.05, 0.05 };
992 GLfloat diffuseLight[] = { 0.8, 0.8, 0.8, 1.0 };
994 GLfloat specular[] = {1.0, 1.0, 1.0 , 1.0};
998 GLfloat mAmbientB[] = {0.24725,0.1995,0.0745,1.0};
1000 GLfloat mDiffuseLightB[] = {0.75164,0.60648,0.22648,1.0};
1002 GLfloat mSpecularB[] = {0.628281,0.555802,0.366065, 1.0};
1004 GLfloat mShininessB = 0.4;
1008 GLfloat mAmbient[] = {0.19125,0.0735,0.0225,1.0};
1010 GLfloat mDiffuseLight[] = {0.7038, 0.27048, 0.0828, 1.0};
1012 GLfloat mSpecular[] = {0.256777, 0.137622, 0.086014, 1.0};
1014 GLfloat mShininess = 0.1;
1017 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
1018 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
1019 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
1020 glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
1021 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
1022 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuseLight);
1023 glLightfv(GL_LIGHT1, GL_SPECULAR, specular);
1024 glLightfv(GL_LIGHT2, GL_AMBIENT, ambient);
1025 glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuseLight);
1026 glLightfv(GL_LIGHT2, GL_SPECULAR, specular);
1030 GLfloat positionZ[] = {0.0,0.0,
zobs,1.0};
1031 GLfloat positionY[] = {0.0,1.0,0.0,0.0};
1032 GLfloat positionX[] = {1.0,0.0,0.0,0.0};
1033 glLightfv(GL_LIGHT0, GL_POSITION, positionZ);
1034 glLightfv(GL_LIGHT1, GL_POSITION, positionY);
1035 glLightfv(GL_LIGHT2, GL_POSITION, positionX);
1041 GLfloat mcolor[] = { 1.0, 0.0, 0.0, 1.0 };
1042 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mcolor);
1045 glMaterialfv(GL_FRONT, GL_AMBIENT, mAmbient);
1046 glMaterialfv(GL_FRONT, GL_DIFFUSE, mDiffuseLight);
1047 glMaterialfv(GL_FRONT, GL_SPECULAR, mSpecular);
1048 glMaterialf(GL_FRONT, GL_SHININESS, mShininess*128);
1050 glMaterialfv(GL_BACK, GL_AMBIENT, mAmbientB);
1051 glMaterialfv(GL_BACK, GL_DIFFUSE, mDiffuseLightB);
1052 glMaterialfv(GL_BACK, GL_SPECULAR, mSpecularB);
1053 glMaterialf(GL_BACK, GL_SHININESS, mShininessB*128);
1055 glEnable (GL_LIGHT0);
1056 glEnable (GL_LIGHT1);
1057 glEnable (GL_LIGHT2);
1058 glEnable (GL_LIGHTING);
1061 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
1064 glEnable (GL_COLOR_MATERIAL);
1066 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
1070 glFrontFace(GL_CCW);
1073 glDepthFunc(GL_LEQUAL);
1075 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1082 glNewList(
objects, GL_COMPILE);
1083 glFrontFace(GL_CCW);
1086 glNewList(
objects+1, GL_COMPILE);
1087 glFrontFace(GL_CCW);
1090 glNewList(
objects+2, GL_COMPILE);
1091 glFrontFace(GL_CCW);
1094 glNewList(
objects+3, GL_COMPILE);
1098 glNewList(
objects+4, GL_COMPILE);
1099 glFrontFace(GL_CCW);
1102 glNewList(
objects+5, GL_COMPILE);
1106 glNewList(
objects+6, GL_COMPILE);
1107 glFrontFace(GL_CCW);
1110 glNewList(
objects+7, GL_COMPILE);
1113 glNewList(
objects+8, GL_COMPILE);
1116 glNewList(
objects+9, GL_COMPILE);
1119 glNewList(
objects+10, GL_COMPILE);
1122 glNewList(
objects+11, GL_COMPILE);
1125 glNewList(
objects+12, GL_COMPILE);
1128 glNewList(
objects+13, GL_COMPILE);
1131 glNewList(
objects+14, GL_COMPILE);
1142 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1146 glMatrixMode (GL_MODELVIEW);
1148 gluLookAt(0, 0,
zobs, 0, 0, 0, 0, 1, 0);
1149 arcball.applyRotationMatrix();
1168 glDisable (GL_LIGHTING);
1170 glEnable (GL_LIGHTING);
1173 glDisable (GL_LIGHTING);
1175 glEnable (GL_LIGHTING);
1178 glColor3d (0.8, 0.8, 0.0);
1179 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
1181 glColor3d (1.0, 1.0, 1.0);
1182 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
1184 glEnable(GL_TEXTURE_2D);
1189 glDisable(GL_TEXTURE_2D);
1191 glColor3d (1.0, 1.0, 1.0);
1203 gettimeofday(&tp, NULL);
1204 int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000;
1221 static int previousTimeStamp =
dateNow();
1223 static int numberOfFramesForFPS = 0;
1229 if ( fabs(currentTime - previousTimeStamp) >= 1000 ) {
1230 if ( numberOfFramesForFPS > 60 )
delay *= 2;
1231 else if ( numberOfFramesForFPS < 30 )
delay /= 2;
1232 printf(
"\rfps = %d, delay = %d", numberOfFramesForFPS,
delay);
1234 numberOfFramesForFPS = 0;
1235 previousTimeStamp = currentTime;
1238 numberOfFramesForFPS++;
1241 glutPostRedisplay();
1255 double d, dx, dy, dz;
1259 glViewport(0, 0, (GLsizei) w, (GLsizei) h);
1260 glMatrixMode(GL_PROJECTION);
1268 glMatrixMode(GL_MODELVIEW);
1274 gluLookAt(0, 0,
zobs, 0, 0, 0, 0, 1, 0);
1294 glutPostRedisplay();
1299 glutPostRedisplay();
1305 glClearColor(0.0, 0.0, 0.0, 0.0);
1307 glClearColor(1.0, 250/255.0, 205/255.0, 0.0);
1308 glutPostRedisplay();
1314 glutPostRedisplay();
1322 glutPostRedisplay();
1330 glutPostRedisplay();
1337 gluLookAt(0, 0,
zobs, 0, 0, 0, 0, 1, 0);
1340 glutPostRedisplay();
1345 glutPostRedisplay();
1350 glutPostRedisplay();
1368 glGetIntegerv(GL_VIEWPORT, viewport);
1369 reshape(viewport[2], viewport[3]);
1370 glutPostRedisplay();
1377 glGetFloatv(GL_MODELVIEW_MATRIX, model);
1380 glutPostRedisplay();
1386 glutPostRedisplay();
1391 glutPostRedisplay();
1397 glDeleteTextures(1, &
texName);
1399 glutPostRedisplay();
1403 printf (
"a, A: Draw Axes.\n");
1404 printf (
"b, B: Draw Box.\n");
1405 printf (
"g, G: Change background color.\n");
1406 printf (
"x, X: Rotate about x-axis.\n");
1407 printf (
"y, Y: Rotate about y-axis.\n");
1408 printf (
"z, Z: Rotate about z-axis.\n");
1409 printf (
"w, W: Toggle wireframe view.\n");
1410 printf (
"i, I: Return object to initial position.\n");
1411 printf (
"n, N: Toggle normal display.\n");
1412 printf (
"o, O: Increment object display: Torus -> Cylinder -> Cone -> Sphere -> Paraboloid -> Hyperbolic Paraboloid -> Hyperboloid.\n");
1413 printf (
"1,2,3,4,5,6,7: Display the ith object.\n");
1414 printf (
"t, T: Apply texture.\n");
1415 printf (
"p, P: Procedural x Image Texture.\n");
1416 printf (
"r, R: Euler angles x Arcball.\n");
1417 printf (
"s, S: Toggle spin.\n");
1418 printf (
"h, H: Display help.\n");
1419 printf (
"Esc: Exit.\n");
1445 if ( button == GLUT_LEFT_BUTTON )
1451 glutPostRedisplay();
1470 arcball.updateRotation(_x,_y);
1471 glutPostRedisplay();
1489 glutInitWindowSize(512, 512);
1490 glutInit(&argc, argv);
1491 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
1492 glutCreateWindow(argv[0]);
1493 memset(image,
'\0',
sizeof(image));
1494 strncpy(image,
"velazquez_texture_256.jpg",
sizeof(image));
1496 sscanf(argv[1],
"%lf", &
R1);
1497 sscanf(argv[2],
"%lf", &
R2);
1498 sscanf(argv[3],
"%lf", &
R3);
1499 sscanf(argv[4],
"%d", &
nR1);
1500 sscanf(argv[5],
"%d", &
nR2);
1501 if ( argc > 6 ) strncpy(image, argv[6],
sizeof(image));
1503 printf (
"R1 = %lf\n",
R1 );
1504 printf (
"R2 = %lf\n",
R2 );
1505 printf (
"R3 = %lf\n",
R3 );
1506 printf (
"nR1 = %d\n",
nR1 );
1507 printf (
"nR2 = %d\n",
nR2 );
1508 printf (
"Texture = %s\n", image );
1514 printf (
"Can't load image file %s using DevIL \n", image);
void cylinder(double h, double r, int vs, int rs, int normals)
Draw a cylinder, centered at the origin, with a circular base on plane XY.
int backG
Toggle background color.
void _timer(int value)
Timer callback function to be triggered in at least delay milliseconds.
#define clamp(x)
Clamp to [0,1].
struct _Point Point
3D point structure.
int loadImage(const char *filename)
Load an image from a file.
void cone(double h, double r, int vs, int rs, int normals)
Draw a cone, centered at the origin, with a circular base on plane XY.
_BBOX objBoxes[nObjects]
Object boxes.
void init(void)
Initialize OpenGL state.
enum _oType oType
Quadric types.
int useArcball
Whether to use the arcball paradigm.
int main(int argc, char **argv)
Main program for testing.
int procImage
Whether to use a procedural texture.
int dateNow()
Return the current Coordinated Universal Time (UTC) in miliseconds.
unsigned int delay
Controls the trigger of the timer function.
int applyTexture
Whether to apply texture.
void hyperboloid(double h, double a, double r, int vs, int rs, int normals)
Draw a one-sheeted hyperboloid of revolution, centered at the origin, with a circular base parallel t...
#define checkImageWidth
Texture Image width.
#define toRad(x)
Convert an angle to radians.
void updateBox(oType index, double x, double y, double z)
Add a new point to a bounding box.
void display(void)
Clear window, reset depth buffer and draw torus.
void mouseFunc(int state, int button, int _x, int _y)
Mouse callback interface.
void initTexture(void)
Initialize texture stuff.
int nR1
Number of samples.
int drawNormals
Whether display vertex normals.
double R3
Radius in z direction for an ellipsoid.
#define LEN(x, y, z)
Vector length.
#define nObjects
Number of objects;.
void sphere(double r1, double r2, double r3, int numc, int numt, int normals)
Draw an ellipsoid or a sphere centered at the origin.
double R2
Radius of the tube.
#define frontPlane
Front plane distance.
int showAxes
Whether to show the coordinate axes.
GLubyte checkImage[checkImageHeight][checkImageWidth][4]
Procedural image for a checkerboard.
GLuint texName
Texture identifier.
#define toDeg(x)
Convert an angle to degrees.
GLfloat rotAngle
Rotation angle increment.
#define farPlane
Far plane distance.
int nR2
Number of samples.
void paraboloid(double h, double r, int vs, int rs, int normals)
Draw a paraboloid, centered at the origin, with a circular base on plane XY.
enum _rAxes rAxes
Rotation axes.
double getBoxSize(oType index, double *dx, double *dy, double *dz)
Return bounding box dimension.
#define scale
Scale for drawing normals.
void drawAxes(double r1, double r2)
Draw the three coordinate axes.
void mouseDrag(int _x, int _y)
Mouse callback interface.
void makeCheckImage(void)
Create checkerboard texture.
void reshape(int w, int h)
Handle window resize.
int showBox
Whether to show the bounding boxes.
void torus(double r1, double r2, int numc, int numt, int normals)
Draw a torus, centered at the origin, and azimuthally symmetric about the z-axis.
Point _BBOX[2]
Axis aligned Bounding box.
ILuint ilImage
IL image identifier.
const char * objNames[]
Object names.
#define checkImageHeight
Texture Image height.
GLuint objects
Object display list base index.
double zobs
Camera position.
void keyboard(unsigned char key, int x, int y)
Keyboard callback interface.
int drawWire
Whether draw wireframe or filled polygons.
int OBJECT
Current object.
double R1
Distance from the center of the tube to the center of the torus.
void hyperbolic_paraboloid(double w, double h, int ws, int hs, int normals)
Draw a hyperbolic paraboloid.
void drawBox(const _BBOX BBOX)
Draw the bounding box as a dashed hexahedron.
double viewingAngle
Camera viewing angle, also known as opening angle.