1 /* $Id: reflect.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
4 * Demo of a reflective, texture-mapped surface with OpenGL.
5 * Brian Paul August 14, 1995 This file is in the public domain.
7 * Hardware texture mapping is highly recommended!
10 * 1. Render the reflective object (a polygon) from the normal viewpoint,
11 * setting the stencil planes = 1.
12 * 2. Render the scene from a special viewpoint: the viewpoint which
13 * is on the opposite side of the reflective plane. Only draw where
14 * stencil = 1. This draws the objects in the reflective surface.
15 * 3. Render the scene from the original viewpoint. This draws the
16 * objects in the normal fashion. Use blending when drawing
17 * the reflective, textured surface.
19 * This is a very crude demo. It could be much better.
23 * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
25 * August 1996 - A few optimizations by Brian
29 * April, 1997 - Added Mark Kilgard's changes.
34 * Revision 1.1 1999/08/19 00:55:40 jtg
37 * Revision 3.4 1999/03/28 18:22:05 brianp
40 * Revision 3.3 1998/11/22 02:54:29 brianp
41 * only draw one stack for gluCylinders
43 * Revision 3.2 1998/11/19 02:53:48 brianp
44 * changed texture image and background color
46 * Revision 3.1 1998/11/05 04:34:04 brianp
47 * moved image files to ../images/ directory
49 * Revision 3.0 1998/02/14 18:42:29 brianp
58 /* OK, without hardware support this is overkill. */
66 #include "../util/readtex.c" /* a hack, I know */
69 #define DEG2RAD (3.14159/180.0)
72 #define TABLE_TEXTURE "../images/tile.rgb"
74 static int ImgWidth
, ImgHeight
;
75 static GLenum ImgFormat
;
76 static GLubyte
*Image
= NULL
;
80 static GLint table_list
;
81 static GLint objects_list
[MAX_OBJECTS
];
84 static GLfloat xrot
, yrot
;
89 static void make_table( void )
91 static GLfloat table_mat
[] = { 1.0, 1.0, 1.0, 0.6 };
92 static GLfloat gray
[] = { 0.4, 0.4, 0.4, 1.0 };
94 table_list
= glGenLists(1);
95 glNewList( table_list
, GL_COMPILE
);
97 /* load table's texture */
98 glMaterialfv( GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, table_mat
);
99 /* glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
100 glMaterialfv( GL_FRONT
, GL_DIFFUSE
, table_mat
);
101 glMaterialfv( GL_FRONT
, GL_AMBIENT
, gray
);
103 /* draw textured square for the table */
105 glScalef( 4.0, 4.0, 4.0 );
106 glBegin( GL_POLYGON
);
107 glNormal3f( 0.0, 1.0, 0.0 );
108 glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 0.0, 1.0 );
109 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
110 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, -1.0 );
111 glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 0.0, -1.0 );
115 glDisable( GL_TEXTURE_2D
);
121 static void make_objects( void )
125 static GLfloat cyan
[] = { 0.0, 1.0, 1.0, 1.0 };
126 static GLfloat green
[] = { 0.2, 1.0, 0.2, 1.0 };
127 static GLfloat black
[] = { 0.0, 0.0, 0.0, 0.0 };
130 gluQuadricDrawStyle( q
, GLU_FILL
);
131 gluQuadricNormals( q
, GLU_SMOOTH
);
133 objects_list
[0] = glGenLists(1);
134 glNewList( objects_list
[0], GL_COMPILE
);
135 glMaterialfv( GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, cyan
);
136 glMaterialfv( GL_FRONT
, GL_EMISSION
, black
);
137 gluCylinder( q
, 0.5, 0.5, 1.0, 15, 1 );
140 objects_list
[1] = glGenLists(1);
141 glNewList( objects_list
[1], GL_COMPILE
);
142 glMaterialfv( GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, green
);
143 glMaterialfv( GL_FRONT
, GL_EMISSION
, black
);
144 gluCylinder( q
, 1.5, 0.0, 2.5, 15, 1 );
149 static GLfloat light_pos
[] = { 0.0, 20.0, 0.0, 1.0 };
151 static void init( void )
159 Image
= LoadRGBImage( TABLE_TEXTURE
, &ImgWidth
, &ImgHeight
, &ImgFormat
);
161 printf("Couldn't read %s\n", TABLE_TEXTURE
);
165 gluBuild2DMipmaps(GL_TEXTURE_2D
, 3, ImgWidth
, ImgHeight
,
166 ImgFormat
, GL_UNSIGNED_BYTE
, Image
);
168 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
169 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
170 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
171 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
180 glEnable( GL_CULL_FACE
);
183 glShadeModel( GL_FLAT
);
185 glEnable( GL_LIGHT0
);
186 glEnable( GL_LIGHTING
);
188 glClearColor( 0.5, 0.5, 0.9, 1.0 );
190 glEnable( GL_NORMALIZE
);
195 static void reshape(int w
, int h
)
197 GLfloat aspect
= (float) w
/ (float) h
;
199 glViewport(0, 0, w
, h
);
200 glMatrixMode(GL_PROJECTION
);
202 glFrustum( -aspect
, aspect
, -1.0, 1.0, 4.0, 300.0 );
203 glMatrixMode(GL_MODELVIEW
);
209 static void draw_objects( GLfloat eyex
, GLfloat eyey
, GLfloat eyez
)
219 glTranslatef( 1.0, 1.5, 0.0 );
220 glRotatef( spin
, 1.0, 0.5, 0.0 );
221 glRotatef( 0.5*spin
, 0.0, 0.5, 1.0 );
222 glCallList( objects_list
[0] );
226 glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin
) ), 0.0 );
227 glRotatef( 0.5*spin
, 0.0, 0.5, 1.0 );
228 glRotatef( spin
, 1.0, 0.5, 0.0 );
229 glScalef( 0.5, 0.5, 0.5 );
230 glCallList( objects_list
[1] );
237 glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin
) ), 0.0 );
238 glRotatef( 0.5*spin
, 0.0, 0.5, 1.0 );
239 glRotatef( spin
, 1.0, 0.5, 0.0 );
240 glScalef( 0.5, 0.5, 0.5 );
241 glCallList( objects_list
[1] );
245 glTranslatef( 1.0, 1.5, 0.0 );
246 glRotatef( spin
, 1.0, 0.5, 0.0 );
247 glRotatef( 0.5*spin
, 0.0, 0.5, 1.0 );
248 glCallList( objects_list
[0] );
256 static void draw_table( void )
258 glCallList( table_list
);
263 static void draw_scene( void )
266 GLfloat eyex
, eyey
, eyez
;
268 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
);
271 eyex
= dist
* cos(yrot
*DEG2RAD
) * cos(xrot
*DEG2RAD
);
272 eyez
= dist
* sin(yrot
*DEG2RAD
) * cos(xrot
*DEG2RAD
);
273 eyey
= dist
* sin(xrot
*DEG2RAD
);
277 gluLookAt( eyex
, eyey
, eyez
, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
279 glLightfv( GL_LIGHT0
, GL_POSITION
, light_pos
);
281 /* draw table into stencil planes */
282 glEnable( GL_STENCIL_TEST
);
284 glDisable( GL_DEPTH_TEST
);
286 glStencilFunc( GL_ALWAYS
, 1, 0xffffffff );
287 glStencilOp( GL_REPLACE
, GL_REPLACE
, GL_REPLACE
);
288 glColorMask( GL_FALSE
, GL_FALSE
, GL_FALSE
, GL_FALSE
);
290 glColorMask( GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
);
293 glEnable( GL_DEPTH_TEST
);
297 /* render view from below (reflected viewport) */
298 /* only draw where stencil==1 */
302 glStencilFunc( GL_EQUAL
, 1, 0xffffffff ); /* draw if ==1 */
303 glStencilOp( GL_KEEP
, GL_KEEP
, GL_KEEP
);
304 glScalef( 1.0, -1.0, 1.0 );
306 /* Reposition light in reflected space. */
307 glLightfv(GL_LIGHT0
, GL_POSITION
, light_pos
);
309 draw_objects(eyex
, eyey
, eyez
);
312 /* Restore light's original unreflected position. */
313 glLightfv(GL_LIGHT0
, GL_POSITION
, light_pos
);
316 glDisable( GL_STENCIL_TEST
);
318 glEnable( GL_BLEND
);
319 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
322 glEnable( GL_TEXTURE_2D
);
325 glDisable( GL_TEXTURE_2D
);
326 glDisable( GL_BLEND
);
331 draw_objects(eyex
, eyey
, eyez
);
343 void draw_scene(void)
346 GLfloat eyex
, eyey
, eyez
;
348 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
);
351 eyex
= dist
* cos(yrot
*DEG2RAD
) * cos(xrot
*DEG2RAD
);
352 eyez
= dist
* sin(yrot
*DEG2RAD
) * cos(xrot
*DEG2RAD
);
353 eyey
= dist
* sin(xrot
*DEG2RAD
);
357 gluLookAt( eyex
, eyey
, eyez
, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
368 static void Key( unsigned char key
, int x
, int y
)
377 static void SpecialKey( int key
, int x
, int y
)
385 if ( xrot
> 180 ) xrot
= 180;
391 if ( xrot
< 0 ) xrot
= 0;
406 static void idle( void )
415 int main( int argc
, char *argv
[] )
417 glutInitDisplayMode(GLUT_DOUBLE
| GLUT_RGB
422 glutInitWindowPosition( 0, 0 );
423 glutInitWindowSize(400, 300 );
424 glutCreateWindow(argv
[0]);
425 glutReshapeFunc(reshape
);
426 glutDisplayFunc(draw_scene
);
427 glutKeyboardFunc(Key
);
428 glutSpecialFunc(SpecialKey
);