1 /* $Id: gloss.c,v 1.3 1999/10/26 17:08:31 brianp Exp $ */
4 * Specular reflection demo. The specular highlight is modulated by
5 * a sphere-mapped texture. The result is a high-gloss surface.
6 * NOTE: you really need hardware acceleration for this.
7 * Also note, this technique can't be implemented with multi-texture
8 * and separate specular color interpolation because there's no way
9 * to indicate that the second texture unit (the reflection map)
10 * should modulate the specular color and not the base color.
11 * A future multi-texture extension could fix that.
13 * Command line options:
14 * -info print GL implementation information
17 * Brian Paul October 22, 1999 This program is in the public domain.
27 #include "../util/readtex.c" /* I know, this is a hack. */
29 #define SPECULAR_TEXTURE_FILE "../images/reflect.rgb"
30 #define BASE_TEXTURE_FILE "../images/tile.rgb"
33 #define DO_SPEC_TEXTURE 1
38 static GLuint CylinderObj
= 0;
39 static GLuint TeapotObj
= 0;
40 static GLuint Object
= 0;
41 static GLboolean Animate
= GL_TRUE
;
43 static GLfloat Xrot
= 0.0, Yrot
= 0.0, Zrot
= 0.0;
44 static GLfloat DXrot
= 1.0, DYrot
= 2.5;
46 static GLfloat Black
[4] = { 0, 0, 0, 0 };
47 static GLfloat White
[4] = { 1, 1, 1, 1 };
48 static GLfloat Diffuse
[4] = { .3, .3, 1.0, 1.0 }; /* blue */
49 static GLfloat Shininess
= 15;
51 static GLuint BaseTexture
, SpecularTexture
;
52 static GLboolean DoSpecTexture
= GL_TRUE
;
54 /* performance info */
56 static GLint Frames
= 0;
61 static void Idle( void )
71 static void Display( void )
73 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
76 glRotatef(Xrot
, 1.0, 0.0, 0.0);
77 glRotatef(Yrot
, 0.0, 1.0, 0.0);
78 glRotatef(Zrot
, 0.0, 0.0, 1.0);
80 /* First pass: diffuse lighting with base texture */
81 glMaterialfv(GL_FRONT
, GL_DIFFUSE
, Diffuse
);
82 glMaterialfv(GL_FRONT
, GL_SPECULAR
, Black
);
83 glEnable(GL_TEXTURE_2D
);
84 glBindTexture(GL_TEXTURE_2D
, BaseTexture
);
87 /* Second pass: specular lighting with reflection texture */
88 glBlendFunc(GL_ONE
, GL_ONE
); /* add */
90 glDepthFunc(GL_LEQUAL
);
91 glMaterialfv(GL_FRONT
, GL_DIFFUSE
, Black
);
92 glMaterialfv(GL_FRONT
, GL_SPECULAR
, White
);
94 glBindTexture(GL_TEXTURE_2D
, SpecularTexture
);
95 glEnable(GL_TEXTURE_GEN_S
);
96 glEnable(GL_TEXTURE_GEN_T
);
99 glDisable(GL_TEXTURE_2D
);
102 glDisable(GL_TEXTURE_GEN_S
);
103 glDisable(GL_TEXTURE_GEN_T
);
111 GLint t
= glutGet(GLUT_ELAPSED_TIME
);
113 if (t
- T0
>= 5000) {
114 GLfloat seconds
= (t
- T0
) / 1000.0;
115 GLfloat fps
= Frames
/ seconds
;
116 printf("%d frames in %g seconds = %g FPS\n", Frames
, seconds
, fps
);
124 static void Reshape( int width
, int height
)
127 GLfloat w
= h
* width
/ height
;
128 glViewport( 0, 0, width
, height
);
129 glMatrixMode( GL_PROJECTION
);
131 glFrustum( -w
, w
, -h
, h
, 150.0, 500.0 );
132 glMatrixMode( GL_MODELVIEW
);
134 glTranslatef( 0.0, 0.0, -380.0 );
138 static void ToggleAnimate(void)
142 glutIdleFunc( Idle
);
143 T0
= glutGet(GLUT_ELAPSED_TIME
);
147 glutIdleFunc( NULL
);
152 static void ModeMenu(int entry
)
154 if (entry
==ANIMATE
) {
157 else if (entry
==DO_SPEC_TEXTURE
) {
158 DoSpecTexture
= !DoSpecTexture
;
160 else if (entry
==OBJECT
) {
161 if (Object
== TeapotObj
)
162 Object
= CylinderObj
;
166 else if (entry
==QUIT
) {
173 static void Key( unsigned char key
, int x
, int y
)
182 glMaterialf(GL_FRONT
, GL_SHININESS
, Shininess
);
183 printf("Shininess = %g\n", Shininess
);
187 if (Shininess
> 128.0)
189 glMaterialf(GL_FRONT
, GL_SHININESS
, Shininess
);
190 printf("Shininess = %g\n", Shininess
);
203 static void SpecialKey( int key
, int x
, int y
)
227 static void Init( int argc
, char *argv
[] )
229 /* Cylinder object */
231 static GLfloat height
= 100.0;
232 static GLfloat radius
= 40.0;
233 static GLint slices
= 24; /* pie slices around Z axis */
234 static GLint stacks
= 10; /* subdivisions along length of cylinder */
235 static GLint rings
= 4; /* rings in the end disks */
236 GLUquadricObj
*q
= gluNewQuadric();
238 gluQuadricTexture(q
, GL_TRUE
);
240 CylinderObj
= glGenLists(1);
241 glNewList(CylinderObj
, GL_COMPILE
);
244 glTranslatef(0.0, 0.0, -0.5 * height
);
246 glMatrixMode(GL_TEXTURE
);
248 glScalef(8.0, 4.0, 2.0);
249 glMatrixMode(GL_MODELVIEW
);
252 gluQuadricNormals(q
, GL_SMOOTH
);
253 gluQuadricTexture(q
, GL_TRUE
);
254 gluCylinder(q
, radius
, radius
, height
, slices
, stacks
);
257 glMatrixMode(GL_TEXTURE
);
259 glScalef(3.0, 3.0, 1.0);
260 glMatrixMode(GL_MODELVIEW
);
262 glTranslatef(0.0, 0.0, height
);
263 gluDisk(q
, 0.0, radius
, slices
, rings
);
266 glTranslatef(0.0, 0.0, -height
);
267 gluQuadricOrientation(q
, GLU_INSIDE
);
268 gluDisk(q
, 0.0, radius
, slices
, rings
);
272 glMatrixMode(GL_TEXTURE
);
274 glMatrixMode(GL_MODELVIEW
);
282 TeapotObj
= glGenLists(1);
283 glNewList(TeapotObj
, GL_COMPILE
);
286 glutSolidTeapot(40.0);
292 /* show cylinder by default */
293 Object
= CylinderObj
;
297 glEnable(GL_LIGHTING
);
299 GLfloat pos
[4] = { 3, 3, 3, 1 };
300 glLightfv(GL_LIGHT0
, GL_AMBIENT
, Black
);
301 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, White
);
302 glLightfv(GL_LIGHT0
, GL_SPECULAR
, White
);
303 glLightfv(GL_LIGHT0
, GL_POSITION
, pos
);
305 glMaterialfv(GL_FRONT
, GL_AMBIENT
, Black
);
306 glMaterialf(GL_FRONT
, GL_SHININESS
, Shininess
);
307 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER
, 1);
311 glGenTextures(1, &BaseTexture
);
312 glBindTexture(GL_TEXTURE_2D
, BaseTexture
);
313 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
314 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
315 if (!LoadRGBMipmaps(BASE_TEXTURE_FILE
, GL_RGB
)) {
316 printf("Error: couldn't load texture image file %s\n", BASE_TEXTURE_FILE
);
320 /* Specular texture */
321 glGenTextures(1, &SpecularTexture
);
322 glBindTexture(GL_TEXTURE_2D
, SpecularTexture
);
323 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
324 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
325 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_SPHERE_MAP
);
326 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_SPHERE_MAP
);
327 if (!LoadRGBMipmaps(SPECULAR_TEXTURE_FILE
, GL_RGB
)) {
328 printf("Error: couldn't load texture image file %s\n", SPECULAR_TEXTURE_FILE
);
333 glEnable(GL_CULL_FACE
);
334 glEnable(GL_TEXTURE_2D
);
335 glEnable(GL_DEPTH_TEST
);
336 glEnable(GL_NORMALIZE
);
338 if (argc
> 1 && strcmp(argv
[1], "-info")==0) {
339 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
340 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION
));
341 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR
));
342 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS
));
347 int main( int argc
, char *argv
[] )
349 glutInit( &argc
, argv
);
350 glutInitWindowSize( 500, 500 );
352 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
354 glutCreateWindow(argv
[0] );
358 glutReshapeFunc( Reshape
);
359 glutKeyboardFunc( Key
);
360 glutSpecialFunc( SpecialKey
);
361 glutDisplayFunc( Display
);
362 glutIdleFunc( Idle
);
364 glutCreateMenu(ModeMenu
);
365 glutAddMenuEntry("Toggle Highlight", DO_SPEC_TEXTURE
);
366 glutAddMenuEntry("Toggle Object", OBJECT
);
367 glutAddMenuEntry("Toggle Animate", ANIMATE
);
368 glutAddMenuEntry("Quit", QUIT
);
369 glutAttachMenu(GLUT_RIGHT_BUTTON
);