2 * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that (i) the above copyright notices and this permission notice appear in
7 * all copies of the software and related documentation, and (ii) the name of
8 * Silicon Graphics may not be used in any advertising or
9 * publicity relating to the software without the specific, prior written
10 * permission of Silicon Graphics.
12 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
17 * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25 /* BEP: renamed "nearest" as "nnearest" to avoid math.h collision on AIX */
36 #define PI 3.14159265358979323846
43 char *imageFileName
= "../images/reflect.rgb";
45 float *minFilter
, *magFilter
, *sWrapMode
, *tWrapMode
;
46 float decal
[] = {GL_DECAL
};
47 float modulate
[] = {GL_MODULATE
};
48 float repeat
[] = {GL_REPEAT
};
49 float clamp
[] = {GL_CLAMP
};
50 float nnearest
[] = {GL_NEAREST
};
51 float linear
[] = {GL_LINEAR
};
52 float nearest_mipmap_nearest
[] = {GL_NEAREST_MIPMAP_NEAREST
};
53 float nearest_mipmap_linear
[] = {GL_NEAREST_MIPMAP_LINEAR
};
54 float linear_mipmap_nearest
[] = {GL_LINEAR_MIPMAP_NEAREST
};
55 float linear_mipmap_linear
[] = {GL_LINEAR_MIPMAP_LINEAR
};
56 GLint sphereMap
[] = {GL_SPHERE_MAP
};
58 float xRotation
= 0.0, yRotation
= 0.0;
59 float zTranslate
= -3.0;
60 GLenum autoRotate
= GL_TRUE
;
61 GLboolean isLit
= GL_TRUE
;
62 GLboolean isFogged
= GL_FALSE
;
63 GLboolean doTexture
= GL_TRUE
;
64 float *textureEnvironment
= modulate
;
66 int cube
, cage
, cylinder
, torus
, genericObject
;
68 float c
[6][4][4][3] = {
440 GLfloat identity
[16] = {
448 static void BuildCylinder(int numEdges
)
450 int i
, top
= 1.0, bottom
= -1.0;
451 float x
[100], y
[100], angle
;
453 for (i
= 0; i
<= numEdges
; i
++) {
454 angle
= i
* 2.0 * PI
/ numEdges
;
455 x
[i
] = cos(angle
); /* was cosf() */
456 y
[i
] = sin(angle
); /* was sinf() */
459 glNewList(cylinder
, GL_COMPILE
);
460 glBegin(GL_TRIANGLE_STRIP
);
461 for (i
= 0; i
<= numEdges
; i
++) {
462 glNormal3f(x
[i
], y
[i
], 0.0);
463 glVertex3f(x
[i
], y
[i
], bottom
);
464 glVertex3f(x
[i
], y
[i
], top
);
467 glBegin(GL_TRIANGLE_FAN
);
468 glNormal3f(0.0, 0.0, 1.0);
469 glVertex3f(0.0, 0.0, top
);
470 for (i
= 0; i
<= numEdges
; i
++) {
471 glVertex3f(x
[i
], -y
[i
], top
);
474 glBegin(GL_TRIANGLE_FAN
);
475 glNormal3f(0.0, 0.0, -1.0);
476 glVertex3f(0.0, 0.0, bottom
);
477 for (i
= 0; i
<= numEdges
; i
++) {
478 glVertex3f(x
[i
], y
[i
], bottom
);
484 static void BuildTorus(float rc
, int numc
, float rt
, int numt
)
491 pi
= 3.14159265358979323846;
494 glNewList(torus
, GL_COMPILE
);
495 for (i
= 0; i
< numc
; i
++) {
496 glBegin(GL_QUAD_STRIP
);
497 for (j
= 0; j
<= numt
; j
++) {
498 for (k
= 0; k
<= 1; k
++) {
499 s
= (i
+ k
) % numc
+ 0.5;
502 x
= cos(t
*twopi
/numt
) * cos(s
*twopi
/numc
);
503 y
= sin(t
*twopi
/numt
) * cos(s
*twopi
/numc
);
504 z
= sin(s
*twopi
/numc
);
507 x
= (rt
+ rc
* cos(s
*twopi
/numc
)) * cos(t
*twopi
/numt
);
508 y
= (rt
+ rc
* cos(s
*twopi
/numc
)) * sin(t
*twopi
/numt
);
509 z
= rc
* sin(s
*twopi
/numc
);
518 static void BuildCage(void)
522 float right
, left
, top
, bottom
, front
, back
;
532 inc
= 2.0 * 4.0 * 0.1;
534 glNewList(cage
, GL_COMPILE
);
535 for (i
= 0; i
< 10; i
++) {
541 glVertex3f(left
+i
*inc
, top
, back
);
542 glVertex3f(left
+i
*inc
, bottom
, back
);
545 glVertex3f(right
, bottom
+i
*inc
, back
);
546 glVertex3f(left
, bottom
+i
*inc
, back
);
553 glVertex3f(left
+i
*inc
, top
, front
);
554 glVertex3f(left
+i
*inc
, bottom
, front
);
557 glVertex3f(right
, bottom
+i
*inc
, front
);
558 glVertex3f(left
, bottom
+i
*inc
, front
);
565 glVertex3f(left
, bottom
+i
*inc
, front
);
566 glVertex3f(left
, bottom
+i
*inc
, back
);
569 glVertex3f(left
, top
, back
+i
*inc
);
570 glVertex3f(left
, bottom
, back
+i
*inc
);
577 glVertex3f(right
, top
-i
*inc
, front
);
578 glVertex3f(right
, top
-i
*inc
, back
);
581 glVertex3f(right
, top
, back
+i
*inc
);
582 glVertex3f(right
, bottom
, back
+i
*inc
);
589 glVertex3f(left
+i
*inc
, top
, front
);
590 glVertex3f(left
+i
*inc
, top
, back
);
593 glVertex3f(right
, top
, back
+i
*inc
);
594 glVertex3f(left
, top
, back
+i
*inc
);
601 glVertex3f(right
-i
*inc
, bottom
, front
);
602 glVertex3f(right
-i
*inc
, bottom
, back
);
605 glVertex3f(right
, bottom
, back
+i
*inc
);
606 glVertex3f(left
, bottom
, back
+i
*inc
);
612 static void BuildCube(void)
616 glNewList(cube
, GL_COMPILE
);
617 for (i
= 0; i
< 6; i
++) {
618 for (j
= 0; j
< 4; j
++) {
621 glVertex3fv(c
[i
][j
][0]);
622 glVertex3fv(c
[i
][j
][1]);
623 glVertex3fv(c
[i
][j
][2]);
624 glVertex3fv(c
[i
][j
][3]);
631 static void BuildLists(void)
634 cube
= glGenLists(1);
637 cage
= glGenLists(2);
640 cylinder
= glGenLists(3);
643 torus
= glGenLists(4);
644 BuildTorus(0.65, 20, .85, 65);
646 genericObject
= torus
;
649 static void SetDefaultSettings(void)
652 magFilter
= nnearest
;
653 minFilter
= nnearest
;
656 textureEnvironment
= modulate
;
657 autoRotate
= GL_TRUE
;
660 static unsigned char *AlphaPadImage(int bufSize
, unsigned char *inData
, int alpha
)
662 unsigned char *outData
, *out_ptr
, *in_ptr
;
665 outData
= (unsigned char *) malloc(bufSize
* 4);
669 for (i
= 0; i
< bufSize
; i
++) {
670 *out_ptr
++ = *in_ptr
++;
671 *out_ptr
++ = *in_ptr
++;
672 *out_ptr
++ = *in_ptr
++;
680 static void Init(void)
682 float ambient
[] = {0.0, 0.0, 0.0, 1.0};
683 float diffuse
[] = {1.0, 1.0, 1.0, 1.0};
684 float specular
[] = {1.0, 1.0, 1.0, 1.0};
685 float position
[] = {0.0, 0.0, 4.0, 0.0};
686 float fog_color
[] = {0.0, 0.0, 0.0, 1.0};
687 float mat_ambient
[] = {0.0, 0.0, 0.0, 1.0};
688 float mat_shininess
[] = {90.0};
689 float mat_specular
[] = {1.0, 1.0, 1.0, 1.0};
690 float mat_diffuse
[] = {0.8, 0.8, 0.8, 1.0};
691 float lmodel_ambient
[] = {0.2, 0.2, 0.2, 1.0};
692 float lmodel_twoside
[] = {GL_TRUE
};
697 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
699 SetDefaultSettings();
701 image
= LoadRGBImage(imageFileName
, &w
, &h
, &format
);
703 printf("Error: couldn't load %s\n", imageFileName
);
706 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
707 gluBuild2DMipmaps(GL_TEXTURE_2D
, format
, w
, h
,
708 GL_RGB
, GL_UNSIGNED_BYTE
, image
);
712 glFogf(GL_FOG_DENSITY
, 0.125);
713 glFogi(GL_FOG_MODE
, GL_LINEAR
);
714 glFogf(GL_FOG_START
, 4.0);
715 glFogf(GL_FOG_END
, 8.5);
716 glFogfv(GL_FOG_COLOR
, fog_color
);
718 glLightfv(GL_LIGHT0
, GL_AMBIENT
, ambient
);
719 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, diffuse
);
720 glLightfv(GL_LIGHT0
, GL_SPECULAR
, specular
);
721 glLightfv(GL_LIGHT0
, GL_POSITION
, position
);
724 glMaterialfv(GL_FRONT_AND_BACK
, GL_SHININESS
, mat_shininess
);
725 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, mat_specular
);
726 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, mat_diffuse
);
727 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT
, mat_ambient
);
729 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, lmodel_ambient
);
730 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE
, lmodel_twoside
);
731 glShadeModel(GL_SMOOTH
);
734 glClearColor(0.0, 0.0, 0.0, 0.0);
735 glEnable(GL_DEPTH_TEST
);
738 glEnable(GL_CULL_FACE
);
741 glTexGeniv(GL_S
, GL_TEXTURE_GEN_MODE
, sphereMap
);
742 glTexGeniv(GL_T
, GL_TEXTURE_GEN_MODE
, sphereMap
);
743 glEnable(GL_TEXTURE_GEN_S
);
744 glEnable(GL_TEXTURE_GEN_T
);
746 glTexParameterfv(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, magFilter
);
747 glTexParameterfv(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, minFilter
);
748 glTexParameterfv(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, sWrapMode
);
749 glTexParameterfv(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, tWrapMode
);
751 glTexEnvfv(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, textureEnvironment
);
756 static void ReInit(void)
758 if (genericObject
== torus
) {
759 glEnable(GL_DEPTH_TEST
);
761 glDisable(GL_DEPTH_TEST
);
763 glEnable(GL_DEPTH_TEST
);
767 textureEnvironment
= modulate
;
771 glTexParameterfv(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, magFilter
);
772 glTexParameterfv(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, minFilter
);
773 glTexEnvfv(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, textureEnvironment
);
776 static void Draw(void)
778 glClear(GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT
);
786 glDisable(GL_LIGHTING
);
787 glDisable(GL_TEXTURE_2D
);
792 glEnable(GL_LIGHTING
);
794 glColor3f(1.0, 0.5, 0.2);
796 glEnable(GL_TEXTURE_2D
);
799 glTranslatef(0.0, 0.0, zTranslate
);
800 glRotatef(xRotation
, 1, 0, 0);
801 glRotatef(yRotation
, 0, 1, 0);
802 glCallList(genericObject
);
809 static void Reshape(int width
, int height
)
814 glViewport( 0, 0, width
, height
); /*new*/
815 glMatrixMode(GL_PROJECTION
);
817 glFrustum(-0.2, 0.2, -0.2, 0.2, 0.15, 9.0);
818 glMatrixMode(GL_MODELVIEW
);
821 static void Idle(void)
823 static double t0
= -1.;
825 t
= glutGet(GLUT_ELAPSED_TIME
) / 1000.;
831 xRotation
+= .75*60.*dt
;
832 yRotation
+= .375*60.*dt
;
836 static void Key2(int key
, int x
, int y
)
842 autoRotate
= GL_FALSE
;
847 autoRotate
= GL_FALSE
;
852 autoRotate
= GL_FALSE
;
857 autoRotate
= GL_FALSE
;
866 static void Key(unsigned char key
, int x
, int y
)
871 /* free(image->data);*/
875 autoRotate
= !autoRotate
;
884 if (genericObject
== cube
) {
885 genericObject
= cylinder
;
887 else if (genericObject
== cylinder
) {
888 genericObject
= torus
;
891 genericObject
= cube
;
896 textureEnvironment
= decal
;
900 textureEnvironment
= modulate
;
908 isFogged
= !isFogged
;
912 doTexture
= !doTexture
;
916 magFilter
= nnearest
;
924 minFilter
= nnearest
;
932 minFilter
= nearest_mipmap_nearest
;
936 minFilter
= nearest_mipmap_linear
;
940 minFilter
= linear_mipmap_nearest
;
944 minFilter
= linear_mipmap_linear
;
953 static GLenum
Args(int argc
, char **argv
)
957 doubleBuffer
= GL_TRUE
;
959 for (i
= 1; i
< argc
; i
++) {
960 if (strcmp(argv
[i
], "-sb") == 0) {
961 doubleBuffer
= GL_FALSE
;
962 } else if (strcmp(argv
[i
], "-db") == 0) {
963 doubleBuffer
= GL_TRUE
;
964 } else if (strcmp(argv
[i
], "-f") == 0) {
965 if (i
+1 >= argc
|| argv
[i
+1][0] == '-') {
966 printf("-f (No file name).\n");
969 imageFileName
= argv
[++i
];
972 printf("%s (Bad option).\n", argv
[i
]);
979 int main(int argc
, char **argv
)
983 glutInit(&argc
, argv
);
985 if (Args(argc
, argv
) == GL_FALSE
) {
989 if (imageFileName
== 0) {
990 printf("No image file.\n");
994 glutInitWindowPosition(0, 0); glutInitWindowSize( W
, H
);
996 type
= GLUT_RGB
| GLUT_DEPTH
;
997 type
|= (doubleBuffer
) ? GLUT_DOUBLE
: GLUT_SINGLE
;
998 glutInitDisplayMode(type
);
1000 if (glutCreateWindow("Texture Test") == GL_FALSE
) {
1006 glutReshapeFunc(Reshape
);
1007 glutKeyboardFunc(Key
);
1008 glutSpecialFunc(Key2
);
1009 glutDisplayFunc(Draw
);