LCG_cg 1.0
torus.cpp
Go to the documentation of this file.
1
44#define GL_GLEXT_PROTOTYPES
45
46#include <IL/il.h>
47#include <GL/glut.h>
48#include <stdio.h>
49#include <math.h>
50#include <stdlib.h>
51#include <string.h>
52#include <sys/time.h>
53#include <Arcball/Arcball.hpp>
54
59#define M_PI_ 3.14159265358979323846
61#define checkImageWidth 128
63#define checkImageHeight 128
67#define farPlane (zobs+10*d)
69#define frontPlane 1
71#define posAng(x) ((x) < 0.0 ? ((x)+TWOPI) : (x))
73#define TWOPI (2*M_PI)
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)
88
90double zobs = 10.0;
92double viewingAngle = 45;
94GLuint objects;
96double R1 = 1.0;
98double R2 = 0.3;
100double R3 = 0.5;
102int nR1 = 25;
104int nR2 = 10;
106int drawWire = 0;
112int showAxes = 0;
114int showBox = 0;
116int backG = 0;
118int procImage = 1;
122int spin = 1;
124typedef struct _Point {
125 double x, y, z;
128typedef Point _BBOX[2];
129
132
134typedef enum _rAxes {xAxis, yAxis, zAxis} rAxes;
135
138
140GLfloat rotAngle = 2.0;
141
143unsigned int delay = 60;
144
148GLuint texName;
150ILuint ilImage;
152const char *objNames[] = {"Torus", "Cylinder", "Cone", "Ellipsoid", "Paraboloid", "Hyperbolic Paraboloid", "Hyperboloid"};
158Arcball arcball;
159
180void updateBox(oType index, double x, double y, double z) {
181 _BBOX *bbox = objBoxes+index;
182
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);
189}
190
199double getBoxSize(oType index, double *dx, double *dy, double *dz) {
200 _BBOX *bbox = objBoxes+index;
201
202 *dx = (*bbox)[1].x - (*bbox)[0].x;
203 *dy = (*bbox)[1].y - (*bbox)[0].y;
204 *dz = (*bbox)[1].z - (*bbox)[0].z;
205
206 return LEN(*dx,*dy,*dz);
207}
208
242void cone(double h, double r, int vs, int rs, int normals) {
243 int i, j, k;
244 double z, th, x, y, ln, nx, ny, nz, u;
245 double hr = h / r;
246
247 double diag;
248 if (normals) {
249 double dx,dy,dz;
250 diag = getBoxSize(_cone,&dx,&dy,&dz);
251 }
252
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--) {
257 z = h * (i+k) / vs;
258 u = (h-z) / hr; // cone is upside down
259
260 th = j * TWOPI / rs;
261 x = u * cos(th);
262 y = u * sin(th);
263
264 nx = x * hr; ny = y * hr; nz = u > 0 ? u : 1; // cone is upside down
265 ln = LEN(nx,ny,nz);
266 nx /= ln; ny /= ln; nz /= ln;
267 th = clamp(th/TWOPI);
268
269 glNormal3d(nx, ny, nz);
270 glTexCoord2d(th,z/h);
271 glVertex3d(x, y, z);
272 if (normals)
273 glVertex3d(x+scale*nx, y+scale*ny, z+scale*nz);
274 else
275 updateBox(_cone, x, y, z);
276 }
277 }
278 glEnd();
279 }
280}
281
313void cylinder(double h, double r, int vs, int rs, int normals) {
314 int i, j;
315 double z0, z1, th, x, y, ln, nx, ny;
316
317 double diag;
318
319 if (normals) {
320 double dx,dy,dz;
321 diag = getBoxSize(_cylinder,&dx,&dy,&dz);
322 }
323
324 for (i = 0; i < vs; i++) { // generate stacks
325 z0 = h * i / vs; // stack bottom z
326 z1 = h * (i+1) / vs; // stack top z
327 glBegin(normals?GL_LINES:GL_QUAD_STRIP);
328 for (j = 0; j <= rs; j++) { // generate slices
329 th = j * TWOPI / rs; // slice left theta
330 x = r * cos(th);
331 y = r * sin(th);
332
333 ln = LEN(x,y,0);
334 nx = x/ln; ny = y/ln;
335 th = clamp(th/TWOPI);
336
337 glNormal3d(nx, ny, 0);
338 glTexCoord2d(th,z1/h);
339 glVertex3d(x, y, z1);
340 if (normals)
341 glVertex3d(x+scale*nx, y+scale*ny, z1);
342 else
343 updateBox(_cylinder, x, y, z1);
344 glNormal3d(nx, ny, 0);
345 glTexCoord2d(th,z0/h);
346 glVertex3d(x, y, z0);
347 if (normals)
348 glVertex3d(x+scale*nx, y+scale*ny, z0);
349 else
350 updateBox(_cylinder, x, y, z0);
351 }
352 glEnd();
353 }
354}
355
387void paraboloid(double h, double r, int vs, int rs, int normals) {
388 int i, j, k;
389 double z, th, x, y, ln, nx, ny, nz, u;
390 double hr2 = h/(r*r);
391
392 double diag;
393 if (normals) {
394 double dx,dy,dz;
395 diag = getBoxSize(_paraboloid,&dx,&dy,&dz);
396 }
397
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--) {
402 z = h * (i+k) / vs;
403 u = sqrt((h-z)/hr2); // paraboloid is upside down
404
405 th = j * TWOPI / rs;
406 x = u * cos(th);
407 y = u * sin(th);
408
409 nx = 2 * x * hr2; ny = 2 * y * hr2; nz = 1; // paraboloid is upside down
410 ln = LEN(nx,ny,nz);
411 nx /= ln; ny /= ln; nz /= ln;
412 th = clamp(th/TWOPI);
413
414 glNormal3d(nx, ny, nz);
415 glTexCoord2d(th,z/h);
416 glVertex3d(x, y, z);
417 if (normals)
418 glVertex3d(x+scale*nx, y+scale*ny, z+scale*nz);
419 else
420 updateBox(_paraboloid, x, y, z);
421 }
422 }
423 glEnd();
424 }
425}
426
463void hyperboloid(double h, double a, double r, int vs, int rs, int normals) {
464 int i, j, k;
465 double z, th, x, y, ln, nx, ny, nz, u;
466 double c = sqrt( h*h / (4 * (r*r/(a*a) - 1)) );
467 if ( r < a ) {
468 printf ( "Hyperboloid: r < a -> invalid!\n" );
469 return;
470 }
471
472 double diag;
473 if (normals) {
474 double dx,dy,dz;
475 diag = getBoxSize(_hyperboloid,&dx,&dy,&dz);
476 }
477
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--) {
482 z = h * (i+k) / vs;
483 u = z/c;
484 u = a * sqrt(1+u*u);
485
486 th = j * TWOPI / rs;
487 x = u * cos(th);
488 y = u * sin(th);
489
490 nx = x * c; ny = y * c; nz = -z * a * a / c;
491 ln = LEN(nx,ny,nz);
492 nx /= ln; ny /= ln; nz /= ln;
493 th = clamp(th/TWOPI);
494
495 glNormal3d(nx, ny, nz);
496 glTexCoord2d(th,(z+h)/(2*h)); // map [0,1] to [-h,h]
497 glVertex3d(x, y, z);
498 if (normals)
499 glVertex3d(x+scale*nx, y+scale*ny, z+scale*nz);
500 else
501 updateBox(_hyperboloid, x, y, z);
502 }
503 }
504 glEnd();
505 }
506}
507
539void hyperbolic_paraboloid(double w, double h, int ws, int hs, int normals) {
540 int i, j, k;
541 double u, v, z, x, y, ln, nx, ny, nz;
542
543 double diag;
544 if (normals) {
545 double dx,dy,dz;
546 diag = getBoxSize(_hyperbolic_paraboloid,&dx,&dy,&dz);
547 }
548
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--) {
553 u = j*w/ws;
554 v = (i+k)*h/hs;
555
556 x = u;
557 y = v;
558 z = u*v;
559
560 nx = y; ny = x; nz = -1;
561 ln = LEN(nx,ny,nz);
562 nx /= ln; ny /= ln; nz /= ln;
563
564 glNormal3d(nx, ny, nz);
565 glTexCoord2d((u+w)/(2*w),(v+h)/(2*h)); // map [0,1] to [-h,h]
566 glVertex3d(x, y, z);
567 if (normals)
568 glVertex3d(x+scale*nx, y+scale*ny, z+scale*nz);
569 else
571 }
572 }
573 glEnd();
574 }
575}
576
622void torus(double r1, double r2, int numc, int numt, int normals) {
623 int i, j, k;
624 double s, t, x, y, z;
625 double u, v, cu, cv, su, sv, nx, ny, nz;
626 double ln;
627
628 double diag;
629 if (normals) {
630 double dx,dy,dz;
631 diag = getBoxSize(_torus,&dx,&dy,&dz);
632 }
633
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--) {
638#if 0
639 s = (i + k) % numc + 0.5;
640 t = j % numt;
641#else
642 s = (i + k);
643 t = j;
644#endif
645 u = t*TWOPI/numt;
646 v = s*TWOPI/numc;
647
648 cu = cos(u);
649 cv = cos(v);
650 su = sin(u);
651 sv = sin(v);
652
653 // (x,y,z) = f(u,v)
654 x = (r1 + r2 * cv) * cu;
655 y = (r1 + r2 * cv) * su;
656 z = r2 * sv;
657
658 // df/du x df/dv
659 nx = cv * cu;
660 ny = cv * su;
661 nz = sv;
662
663 ln = LEN(nx,ny,nz);
664 nx /= ln; ny /= ln; nz /= ln;
665
666 u = clamp(u/TWOPI);
667 v = clamp(v/TWOPI);
668
669 glTexCoord2d(u,v);
670
671 glNormal3d(nx, ny, nz);
672 glVertex3d(x, y, z);
673 if (normals)
674 glVertex3d(x+scale*nx, y+scale*ny, z+scale*nz);
675 else
676 updateBox(_torus, x, y, z);
677 }
678 }
679 glEnd();
680 }
681}
682
722void sphere(double r1, double r2, double r3, int numc, int numt, int normals) {
723 int i, j, k;
724 double s, x, y, z;
725 double u, v, cu, cv, su, sv, nx, ny, nz;
726 double ln;
727
728 double diag;
729 if (normals) {
730 double dx,dy,dz;
731 diag = getBoxSize(_ellipsoid,&dx,&dy,&dz);
732 }
733
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--) {
738 s = (i + k);
739
740 u = j*TWOPI/numt;
741 v = s*M_PI/numc;
742
743 cu = cos(u);
744 cv = cos(v);
745 su = sin(u);
746 sv = sin(v);
747
748 // (x,y,z) = f(u,v)
749 x = r1 * cu * sv;
750 y = r2 * su * sv;
751 z = r3 * cv;
752
753 // df/du x df/dv
754 nx = r2*r3*r2*r3 * x;
755 ny = r1*r3*r1*r3 * y;
756 nz = r1*r2*r1*r2 * z;
757
758 ln = LEN(nx,ny,nz);
759 nx /= ln; ny /= ln; nz /= ln;
760
761 u = clamp(u/TWOPI);
762 v = clamp(v/M_PI);
763
764 glTexCoord2d(u,v);
765
766 glNormal3d(nx, ny, nz);
767 glVertex3d(x, y, z);
768 if (normals)
769 glVertex3d(x+scale*nx, y+scale*ny, z+scale*nz);
770 else
771 updateBox(_ellipsoid, x, y, z);
772 }
773 }
774 glEnd();
775 }
776}
777
785void drawAxes (double r1, double r2) {
786 double d;
787 d = r1+r2;
788 glBegin(GL_LINES);
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);
798 glEnd();
799}
800
805void drawBox (const _BBOX BBOX) {
806 // glPushAttrib is done to return everything to normal after drawing
807 glPushAttrib(GL_ENABLE_BIT);
808 glLineStipple(3, 0xAAAA); // [1]
809 glEnable(GL_LINE_STIPPLE);
810
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);
817 glEnd();
818
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);
824 glEnd();
825
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);
831 glEnd();
832
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);
838 glEnd();
839
840 glPopAttrib();
841}
842
860void makeCheckImage(void) {
861 int i, j, c;
862
863 for (i = 0; i < checkImageHeight; i++) {
864 for (j = 0; j < checkImageWidth; j++) {
865 // (i and 1000) xor (j and 1000)
866 c = ( (i&0x8)==0 ) ^ ( (j&0x8)==0 );
867 c *= 255;
868 if ( (i&0x8)==0 ) {
869 checkImage[i][j][0] = (GLubyte) fmax(c,255); // red
870 checkImage[i][j][1] = (GLubyte) c; // green
871 } else {
872 checkImage[i][j][0] = (GLubyte) c; // red
873 checkImage[i][j][1] = (GLubyte) fmax(c,128); // green
874 }
875 checkImage[i][j][2] = (GLubyte) c; // blue
876 checkImage[i][j][3] = (GLubyte) 255; // alpha
877 }
878 }
879}
880
887int loadImage (const char *filename) {
888 ILuint imageName;
889
890 ilGenImages(1, &imageName); // load just one image
891 ilBindImage(imageName); // set image name as the current image in DevIL
892
893 // load image filename using DevIL
894 if ( !ilLoadImage(filename) )
895 return -1;
896
897 // convert every colour component to unsigned byte
898 // one can replace IL_RGB with IL_RGBA if the image contains alpha channel
899 if ( !ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE) )
900 return -1;
901
902 return imageName;
903}
904
912void initTexture(void) {
913 // Create a checkerboard, by using a procedural texture: red, green and white.
915
916 // UNSIGNED_BYTE requires one byte alignment.
917 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
918
919 // Create a single texture and save its name as texName.
920 glGenTextures(1, &texName);
921 // Set texName as the current texture.
922 glBindTexture(GL_TEXTURE_2D, texName);
923 // Specifies a texture environment.
924 // GL_DECAL ignores the primary color and just shows the texel.
925 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
926
927 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
928 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
929 // GL_TEXTURE_MIN_FILTER is used whenever a surface is rendered with
930 // smaller dimensions than its corresponding texture bitmap (far away objects).
931 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
932 // GL_TEXTURE_MAG_FILTER is used in the exact opposite case:
933 // a surface is bigger than the texture being applied (near objects)
934 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
935
936 if ( procImage ) {
937 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight,
938 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
939 } else {
940
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());
943 }
944
945 // Mipmap only makes sense for the MIN_FILTER.
946 glGenerateMipmap(GL_TEXTURE_2D); // allocate the mipmaps, after texture is created.
947}
948
949
975void init(void) {
976 glEnable(GL_DEPTH_TEST);
977 // Depth value used when the depth buffer is cleared.
978 glClearDepth(1.0);
979 // Gouraud shading.
980 glShadeModel (GL_SMOOTH);
981 // Background color.
982 glClearColor(1.0, 250/255.0, 205/255.0, 0.0);
983 //glEnable(GL_NORMALIZE);
984 glEnable(GL_RESCALE_NORMAL);
985 // Disable clipping against near and far planes.
986 glDisable(GL_DEPTH_CLAMP);
987
988 // Create light components
989 GLfloat global_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
990 GLfloat ambient[] = { 0.05, 0.05, 0.05 };
991 // diffuse light color
992 GLfloat diffuseLight[] = { 0.8, 0.8, 0.8, 1.0 };
993 // specular light color
994 GLfloat specular[] = {1.0, 1.0, 1.0 , 1.0};
995
996 // Gold color: OpenGL/VRML Materials
997 // ambient material color
998 GLfloat mAmbientB[] = {0.24725,0.1995,0.0745,1.0};
999 // diffuse material color
1000 GLfloat mDiffuseLightB[] = {0.75164,0.60648,0.22648,1.0};
1001 // specular material color
1002 GLfloat mSpecularB[] = {0.628281,0.555802,0.366065, 1.0};
1003 // set the shininess of the material
1004 GLfloat mShininessB = 0.4;
1005
1006 // Cooper color: OpenGL/VRML Materials
1007 // ambient material color
1008 GLfloat mAmbient[] = {0.19125,0.0735,0.0225,1.0};
1009 // diffuse material color
1010 GLfloat mDiffuseLight[] = {0.7038, 0.27048, 0.0828, 1.0};
1011 // specular material color
1012 GLfloat mSpecular[] = {0.256777, 0.137622, 0.086014, 1.0};
1013 // set the shininess of the material
1014 GLfloat mShininess = 0.1;
1015
1016 // Assign created components to GL_LIGHT0
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);
1027
1028 // It's a 4D vector. If w=1, then it's a positional light source.
1029 // If w=0, it's a directional light source.
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);
1036
1037 // mcolor will be applied to both ambient and diffuse components of the material.
1038 // This is done for convenience because in most cases Ambient and Diffuse properties
1039 // of a material should be set to the same color.
1040#if 0
1041 GLfloat mcolor[] = { 1.0, 0.0, 0.0, 1.0 };
1042 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mcolor);
1043#endif
1044
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);
1049
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);
1054
1055 glEnable (GL_LIGHT0);
1056 glEnable (GL_LIGHT1);
1057 glEnable (GL_LIGHT2);
1058 glEnable (GL_LIGHTING);
1059 // Whether one- or two-sided lighting calculations are done for polygons.
1060 // It has no effect on the lighting calculations for points, lines, or bitmaps.
1061 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
1062#if 0
1063 // enable color tracking (specify material properties by merely calling the glColor)
1064 glEnable (GL_COLOR_MATERIAL);
1065 // set material properties which will be assigned by glColor
1066 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
1067#endif
1068 // specifies the orientation of front-facing polygons.
1069 // GL_CW and GL_CCW are accepted. The initial value is GL_CCW.
1070 glFrontFace(GL_CCW);
1071 // specifies the function used to compare each incoming pixel depth value
1072 // with the depth value present in the depth buffer.
1073 glDepthFunc(GL_LEQUAL);
1074 glLineWidth(2.0);
1075 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1076
1077 initTexture();
1078
1079 // create 2*nObjects+1 display lists
1080 objects = glGenLists (theAxes+1);
1081
1082 glNewList(objects, GL_COMPILE);
1083 glFrontFace(GL_CCW);
1084 torus(R1, R2, nR2, nR1, 0);
1085 glEndList();
1086 glNewList(objects+1, GL_COMPILE);
1087 glFrontFace(GL_CCW);
1088 cylinder ( 2*R1, 2*R2, nR2, nR1 , 0 );
1089 glEndList();
1090 glNewList(objects+2, GL_COMPILE);
1091 glFrontFace(GL_CCW);
1092 cone ( 2*R1, 2*R2, nR2, nR1 , 0 );
1093 glEndList();
1094 glNewList(objects+3, GL_COMPILE);
1095 glFrontFace(GL_CW);
1096 sphere ( 1.5*R1, 1.5*R2, 1.5*R3, nR2, nR1 , 0 );
1097 glEndList();
1098 glNewList(objects+4, GL_COMPILE);
1099 glFrontFace(GL_CCW);
1100 paraboloid ( 2*R1, 2*R2, nR2, nR1 , 0 );
1101 glEndList();
1102 glNewList(objects+5, GL_COMPILE);
1103 glFrontFace(GL_CW);
1104 hyperbolic_paraboloid ( 2*R1, 2*R1, nR1/2, nR1/2, 0 );
1105 glEndList();
1106 glNewList(objects+6, GL_COMPILE);
1107 glFrontFace(GL_CCW);
1108 hyperboloid ( R1, R2, R3, nR1/3, nR2, 0 );
1109 glEndList();
1110 glNewList(objects+7, GL_COMPILE);
1111 torus(R1, R2, nR2, nR1, 1);
1112 glEndList();
1113 glNewList(objects+8, GL_COMPILE);
1114 cylinder ( 2*R1, 2*R2, nR2, nR1, 1 );
1115 glEndList();
1116 glNewList(objects+9, GL_COMPILE);
1117 cone ( 2*R1, 2*R2, nR2, nR1, 1 );
1118 glEndList();
1119 glNewList(objects+10, GL_COMPILE);
1120 sphere ( 1.5*R1, 1.5*R2, 1.5*R3, nR2, nR1, 1 );
1121 glEndList();
1122 glNewList(objects+11, GL_COMPILE);
1123 paraboloid ( 2*R1, 2*R2, nR2, nR1, 1 );
1124 glEndList();
1125 glNewList(objects+12, GL_COMPILE);
1126 hyperbolic_paraboloid ( 2*R1, 2*R1, nR1/2, nR1/2, 1 );
1127 glEndList();
1128 glNewList(objects+13, GL_COMPILE);
1129 hyperboloid ( R1, R2, R3, nR1/3, nR2, 1 );
1130 glEndList();
1131 glNewList(objects+14, GL_COMPILE);
1132 drawAxes ( R1, R2 );
1133 glEndList();
1134}
1135
1141void display(void) {
1142 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1143
1144 if (useArcball) {
1145 // Apply arcball transformation.
1146 glMatrixMode (GL_MODELVIEW);
1147 glLoadIdentity();
1148 gluLookAt(0, 0, zobs, 0, 0, 0, 0, 1, 0);
1149 arcball.applyRotationMatrix();
1150 } else {
1151 if ( spin )
1152 switch (axis) {
1153 case xAxis:
1154 glRotatef(rotAngle, 1.0,0.0,0.0);
1155 break;
1156 case yAxis:
1157 glRotatef(rotAngle,0.0,1.0,0.0);
1158 break;
1159 case zAxis:
1160 glRotatef(rotAngle,0.0,0.0,1.0);
1161 break;
1162 default:
1163 ;
1164 }
1165 }
1166
1167 if ( showAxes ) {
1168 glDisable (GL_LIGHTING);
1169 glCallList(objects+theAxes);
1170 glEnable (GL_LIGHTING);
1171 }
1172 if ( showBox ) {
1173 glDisable (GL_LIGHTING);
1175 glEnable (GL_LIGHTING);
1176 }
1177 if ( drawWire ) {
1178 glColor3d (0.8, 0.8, 0.0);
1179 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
1180 } else {
1181 glColor3d (1.0, 1.0, 1.0);
1182 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
1183 if ( applyTexture ) {
1184 glEnable(GL_TEXTURE_2D);
1185 }
1186 }
1187
1188 glCallList(objects+OBJECT);
1189 glDisable(GL_TEXTURE_2D);
1190
1191 glColor3d (1.0, 1.0, 1.0);
1192 if (drawNormals) glCallList(objects+OBJECT+nObjects);
1193
1194 glutSwapBuffers();
1195}
1196
1201int dateNow() {
1202 struct timeval tp;
1203 gettimeofday(&tp, NULL);
1204 int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000;
1205 return ms;
1206}
1207
1219void _timer(int value) {
1220 // Previous time.
1221 static int previousTimeStamp = dateNow();
1222 // Frames per second.
1223 static int numberOfFramesForFPS = 0;
1224 // Current time.
1225 int currentTime;
1226
1227 // How many times we've been here in one second.
1228 currentTime = dateNow();
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);
1233 fflush(stdout);
1234 numberOfFramesForFPS = 0;
1235 previousTimeStamp = currentTime;
1236 }
1237
1238 numberOfFramesForFPS++;
1239
1240 // send redisplay event
1241 glutPostRedisplay();
1242
1243 // call this function again in delay milliseconds
1244 glutTimerFunc(delay, _timer, value);
1245}
1246
1254void reshape(int w, int h) {
1255 double d, dx, dy, dz;
1256 d = getBoxSize((oType)OBJECT, &dx, &dy, &dz);
1257
1258 // Set the viewport to be the entire window
1259 glViewport(0, 0, (GLsizei) w, (GLsizei) h);
1260 glMatrixMode(GL_PROJECTION);
1261 glLoadIdentity();
1262#if 0
1263 // set camera angle to fit object
1264 viewingAngle = 2.0 * atan2(d*0.8,zobs);
1266#endif
1267 gluPerspective(viewingAngle, (GLfloat)w/h, frontPlane, farPlane);
1268 glMatrixMode(GL_MODELVIEW);
1269 glLoadIdentity();
1270#if 1
1271 // set camera position to fit object
1272 zobs = d * 0.8 / tan(toRad(viewingAngle*0.5));
1273#endif
1274 gluLookAt(0, 0, zobs, 0, 0, 0, 0, 1, 0);
1275 arcball.setWidthHeight(w, h);
1276}
1277
1289void keyboard(unsigned char key, int x, int y) {
1290 switch (key) {
1291 case 'a':
1292 case 'A':
1293 showAxes = !showAxes;
1294 glutPostRedisplay();
1295 break;
1296 case 'b':
1297 case 'B':
1298 showBox = !showBox;
1299 glutPostRedisplay();
1300 break;
1301 case 'g':
1302 case 'G':
1303 backG = !backG;
1304 if ( backG)
1305 glClearColor(0.0, 0.0, 0.0, 0.0);
1306 else
1307 glClearColor(1.0, 250/255.0, 205/255.0, 0.0);
1308 glutPostRedisplay();
1309 break;
1310 case 'x':
1311 case 'X':
1312 if (!spin) {
1313 glRotatef(rotAngle,1.0,0.0,0.0);
1314 glutPostRedisplay();
1315 }
1316 axis = xAxis;
1317 break;
1318 case 'y':
1319 case 'Y':
1320 if (!spin) {
1321 glRotatef(rotAngle,0.0,1.0,0.0);
1322 glutPostRedisplay();
1323 }
1324 axis = yAxis;
1325 break;
1326 case 'z':
1327 case 'Z':
1328 if (!spin) {
1329 glRotatef(rotAngle,0.0,0.0,1.0);
1330 glutPostRedisplay();
1331 }
1332 axis = zAxis;
1333 break;
1334 case 'i':
1335 case 'I':
1336 glLoadIdentity();
1337 gluLookAt(0, 0, zobs, 0, 0, 0, 0, 1, 0);
1338 axis = xAxis;
1339 arcball.reset();
1340 glutPostRedisplay();
1341 break;
1342 case 'w':
1343 case 'W':
1344 drawWire = !drawWire;
1345 glutPostRedisplay();
1346 break;
1347 case 'n':
1348 case 'N':
1350 glutPostRedisplay();
1351 break;
1352 case 'o':
1353 case 'O':
1354 ++OBJECT;
1355 OBJECT %= nObjects;
1356 goto code;
1357 case '1':
1358 case '2':
1359 case '3':
1360 case '4':
1361 case '5':
1362 case '6':
1363 case '7':
1364 OBJECT = key - '0' - 1;
1365 code:
1366 glutSetWindowTitle(objNames[OBJECT]);
1367 GLint viewport[4];
1368 glGetIntegerv(GL_VIEWPORT, viewport);
1369 reshape(viewport[2], viewport[3]);
1370 glutPostRedisplay();
1371 break;
1372 case 'r':
1373 case 'R':
1375 if (useArcball) {
1376 GLMatrix model;
1377 glGetFloatv(GL_MODELVIEW_MATRIX, model);
1378 arcball.setViewMatrix(model);
1379 }
1380 glutPostRedisplay();
1381 break;
1382 case 's':
1383 case 'S':
1384 spin = !spin;
1385 rotAngle = spin ? 2 : 30;
1386 glutPostRedisplay();
1387 break;
1388 case 't':
1389 case 'T':
1391 glutPostRedisplay();
1392 break;
1393 case 'p':
1394 case 'P':
1396 // Delete the current texture, so it can be recreated.
1397 glDeleteTextures(1, &texName);
1398 initTexture();
1399 glutPostRedisplay();
1400 break;
1401 case 'h':
1402 case 'H':
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");
1420 break;
1421 case 27:
1422 ilDeleteImages(1, &ilImage);
1423 printf("\n");
1424 exit(0);
1425 break;
1426 }
1427}
1428
1441void mouseFunc(int state, int button, int _x , int _y) {
1442
1443 if (!useArcball) return;
1444
1445 if ( button == GLUT_LEFT_BUTTON )
1446 arcball.startRotation(_x,_y);
1447 else
1448 arcball.stopRotation();
1449
1450
1451 glutPostRedisplay();
1452 }
1453
1468void mouseDrag(int _x, int _y) {
1469 if (!useArcball) return;
1470 arcball.updateRotation(_x,_y);
1471 glutPostRedisplay();
1472}
1473
1487int main(int argc, char **argv) {
1488 char image[256];
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));
1495 if ( argc > 5 ) {
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));
1502 } else {
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 );
1509 }
1510
1511 ilInit();
1512 // load the file image with DevIL
1513 if ( (ilImage=loadImage(image)) == -1 ) {
1514 printf ("Can't load image file %s using DevIL \n", image);
1515 return -1;
1516 }
1517
1518 init();
1519 arcball = Arcball();
1520 glutReshapeFunc(reshape);
1521 glutKeyboardFunc(keyboard);
1522 glutMouseFunc(mouseFunc);
1523 glutMotionFunc(mouseDrag);
1524 glutTimerFunc(delay, _timer, 0);
1525 glutDisplayFunc(display);
1526 display();
1527 glutMainLoop();
1528 return 0;
1529}
3D point structure.
Definition torus.cpp:124
double x
Definition torus.cpp:125
double y
Definition torus.cpp:125
double z
Definition torus.cpp:125
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.
Definition torus.cpp:313
int backG
Toggle background color.
Definition torus.cpp:116
void _timer(int value)
Timer callback function to be triggered in at least delay milliseconds.
Definition torus.cpp:1219
#define clamp(x)
Clamp to [0,1].
Definition torus.cpp:79
struct _Point Point
3D point structure.
int loadImage(const char *filename)
Load an image from a file.
Definition torus.cpp:887
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.
Definition torus.cpp:242
_BBOX objBoxes[nObjects]
Object boxes.
Definition torus.cpp:154
void init(void)
Initialize OpenGL state.
Definition torus.cpp:975
enum _oType oType
Quadric types.
int useArcball
Whether to use the arcball paradigm.
Definition torus.cpp:120
int main(int argc, char **argv)
Main program for testing.
Definition torus.cpp:1487
int procImage
Whether to use a procedural texture.
Definition torus.cpp:118
int dateNow()
Return the current Coordinated Universal Time (UTC) in miliseconds.
Definition torus.cpp:1201
unsigned int delay
Controls the trigger of the timer function.
Definition torus.cpp:143
int applyTexture
Whether to apply texture.
Definition torus.cpp:110
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...
Definition torus.cpp:463
int spin
Automatic spin.
Definition torus.cpp:122
#define checkImageWidth
Texture Image width.
Definition torus.cpp:61
#define TWOPI
Two PI.
Definition torus.cpp:73
_rAxes
Rotation axes.
Definition torus.cpp:134
@ yAxis
Definition torus.cpp:134
@ zAxis
Definition torus.cpp:134
@ xAxis
Definition torus.cpp:134
#define toRad(x)
Convert an angle to radians.
Definition torus.cpp:75
void updateBox(oType index, double x, double y, double z)
Add a new point to a bounding box.
Definition torus.cpp:180
void display(void)
Clear window, reset depth buffer and draw torus.
Definition torus.cpp:1141
void mouseFunc(int state, int button, int _x, int _y)
Mouse callback interface.
Definition torus.cpp:1441
void initTexture(void)
Initialize texture stuff.
Definition torus.cpp:912
int nR1
Number of samples.
Definition torus.cpp:102
int drawNormals
Whether display vertex normals.
Definition torus.cpp:108
double R3
Radius in z direction for an ellipsoid.
Definition torus.cpp:100
#define LEN(x, y, z)
Vector length.
Definition torus.cpp:81
#define nObjects
Number of objects;.
Definition torus.cpp:85
void sphere(double r1, double r2, double r3, int numc, int numt, int normals)
Draw an ellipsoid or a sphere centered at the origin.
Definition torus.cpp:722
double R2
Radius of the tube.
Definition torus.cpp:98
#define frontPlane
Front plane distance.
Definition torus.cpp:69
int showAxes
Whether to show the coordinate axes.
Definition torus.cpp:112
rAxes axis
Current axis.
Definition torus.cpp:137
GLubyte checkImage[checkImageHeight][checkImageWidth][4]
Procedural image for a checkerboard.
Definition torus.cpp:146
_oType
Quadric types.
Definition torus.cpp:131
@ _hyperboloid
Definition torus.cpp:131
@ _hyperbolic_paraboloid
Definition torus.cpp:131
@ _ellipsoid
Definition torus.cpp:131
@ _torus
Definition torus.cpp:131
@ _paraboloid
Definition torus.cpp:131
@ _cone
Definition torus.cpp:131
@ _cylinder
Definition torus.cpp:131
GLuint texName
Texture identifier.
Definition torus.cpp:148
#define toDeg(x)
Convert an angle to degrees.
Definition torus.cpp:77
GLfloat rotAngle
Rotation angle increment.
Definition torus.cpp:140
#define farPlane
Far plane distance.
Definition torus.cpp:67
int nR2
Number of samples.
Definition torus.cpp:104
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.
Definition torus.cpp:387
Arcball arcball
ArcBall.
Definition torus.cpp:158
enum _rAxes rAxes
Rotation axes.
double getBoxSize(oType index, double *dx, double *dy, double *dz)
Return bounding box dimension.
Definition torus.cpp:199
#define scale
Scale for drawing normals.
Definition torus.cpp:87
void drawAxes(double r1, double r2)
Draw the three coordinate axes.
Definition torus.cpp:785
void mouseDrag(int _x, int _y)
Mouse callback interface.
Definition torus.cpp:1468
void makeCheckImage(void)
Create checkerboard texture.
Definition torus.cpp:860
#define theAxes
Axes.
Definition torus.cpp:83
void reshape(int w, int h)
Handle window resize.
Definition torus.cpp:1254
int showBox
Whether to show the bounding boxes.
Definition torus.cpp:114
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.
Definition torus.cpp:622
Point _BBOX[2]
Axis aligned Bounding box.
Definition torus.cpp:128
ILuint ilImage
IL image identifier.
Definition torus.cpp:150
const char * objNames[]
Object names.
Definition torus.cpp:152
#define checkImageHeight
Texture Image height.
Definition torus.cpp:63
GLuint objects
Object display list base index.
Definition torus.cpp:94
double zobs
Camera position.
Definition torus.cpp:90
void keyboard(unsigned char key, int x, int y)
Keyboard callback interface.
Definition torus.cpp:1289
int drawWire
Whether draw wireframe or filled polygons.
Definition torus.cpp:106
int OBJECT
Current object.
Definition torus.cpp:156
double R1
Distance from the center of the tube to the center of the torus.
Definition torus.cpp:96
void hyperbolic_paraboloid(double w, double h, int ws, int hs, int normals)
Draw a hyperbolic paraboloid.
Definition torus.cpp:539
void drawBox(const _BBOX BBOX)
Draw the bounding box as a dashed hexahedron.
Definition torus.cpp:805
double viewingAngle
Camera viewing angle, also known as opening angle.
Definition torus.cpp:92