test for GL 1.2
[mesa.git] / progs / demos / spectex.c
1 /* $Id: spectex.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
2
3 /*
4 * GLUT demonstration of texturing with specular highlights.
5 *
6 * When drawing a lit, textured surface one usually wants the specular
7 * highlight to override the texture colors. However, OpenGL applies
8 * texturing after lighting so the specular highlight is modulated by
9 * the texture.
10 *
11 * The solution here shown here is a two-pass algorithm:
12 * 1. Draw the textured surface without specular lighting.
13 * 2. Enable blending to add the next pass:
14 * 3. Redraw the surface with a matte white material and only the
15 * specular components of light sources enabled.
16 *
17 * Brian Paul February 1997
18 */
19
20
21 /*
22 * $Log: spectex.c,v $
23 * Revision 1.1 1999/08/19 00:55:40 jtg
24 * Initial revision
25 *
26 * Revision 3.2 1999/03/28 18:22:05 brianp
27 * minor clean-up
28 *
29 * Revision 3.1 1998/02/14 18:47:48 brianp
30 * added OpenGL 1.2 separate specular interpolation support
31 *
32 * Revision 3.0 1998/02/14 18:42:29 brianp
33 * initial rev
34 *
35 */
36
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <math.h>
41 #include <GL/glut.h>
42
43
44 static GLUquadricObj *Quadric;
45 static GLuint Sphere;
46 static GLfloat LightPos[4] = {10.0, 10.0, 10.0, 1.0};
47 static GLfloat Delta = 1.0;
48 static GLint Mode = 0;
49
50 /*static GLfloat Blue[4] = {0.0, 0.0, 1.0, 1.0};*/
51 /*static GLfloat Gray[4] = {0.5, 0.5, 0.5, 1.0};*/
52 static GLfloat Black[4] = {0.0, 0.0, 0.0, 1.0};
53 static GLfloat White[4] = {1.0, 1.0, 1.0, 1.0};
54
55
56
57 static void Idle( void )
58 {
59 LightPos[0] += Delta;
60 if (LightPos[0]>15.0)
61 Delta = -1.0;
62 else if (LightPos[0]<-15.0)
63 Delta = 1.0;
64
65 glutPostRedisplay();
66 }
67
68
69 static void Display( void )
70 {
71 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
72
73 glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
74
75 glPushMatrix();
76 glRotatef(90.0, 1.0, 0.0, 0.0);
77
78 if (Mode==0) {
79 /* Typical method: diffuse + specular + texture */
80 glEnable(GL_TEXTURE_2D);
81 glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
82 glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
83 #ifdef GL_VERSION_1_2
84 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
85 #endif
86 glCallList(Sphere);
87 }
88 else if (Mode==1) {
89 /* just specular highlight */
90 glDisable(GL_TEXTURE_2D);
91 glLightfv(GL_LIGHT0, GL_DIFFUSE, Black); /* disable diffuse */
92 glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
93 #ifdef GL_VERSION_1_2
94 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
95 #endif
96 glCallList(Sphere);
97 }
98 else if (Mode==2) {
99 /* diffuse textured */
100 glEnable(GL_TEXTURE_2D);
101 glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
102 glLightfv(GL_LIGHT0, GL_SPECULAR, Black); /* disable specular */
103 #ifdef GL_VERSION_1_2
104 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
105 #endif
106 glCallList(Sphere);
107 }
108 else if (Mode==3) {
109 /* 2-pass: diffuse textured then add specular highlight*/
110 glEnable(GL_TEXTURE_2D);
111 glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
112 glLightfv(GL_LIGHT0, GL_SPECULAR, Black); /* disable specular */
113 #ifdef GL_VERSION_1_2
114 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
115 #endif
116 glCallList(Sphere);
117 /* specular highlight */
118 glDepthFunc(GL_EQUAL); /* redraw same pixels */
119 glDisable(GL_TEXTURE_2D);
120 glEnable(GL_BLEND); /* add */
121 glLightfv(GL_LIGHT0, GL_DIFFUSE, Black); /* disable diffuse */
122 glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
123 glCallList(Sphere);
124 glDepthFunc(GL_LESS);
125 glDisable(GL_BLEND);
126 }
127 else if (Mode==4) {
128 /* OpenGL 1.2's separate diffuse and specular color */
129 glEnable(GL_TEXTURE_2D);
130 glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
131 glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
132 #ifdef GL_VERSION_1_2
133 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
134 #endif
135 glCallList(Sphere);
136 }
137
138 glPopMatrix();
139
140 glutSwapBuffers();
141 }
142
143
144 static void Reshape( int width, int height )
145 {
146 glViewport( 0, 0, width, height );
147 glMatrixMode( GL_PROJECTION );
148 glLoadIdentity();
149 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
150 glMatrixMode( GL_MODELVIEW );
151 glLoadIdentity();
152 glTranslatef( 0.0, 0.0, -12.0 );
153 }
154
155
156 static void Key( unsigned char key, int x, int y )
157 {
158 (void) x;
159 (void) y;
160 switch (key) {
161 case 27:
162 exit(0);
163 break;
164 }
165 glutPostRedisplay();
166 }
167
168
169 static void SpecialKey( int key, int x, int y )
170 {
171 (void) x;
172 (void) y;
173 switch (key) {
174 case GLUT_KEY_UP:
175 break;
176 case GLUT_KEY_DOWN:
177 break;
178 }
179 glutPostRedisplay();
180 }
181
182
183 static void Init( void )
184 {
185 int i, j;
186 GLubyte texImage[64][64][3];
187
188 glEnable(GL_LIGHTING);
189 glEnable(GL_LIGHT0);
190 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
191 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Black);
192
193 glMaterialfv(GL_FRONT, GL_DIFFUSE, White);
194 glMaterialfv(GL_FRONT, GL_SPECULAR, White);
195 glMaterialf(GL_FRONT, GL_SHININESS, 20.0);
196
197 /* Actually, these are set again later */
198 glLightfv(GL_LIGHT0, GL_DIFFUSE, White);
199 glLightfv(GL_LIGHT0, GL_SPECULAR, White);
200
201 Quadric = gluNewQuadric();
202 gluQuadricTexture( Quadric, GL_TRUE );
203
204 Sphere= glGenLists(1);
205 glNewList( Sphere, GL_COMPILE );
206 gluSphere( Quadric, 1.0, 24, 24 );
207 glEndList();
208
209 glEnable(GL_DEPTH_TEST);
210 glEnable(GL_CULL_FACE);
211
212 for (i=0;i<64;i++) {
213 for (j=0;j<64;j++) {
214 int k = ((i>>3)&1) ^ ((j>>3)&1);
215 texImage[i][j][0] = 255*k;
216 texImage[i][j][1] = 255*(1-k);
217 texImage[i][j][2] = 0;
218 }
219 }
220
221 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
222 glTexImage2D( GL_TEXTURE_2D,
223 0,
224 3,
225 64, 64,
226 0,
227 GL_RGB, GL_UNSIGNED_BYTE,
228 texImage );
229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
231 glEnable(GL_TEXTURE_2D);
232
233 glBlendFunc(GL_ONE, GL_ONE);
234 }
235
236
237 static void ModeMenu(int entry)
238 {
239 if (entry==99)
240 exit(0);
241 Mode = entry;
242 }
243
244
245 int main( int argc, char *argv[] )
246 {
247
248 glutInit( &argc, argv );
249 glutInitWindowPosition( 0, 0 );
250 glutInitWindowSize( 300, 300 );
251
252 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
253
254 glutCreateWindow( "spectex" );
255
256 Init();
257
258 glutReshapeFunc( Reshape );
259 glutKeyboardFunc( Key );
260 glutSpecialFunc( SpecialKey );
261 glutDisplayFunc( Display );
262 glutIdleFunc( Idle );
263
264 glutCreateMenu( ModeMenu );
265 glutAddMenuEntry("1-pass lighting + texturing", 0);
266 glutAddMenuEntry("specular lighting", 1);
267 glutAddMenuEntry("diffuse lighting + texturing", 2);
268 glutAddMenuEntry("2-pass lighting + texturing", 3);
269 #ifdef GL_VERSION_1_2
270 glutAddMenuEntry("OpenGL 1.2 separate specular", 4);
271 #endif
272 glutAddMenuEntry("Quit", 99);
273 glutAttachMenu(GLUT_RIGHT_BUTTON);
274
275 glutMainLoop();
276 return 0;
277 }