1 /* $Id: spectex.c,v 1.2 2002/04/22 16:03:37 brianp 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
26 static GLUquadricObj
*Quadric
;
28 static GLfloat LightPos
[4] = {10.0, 10.0, 10.0, 1.0};
29 static GLfloat Delta
= 1.0;
30 static GLint Mode
= 0;
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};
39 static void Idle( void )
44 else if (LightPos
[0]<-15.0)
51 static void Display( void )
53 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
55 glLightfv(GL_LIGHT0
, GL_POSITION
, LightPos
);
58 glRotatef(90.0, 1.0, 0.0, 0.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 */
66 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SINGLE_COLOR
);
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 */
76 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SINGLE_COLOR
);
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 */
86 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SINGLE_COLOR
);
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 */
96 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL
, GL_SINGLE_COLOR
);
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 */
106 glDepthFunc(GL_LESS
);
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
);
126 static void Reshape( int width
, int height
)
128 glViewport( 0, 0, width
, height
);
129 glMatrixMode( GL_PROJECTION
);
131 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
132 glMatrixMode( GL_MODELVIEW
);
134 glTranslatef( 0.0, 0.0, -12.0 );
138 static void Key( unsigned char key
, int x
, int y
)
151 static void SpecialKey( int key
, int x
, int y
)
165 static void Init( void )
168 GLubyte texImage
[64][64][3];
170 glEnable(GL_LIGHTING
);
172 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE
, 0);
173 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, Black
);
175 glMaterialfv(GL_FRONT
, GL_DIFFUSE
, White
);
176 glMaterialfv(GL_FRONT
, GL_SPECULAR
, White
);
177 glMaterialf(GL_FRONT
, GL_SHININESS
, 20.0);
179 /* Actually, these are set again later */
180 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, White
);
181 glLightfv(GL_LIGHT0
, GL_SPECULAR
, White
);
183 Quadric
= gluNewQuadric();
184 gluQuadricTexture( Quadric
, GL_TRUE
);
186 Sphere
= glGenLists(1);
187 glNewList( Sphere
, GL_COMPILE
);
188 gluSphere( Quadric
, 1.0, 24, 24 );
191 glEnable(GL_DEPTH_TEST
);
192 glEnable(GL_CULL_FACE
);
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;
203 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
204 glTexImage2D( GL_TEXTURE_2D
,
209 GL_RGB
, GL_UNSIGNED_BYTE
,
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
);
215 glBlendFunc(GL_ONE
, GL_ONE
);
219 static void ModeMenu(int entry
)
227 int main( int argc
, char *argv
[] )
230 glutInit( &argc
, argv
);
231 glutInitWindowPosition( 0, 0 );
232 glutInitWindowSize( 300, 300 );
234 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
236 glutCreateWindow( "spectex" );
240 glutReshapeFunc( Reshape
);
241 glutKeyboardFunc( Key
);
242 glutSpecialFunc( SpecialKey
);
243 glutDisplayFunc( Display
);
244 glutIdleFunc( Idle
);
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);
254 glutAddMenuEntry("Quit", 99);
255 glutAttachMenu(GLUT_RIGHT_BUTTON
);