#include #include #include #include #include #include #include "framebufferObject.h" GLboolean doubleBuffer = GL_TRUE, iconic = GL_FALSE, keepAspect = GL_FALSE; int moving, startx, starty; int useStencil = 1, useClippingPlane = 1; GLdouble bodyWidth = 3.0; float jump = 0.0; GLuint floor_texture; // The coordinates (A,B,C,D) for the plane with equation Ax + By + Cz + D = 0 GLdouble mirror_plane[4] = { 0, 1, 0, 0 }; extern FrameBuffer *mirrorFB; void mouse(int button, int state, int x, int y); void motion(int x, int y); void controlLights(int value); void idle(void); void visible(int vis); GLuint loadTheTexture( void ); void makeDisplayLists(void); void drawBouncingTeapot(void); void drawFloor(void); void InitializeViewingAndLighting( void ); void SetupEyeViewBasedOnUserInput( void ); void SetLightPostionInCurrentCoordinateFrame( void ); void DrawMirrorIntoStencilBuffer( void ); void SetStencilToRenderOnlyWhenEqualToOne( void ); void MultiplyReflectionMatrixOntoStack( void ); void DrawMirrorBlendedWithReflectedScene( void ); void InitializeFramebufferObjects( void ); void SetupReflectionViewBasedOnUserInput( void ); void DrawMirrorWithReflectedTexture( void ); void DrawReflectedSceneIntoBuffer( FrameBuffer *fb ) { fb->BindBuffer(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glPushMatrix(); /* Do standard per-frame OpenGL setup (for view and lights) */ SetupReflectionViewBasedOnUserInput(); SetLightPostionInCurrentCoordinateFrame(); // simply calls glLightfv() with a position glClipPlane( GL_CLIP_PLANE0, mirror_plane ); glEnable( GL_CLIP_PLANE0 ); /* Draw "actual" scene, not its reflection. */ glCullFace( GL_FRONT ); drawBouncingTeapot(); glCullFace( GL_BACK ); glDisable( GL_CLIP_PLANE0 ); glPopMatrix(); fb->UnbindBuffer(); } void redraw(void) { if (!mirrorFB) InitializeFramebufferObjects(); DrawReflectedSceneIntoBuffer( mirrorFB ); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glPushMatrix(); /* Do standard per-frame OpenGL setup (for view and lights) */ SetupEyeViewBasedOnUserInput(); SetLightPostionInCurrentCoordinateFrame(); // simply calls glLightfv() with a position /* If you want the mirror to have color (only reflect part of the light) */ /* then you need to draw it to partially occlude stuff (i.e., with */ /* alpha-blending enabled) */ DrawMirrorWithReflectedTexture(); /* Draw "actual" scene, not its reflection. */ drawBouncingTeapot(); glPopMatrix(); glutSwapBuffers(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowSize( 512, 512 ); glutCreateWindow("Basic Planar Reflection Demo"); glutDisplayFunc(redraw); glutMouseFunc(mouse); glutMotionFunc(motion); glutVisibilityFunc(visible); glutCreateMenu(controlLights); glutAddMenuEntry("Toggle right light", 1); glutAddMenuEntry("Toggle left light", 2); glutAddMenuEntry("Toggle artifact elimination", 3); glutAddMenuEntry("Toggle mirror shape", 4 ); glutAttachMenu(GLUT_RIGHT_BUTTON); makeDisplayLists(); floor_texture = loadTheTexture(); InitializeViewingAndLighting(); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glewInit(); glutMainLoop(); return 0; }