3
* GLUT demonstration of texturing with specular highlights.
5
* When drawing a lit, textured surface one usually wants the specular
6
* highlight to override the texture colors. However, OpenGL applies
7
* texturing after lighting so the specular highlight is modulated by
10
* The solution here shown here is a two-pass algorithm:
11
* 1. Draw the textured surface without specular lighting.
12
* 2. Enable blending to add the next pass:
13
* 3. Redraw the surface with a matte white material and only the
14
* specular components of light sources enabled.
16
* Brian Paul February 1997
25
static GLUquadricObj *Quadric;
27
static GLfloat LightPos[4] = {10.0, 10.0, 10.0, 1.0};
28
static GLfloat Delta = 20.0;
29
static GLint Mode = 4;
31
/*static GLfloat Blue[4] = {0.0, 0.0, 1.0, 1.0};*/
32
/*static GLfloat Gray[4] = {0.5, 0.5, 0.5, 1.0};*/
33
static GLfloat Black[4] = {0.0, 0.0, 0.0, 1.0};
34
static GLfloat White[4] = {1.0, 1.0, 1.0, 1.0};
36
static GLboolean smooth = 1;
41
static double t0 = -1.;
42
double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;;
47
LightPos[0] += Delta * dt;
48
if (LightPos[0]>15.0 || LightPos[0]<-15.0)
55
static void Display( void )
57
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
59
glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
62
glRotatef(90.0, 1.0, 0.0, 0.0);
65
/* Typical method: diffuse + specular + texture */
66
glEnable(GL_TEXTURE_2D);
67
glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
68
glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
70
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
75
/* just specular highlight */
76
glDisable(GL_TEXTURE_2D);
77
glLightfv(GL_LIGHT0, GL_DIFFUSE, Black); /* disable diffuse */
78
glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
80
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
85
/* diffuse textured */
86
glEnable(GL_TEXTURE_2D);
87
glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
88
glLightfv(GL_LIGHT0, GL_SPECULAR, Black); /* disable specular */
90
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
95
/* 2-pass: diffuse textured then add specular highlight*/
96
glEnable(GL_TEXTURE_2D);
97
glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
98
glLightfv(GL_LIGHT0, GL_SPECULAR, Black); /* disable specular */
100
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
103
/* specular highlight */
104
glDepthFunc(GL_EQUAL); /* redraw same pixels */
105
glDisable(GL_TEXTURE_2D);
106
glEnable(GL_BLEND); /* add */
107
glLightfv(GL_LIGHT0, GL_DIFFUSE, Black); /* disable diffuse */
108
glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
110
glDepthFunc(GL_LESS);
114
/* OpenGL 1.2's separate diffuse and specular color */
115
glEnable(GL_TEXTURE_2D);
116
glLightfv(GL_LIGHT0, GL_DIFFUSE, White); /* enable diffuse */
117
glLightfv(GL_LIGHT0, GL_SPECULAR, White); /* enable specular */
118
#ifdef GL_VERSION_1_2
119
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
130
static void Reshape( int width, int height )
132
glViewport( 0, 0, width, height );
133
glMatrixMode( GL_PROJECTION );
135
glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
136
glMatrixMode( GL_MODELVIEW );
138
glTranslatef( 0.0, 0.0, -12.0 );
142
static void Key( unsigned char key, int x, int y )
153
glShadeModel(GL_SMOOTH);
155
glShadeModel(GL_FLAT);
162
static void SpecialKey( int key, int x, int y )
176
static void Init( void )
179
GLubyte texImage[64][64][3];
181
glEnable(GL_LIGHTING);
183
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
184
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Black);
186
glShadeModel(GL_SMOOTH);
188
glMaterialfv(GL_FRONT, GL_DIFFUSE, White);
189
glMaterialfv(GL_FRONT, GL_SPECULAR, White);
190
glMaterialf(GL_FRONT, GL_SHININESS, 20.0);
192
/* Actually, these are set again later */
193
glLightfv(GL_LIGHT0, GL_DIFFUSE, White);
194
glLightfv(GL_LIGHT0, GL_SPECULAR, White);
196
Quadric = gluNewQuadric();
197
gluQuadricTexture( Quadric, GL_TRUE );
199
Sphere= glGenLists(1);
200
glNewList( Sphere, GL_COMPILE );
201
gluSphere( Quadric, 1.0, 24, 24 );
204
glEnable(GL_DEPTH_TEST);
205
glEnable(GL_CULL_FACE);
209
int k = ((i>>3)&1) ^ ((j>>3)&1);
210
texImage[i][j][0] = 255*k;
211
texImage[i][j][1] = 255*(1-k);
212
texImage[i][j][2] = 0;
216
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
217
glTexImage2D( GL_TEXTURE_2D,
222
GL_RGB, GL_UNSIGNED_BYTE,
224
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
225
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
226
glEnable(GL_TEXTURE_2D);
228
glBlendFunc(GL_ONE, GL_ONE);
232
static void ModeMenu(int entry)
240
int main( int argc, char *argv[] )
242
glutInitWindowSize( 300, 300 );
243
glutInit( &argc, argv );
244
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
245
glutCreateWindow( "spectex" );
249
glutReshapeFunc( Reshape );
250
glutKeyboardFunc( Key );
251
glutSpecialFunc( SpecialKey );
252
glutDisplayFunc( Display );
253
glutIdleFunc( Idle );
255
glutCreateMenu( ModeMenu );
256
glutAddMenuEntry("1-pass lighting + texturing", 0);
257
glutAddMenuEntry("specular lighting", 1);
258
glutAddMenuEntry("diffuse lighting + texturing", 2);
259
glutAddMenuEntry("2-pass lighting + texturing", 3);
260
#ifdef GL_VERSION_1_2
261
glutAddMenuEntry("OpenGL 1.2 separate specular", 4);
263
glutAddMenuEntry("Quit", 99);
264
glutAttachMenu(GLUT_RIGHT_BUTTON);