#include #include #include #include #ifndef __sgi /* Most math.h's do not define float versions of math functions. */ #define floorf(x) ((float)floor((x))) #endif static float transx = 1.0, transy, rotx, roty; static int ox = -1, oy = -1; static int mot = 0; #define PAN 1 #define ROT 2 void pan(const int x, const int y) { transx += (x-ox)/5.; transy -= (y-oy)/5.; ox = x; oy = y; glutPostRedisplay(); } void rotate(const int x, const int y) { rotx += x-ox; if (rotx > 360.) rotx -= 360.; else if (rotx < -360.) rotx += 360.; roty += y-oy; if (roty > 360.) roty -= 360.; else if (roty < -360.) roty += 360.; ox = x; oy = y; glutPostRedisplay(); } void motion(int x, int y) { if (mot == PAN) pan(x, y); else if (mot == ROT) rotate(x,y); } void mouse(int button, int state, int x, int y) { if(state == GLUT_DOWN) { switch(button) { case GLUT_LEFT_BUTTON: mot = PAN; motion(ox = x, oy = y); break; case GLUT_MIDDLE_BUTTON: mot = ROT; motion(ox = x, oy = y); break; case GLUT_RIGHT_BUTTON: break; } } else if (state == GLUT_UP) { mot = 0; } } #define stripeImageWidth 32 GLubyte stripeImage[4*stripeImageWidth]; void makeStripeImage(void) { int j; for (j = 0; j < stripeImageWidth; j++) { stripeImage[4*j] = (GLubyte) ((j<=4) ? 255 : 0); stripeImage[4*j+1] = (GLubyte) ((j>4) ? 255 : 0); stripeImage[4*j+2] = (GLubyte) 0; stripeImage[4*j+3] = (GLubyte) 255; } } void hsv_to_rgb(float h,float s,float v,float *r,float *g,float *b) { int i; float f, p, q, t; h *= 360.0; if (s==0) { *r = v; *g = v; *b = v; } else { if (h==360) h = 0; h /= 60; i = floorf(h); f = h - i; p = v*(1.0-s); q = v*(1.0-(s*f)); t = v*(1.0-(s*(1.0-f))); switch (i) { case 0 : *r = v; *g = t; *b = p; break; case 1 : *r = q; *g = v; *b = p; break; case 2 : *r = p; *g = v; *b = t; break; case 3 : *r = p; *g = q; *b = v; break; case 4 : *r = t; *g = p; *b = v; break; case 5 : *r = v; *g = p; *b = q; break; } } } GLubyte rainbow[4*stripeImageWidth]; void makeRainbow(void) { int j; for (j = 0; j < stripeImageWidth; j++) { float r, g, b; hsv_to_rgb((float)j/(stripeImageWidth-1.f), 1.0, 1.0, &r, &g, &b); rainbow[4*j] = r*255; rainbow[4*j+1] = g*255; rainbow[4*j+2] = b*255; rainbow[4*j+3] = (GLubyte) 255; } } /* planes for texture coordinate generation */ static GLfloat xequalzero[] = {1.0, 0.0, 0.0, 0.0}; static GLfloat slanted[] = {1.0, 1.0, 1.0, 0.0}; static GLfloat *currentCoeff; static GLenum currentPlane; static GLint currentGenMode; void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); makeStripeImage(); makeRainbow(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, stripeImage); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); currentCoeff = xequalzero; currentGenMode = GL_OBJECT_LINEAR; currentPlane = GL_OBJECT_PLANE; glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode); glTexGenfv(GL_S, currentPlane, currentCoeff); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_1D); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glFrontFace(GL_CW); glCullFace(GL_BACK); glMaterialf (GL_FRONT, GL_SHININESS, 64.0); } void tfunc(void) { static int state; if (state ^= 1) { glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rainbow); } else { glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage1D(GL_TEXTURE_1D, 0, 4, stripeImageWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, stripeImage); } glutPostRedisplay(); } void display(void) { #if 0 static GLUquadricObj *q = NULL; #endif glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0., 0., transx); glRotatef(rotx, 1.0, 0.0, 0.0); glRotatef(45.0, 0.0, 0.0, 1.0); glutSolidTeapot(2.0); #if 0 if (!q) q = gluNewQuadric(); gluQuadricTexture(q, GL_TRUE); gluCylinder(q, 1.0, 2.0, 3.0, 10, 10); #endif glPopMatrix(); glutSwapBuffers(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho (-3.5, 3.5, -3.5*(GLfloat)h/(GLfloat)w, 3.5*(GLfloat)h/(GLfloat)w, -3.5, 3.5); else glOrtho (-3.5*(GLfloat)w/(GLfloat)h, 3.5*(GLfloat)w/(GLfloat)h, -3.5, 3.5, -3.5, 3.5); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /*ARGSUSED1*/ void keyboard (unsigned char key, int x, int y) { switch (key) { case 'e': case 'E': currentGenMode = GL_EYE_LINEAR; currentPlane = GL_EYE_PLANE; glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode); glTexGenfv(GL_S, currentPlane, currentCoeff); glutPostRedisplay(); break; case 'o': case 'O': currentGenMode = GL_OBJECT_LINEAR; currentPlane = GL_OBJECT_PLANE; glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode); glTexGenfv(GL_S, currentPlane, currentCoeff); glutPostRedisplay(); break; case 's': case 'S': currentCoeff = slanted; glTexGenfv(GL_S, currentPlane, currentCoeff); glutPostRedisplay(); break; case 'x': case 'X': currentCoeff = xequalzero; glTexGenfv(GL_S, currentPlane, currentCoeff); glutPostRedisplay(); break; case 't': tfunc(); break; case 27: exit(0); break; default: break; } } int main(int argc, char*argv[]) { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(256, 256); glutInitWindowPosition(100, 100); glutInit(&argc, argv); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); glutMotionFunc(motion); glutMainLoop(); return 0; }