1 /* $Id: spectex.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
4 * GLUT demonstration of texturing with specular highlights.
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
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.
17 * Brian Paul February 1997
23 * Revision 1.1 1999/08/19 00:55:40 jtg
26 * Revision 3.2 1999/03/28 18:22:05 brianp
29 * Revision 3.1 1998/02/14 18:47:48 brianp
30 * added OpenGL 1.2 separate specular interpolation support
32 * Revision 3.0 1998/02/14 18:42:29 brianp
44 static GLUquadricObj
*Quadric
;
46 static GLfloat LightPos
[4] = {10.0, 10.0, 10.0, 1.0};
47 static GLfloat Delta
= 1.0;
48 static GLint Mode
= 0;
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};
57 static void Idle( void )
62 else if (LightPos
[0]<-15.0)
69 static void Display( void )
71 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
73 glLightfv(GL_LIGHT0
, GL_POSITION
, LightPos
);
76 glRotatef(90.0, 1.0, 0.0, 0.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 */
84 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SINGLE_COLOR
);
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 */
94 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SINGLE_COLOR
);
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
);
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
);
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 */
124 glDepthFunc(GL_LESS
);
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
);
144 static void Reshape( int width
, int height
)
146 glViewport( 0, 0, width
, height
);
147 glMatrixMode( GL_PROJECTION
);
149 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
150 glMatrixMode( GL_MODELVIEW
);
152 glTranslatef( 0.0, 0.0, -12.0 );
156 static void Key( unsigned char key
, int x
, int y
)
169 static void SpecialKey( int key
, int x
, int y
)
183 static void Init( void )
186 GLubyte texImage
[64][64][3];
188 glEnable(GL_LIGHTING
);
190 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE
, 0);
191 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, Black
);
193 glMaterialfv(GL_FRONT
, GL_DIFFUSE
, White
);
194 glMaterialfv(GL_FRONT
, GL_SPECULAR
, White
);
195 glMaterialf(GL_FRONT
, GL_SHININESS
, 20.0);
197 /* Actually, these are set again later */
198 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, White
);
199 glLightfv(GL_LIGHT0
, GL_SPECULAR
, White
);
201 Quadric
= gluNewQuadric();
202 gluQuadricTexture( Quadric
, GL_TRUE
);
204 Sphere
= glGenLists(1);
205 glNewList( Sphere
, GL_COMPILE
);
206 gluSphere( Quadric
, 1.0, 24, 24 );
209 glEnable(GL_DEPTH_TEST
);
210 glEnable(GL_CULL_FACE
);
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;
221 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
222 glTexImage2D( GL_TEXTURE_2D
,
227 GL_RGB
, GL_UNSIGNED_BYTE
,
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
);
233 glBlendFunc(GL_ONE
, GL_ONE
);
237 static void ModeMenu(int entry
)
245 int main( int argc
, char *argv
[] )
248 glutInit( &argc
, argv
);
249 glutInitWindowPosition( 0, 0 );
250 glutInitWindowSize( 300, 300 );
252 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
254 glutCreateWindow( "spectex" );
258 glutReshapeFunc( Reshape
);
259 glutKeyboardFunc( Key
);
260 glutSpecialFunc( SpecialKey
);
261 glutDisplayFunc( Display
);
262 glutIdleFunc( Idle
);
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);
272 glutAddMenuEntry("Quit", 99);
273 glutAttachMenu(GLUT_RIGHT_BUTTON
);