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
[] )
243 glutInit( &argc
, argv
);
244 glutInitWindowPosition( 0, 0 );
245 glutInitWindowSize( 300, 300 );
247 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
249 glutCreateWindow( "spectex" );
253 glutReshapeFunc( Reshape
);
254 glutKeyboardFunc( Key
);
255 glutSpecialFunc( SpecialKey
);
256 glutDisplayFunc( Display
);
257 glutIdleFunc( Idle
);
259 glutCreateMenu( ModeMenu
);
260 glutAddMenuEntry("1-pass lighting + texturing", 0);
261 glutAddMenuEntry("specular lighting", 1);
262 glutAddMenuEntry("diffuse lighting + texturing", 2);
263 glutAddMenuEntry("2-pass lighting + texturing", 3);
264 #ifdef GL_VERSION_1_2
265 glutAddMenuEntry("OpenGL 1.2 separate specular", 4);
267 glutAddMenuEntry("Quit", 99);
268 glutAttachMenu(GLUT_RIGHT_BUTTON
);