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