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
= 1.0;
29 static GLint Mode
= 0;
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};
38 static void Idle( void )
43 else if (LightPos
[0]<-15.0)
50 static void Display( void )
52 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
54 glLightfv(GL_LIGHT0
, GL_POSITION
, LightPos
);
57 glRotatef(90.0, 1.0, 0.0, 0.0);
60 /* Typical method: diffuse + specular + texture */
61 glEnable(GL_TEXTURE_2D
);
62 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, White
); /* enable diffuse */
63 glLightfv(GL_LIGHT0
, GL_SPECULAR
, White
); /* enable specular */
65 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SINGLE_COLOR
);
70 /* just specular highlight */
71 glDisable(GL_TEXTURE_2D
);
72 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, Black
); /* disable diffuse */
73 glLightfv(GL_LIGHT0
, GL_SPECULAR
, White
); /* enable specular */
75 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SINGLE_COLOR
);
80 /* diffuse textured */
81 glEnable(GL_TEXTURE_2D
);
82 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, White
); /* enable diffuse */
83 glLightfv(GL_LIGHT0
, GL_SPECULAR
, Black
); /* disable specular */
85 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SINGLE_COLOR
);
90 /* 2-pass: diffuse textured then add specular highlight*/
91 glEnable(GL_TEXTURE_2D
);
92 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, White
); /* enable diffuse */
93 glLightfv(GL_LIGHT0
, GL_SPECULAR
, Black
); /* disable specular */
95 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SINGLE_COLOR
);
98 /* specular highlight */
99 glDepthFunc(GL_EQUAL
); /* redraw same pixels */
100 glDisable(GL_TEXTURE_2D
);
101 glEnable(GL_BLEND
); /* add */
102 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, Black
); /* disable diffuse */
103 glLightfv(GL_LIGHT0
, GL_SPECULAR
, White
); /* enable specular */
105 glDepthFunc(GL_LESS
);
109 /* OpenGL 1.2's separate diffuse and specular color */
110 glEnable(GL_TEXTURE_2D
);
111 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, White
); /* enable diffuse */
112 glLightfv(GL_LIGHT0
, GL_SPECULAR
, White
); /* enable specular */
113 #ifdef GL_VERSION_1_2
114 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SEPARATE_SPECULAR_COLOR
);
125 static void Reshape( int width
, int height
)
127 glViewport( 0, 0, width
, height
);
128 glMatrixMode( GL_PROJECTION
);
130 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
131 glMatrixMode( GL_MODELVIEW
);
133 glTranslatef( 0.0, 0.0, -12.0 );
137 static void Key( unsigned char key
, int x
, int y
)
150 static void SpecialKey( int key
, int x
, int y
)
164 static void Init( void )
167 GLubyte texImage
[64][64][3];
169 glEnable(GL_LIGHTING
);
171 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE
, 0);
172 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, Black
);
174 glMaterialfv(GL_FRONT
, GL_DIFFUSE
, White
);
175 glMaterialfv(GL_FRONT
, GL_SPECULAR
, White
);
176 glMaterialf(GL_FRONT
, GL_SHININESS
, 20.0);
178 /* Actually, these are set again later */
179 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, White
);
180 glLightfv(GL_LIGHT0
, GL_SPECULAR
, White
);
182 Quadric
= gluNewQuadric();
183 gluQuadricTexture( Quadric
, GL_TRUE
);
185 Sphere
= glGenLists(1);
186 glNewList( Sphere
, GL_COMPILE
);
187 gluSphere( Quadric
, 1.0, 24, 24 );
190 glEnable(GL_DEPTH_TEST
);
191 glEnable(GL_CULL_FACE
);
195 int k
= ((i
>>3)&1) ^ ((j
>>3)&1);
196 texImage
[i
][j
][0] = 255*k
;
197 texImage
[i
][j
][1] = 255*(1-k
);
198 texImage
[i
][j
][2] = 0;
202 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
203 glTexImage2D( GL_TEXTURE_2D
,
208 GL_RGB
, GL_UNSIGNED_BYTE
,
210 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
211 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
212 glEnable(GL_TEXTURE_2D
);
214 glBlendFunc(GL_ONE
, GL_ONE
);
218 static void ModeMenu(int entry
)
226 int main( int argc
, char *argv
[] )
229 glutInit( &argc
, argv
);
230 glutInitWindowPosition( 0, 0 );
231 glutInitWindowSize( 300, 300 );
233 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
235 glutCreateWindow( "spectex" );
239 glutReshapeFunc( Reshape
);
240 glutKeyboardFunc( Key
);
241 glutSpecialFunc( SpecialKey
);
242 glutDisplayFunc( Display
);
243 glutIdleFunc( Idle
);
245 glutCreateMenu( ModeMenu
);
246 glutAddMenuEntry("1-pass lighting + texturing", 0);
247 glutAddMenuEntry("specular lighting", 1);
248 glutAddMenuEntry("diffuse lighting + texturing", 2);
249 glutAddMenuEntry("2-pass lighting + texturing", 3);
250 #ifdef GL_VERSION_1_2
251 glutAddMenuEntry("OpenGL 1.2 separate specular", 4);
253 glutAddMenuEntry("Quit", 99);
254 glutAttachMenu(GLUT_RIGHT_BUTTON
);