| Code: |
|
#include <stdlib.h> #include <stdio.h> #include <GHOST_C-api.h> #include <GL/gl.h> #include <GL/glu.h> static GHOST_SystemHandle ghost_system; static GHOST_WindowHandle win; static GHOST_WindowHandle full_screen_window; static GHOST_EventConsumerHandle consumer; static GHOST_TimerTaskHandle timer; static GLuint box; static int exit_requested = 0; static GLfloat xrot = 0.0; static GLfloat yrot = 0.0; static GLfloat zrot = 0.0; // Light Parameters static GLfloat LightAmb[] = {0.7f, 0.7f, 0.7f, 1.0f}; // Ambient Light static GLfloat LightDif[] = {1.0f, 1.0f, 1.0f, 1.0f}; // Diffuse Light static GLfloat LightPos[] = {4.0f, 4.0f, 6.0f, 1.0f}; // Light Position GLUquadricObj *q; // Quadratic For Drawing A Sphere GLfloat xrotspeed = 0.0f; // X Rotation Speed GLfloat yrotspeed = 0.0f; // Y Rotation Speed GLfloat zoom = -7.0f; // Depth Into The Screen GLfloat height = 2.0f; // Height Of Ball From Floor void DrawObject(void) { glColor3f(1.0f, 1.0f, 1.0f); // Set Color To White gluSphere(q, 0.35f, 32, 16); // Draw First Sphere glColor4f(1.0f, 1.0f, 1.0f, 0.4f); // Set Color To White With 40% Alpha glEnable(GL_BLEND); // Enable Blending glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Set Blending Mode To Mix Based On SRC Alpha gluSphere(q, 0.35f, 32, 16); // Draw Another Sphere Using New Texture glDisable(GL_BLEND); } void DrawFloor(void) // Draws The Floor { glBegin(GL_QUADS); // Begin Drawing A Quad glNormal3f(0.0, 1.0, 0.0); // Normal Pointing Up glVertex3f(-2.0, 0.0, 2.0); // Bottom Left Corner Of Floor glVertex3f(-2.0, 0.0,-2.0); // Top Left Corner Of Floor glVertex3f( 2.0, 0.0,-2.0); // Top Right Corner Of Floor glVertex3f( 2.0, 0.0, 2.0); // Bottom Right Corner Of Floor glEnd(); // Done Drawing The Quad } int InitGL(GLvoid) // All Setup For OpenGL Goes Here { glShadeModel(GL_SMOOTH); // Enable Smooth Shading glClearColor(0.2f, 0.5f, 1.0f, 1.0f); // Background glClearDepth(1.0f); // Depth Buffer Setup glClearStencil(0); // Clear The Stencil Buffer To 0 glEnable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations glEnable(GL_TEXTURE_2D); // Enable 2D Texture Mapping glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb); // Set The Ambient Lighting For Light0 glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif); // Set The Diffuse Lighting For Light0 glLightfv(GL_LIGHT0, GL_POSITION, LightPos); // Set The Position For Light0 glEnable(GL_LIGHT0); // Enable Light 0 glEnable(GL_LIGHTING); // Enable Lighting q = gluNewQuadric(); // Create A New Quadratic gluQuadricNormals(q, GL_SMOOTH); // Generate Smooth Normals For The Quad return 1; // Initialization Went OK } void DrawGLScene(void) { // Clip Plane Equations double eqr[] = {0.0f,-1.0f, 0.0f, 0.0f}; // Plane Equation To Use For The Reflected Objects // Clear Screen, Depth Buffer & Stencil Buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glLoadIdentity(); // Reset The Modelview Matrix glTranslatef(0.0f, -0.6f, zoom); // Zoom And Raise Camera Above The Floor (Up 0.6 Units) glColorMask(0,0,0,0); // Set Color Mask glEnable(GL_STENCIL_TEST); // Enable Stencil Buffer For "marking" The Floor glStencilFunc(GL_ALWAYS, 1, 1); // Always Passes, 1 Bit Plane, 1 As Mask glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); // We Set The Stencil Buffer To 1 Where We Draw Any Polygon // Keep If Test Fails, Keep If Test Passes But Buffer Test Fails // Replace If Test Passes glDisable(GL_DEPTH_TEST); // Disable Depth Testing DrawFloor(); // Draw The Floor (Draws To The Stencil Buffer) // We Only Want To Mark It In The Stencil Buffer glEnable(GL_DEPTH_TEST); // Enable Depth Testing glColorMask(1,1,1,1); // Set Color Mask to TRUE, TRUE, TRUE, TRUE glStencilFunc(GL_EQUAL, 1, 1); // We Draw Only Where The Stencil Is 1 // (I.E. Where The Floor Was Drawn) glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // Don't Change The Stencil Buffer glEnable(GL_CLIP_PLANE0); // Enable Clip Plane For Removing Artifacts // (When The Object Crosses The Floor) glClipPlane(GL_CLIP_PLANE0, eqr); // Equation For Reflected Objects glPushMatrix(); // Push The Matrix Onto The Stack glScalef(1.0f, -1.0f, 1.0f); // Mirror Y Axis glLightfv(GL_LIGHT0, GL_POSITION, LightPos); // Set Up Light0 glTranslatef(0.0f, height, 0.0f); // Position The Object glRotatef(xrot, 1.0f, 0.0f, 0.0f); // Rotate Local Coordinate System On X Axis glRotatef(yrot, 0.0f, 1.0f, 0.0f); // Rotate Local Coordinate System On Y Axis DrawObject(); // Draw The Sphere (Reflection) glPopMatrix(); // Pop The Matrix Off The Stack glDisable(GL_CLIP_PLANE0); // Disable Clip Plane For Drawing The Floor glDisable(GL_STENCIL_TEST); // We Don't Need The Stencil Buffer Any More (Disable) glLightfv(GL_LIGHT0, GL_POSITION, LightPos); // Set Up Light0 Position glEnable(GL_BLEND); // Enable Blending (Otherwise The Reflected Object Wont Show) glDisable(GL_LIGHTING); // Since We Use Blending, We Disable Lighting glColor4f(1.0f, 1.0f, 1.0f, 0.8f); // Set Color To White With 80% Alpha glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Blending Based On Source Alpha And 1 Minus Dest Alpha DrawFloor(); // Draw The Floor To The Screen glEnable(GL_LIGHTING); // Enable Lighting glDisable(GL_BLEND); // Disable Blending glTranslatef(0.0f, height, 0.0f); // Position The Ball At Proper Height glRotatef(xrot, 1.0f, 0.0f, 0.0f); // Rotate On The X Axis glRotatef(yrot, 0.0f, 1.0f, 0.0f); // Rotate On The Y Axis DrawObject(); // Draw The Ball xrot += xrotspeed; // Update X Rotation Angle By xrotspeed yrot += yrotspeed; // Update Y Rotation Angle By yrotspeed glFlush(); // Flush The GL Pipeline return 1; // Everything Went OK // Flush The GL Pipeline } /* * This invalidates a window so that the WindowUpdate * event will be generated for the window */ void invalidate_window(void) { if (GHOST_GetFullScreen(ghost_system)) GHOST_InvalidateWindow(full_screen_window); else { if (GHOST_ValidWindow(ghost_system, win)) GHOST_InvalidateWindow(win); } } /* * the procedure to run when the timer goes off */ void timer_proc(GHOST_TimerTaskHandle task, GHOST_TUns64 time) { DrawGLScene(); invalidate_window(); } /* * does the initial OpenGL setup of the main window */ void setup_window(GHOST_WindowHandle win) { GHOST_RectangleHandle rect = NULL; GLfloat w, h, aspect; GHOST_ActivateWindowDrawingContext(win); rect = GHOST_GetClientBounds(win); w = (GLfloat)GHOST_GetWidthRectangle(rect); h = (GLfloat)GHOST_GetHeightRectangle(rect); GHOST_DisposeRectangle(rect); aspect = w / h; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-aspect, aspect, -1.0, 1.0, 5.0, 60.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -12.0); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); DrawGLScene(); } /* * this handles the events as they are generated by the GHOST system */ int process_event(GHOST_EventHandle event, GHOST_TUserDataPtr data) { int handled = 0; GHOST_TEventKeyData *key_data = (GHOST_TEventKeyData *)GHOST_GetEventData(event); /* all the entries need to be in the switch to make the compiler shut up */ switch (GHOST_GetEventType(event)) { case GHOST_kEventUnknown: case GHOST_kEventCursorMove: case GHOST_kEventButtonDown: case GHOST_kEventButtonUp: case GHOST_kEventKeyUp: case GHOST_kEventWindowActivate: case GHOST_kEventWindowDeactivate: case GHOST_kEventWindowSize: case GHOST_kNumEventTypes: break; case GHOST_kEventWheel: { GHOST_TEventWheelData *wheel = (GHOST_TEventWheelData *)GHOST_GetEventData(event); if (wheel->z > 0) xrot += 2; else xrot -= 2; DrawGLScene(); invalidate_window(); } break; case GHOST_kEventWindowUpdate: { GHOST_WindowHandle win_handle = GHOST_GetEventWindow(event); if (!GHOST_ValidWindow(ghost_system, win_handle)) break; setup_window(win_handle); DrawGLScene(); GHOST_SwapWindowBuffers(win_handle); } break; case GHOST_kEventQuit: case GHOST_kEventWindowClose: exit_requested = 1; handled = 1; break; case GHOST_kEventKeyDown: if (key_data) { if (key_data->key == GHOST_kKeyQ) { exit_requested = 1; handled = 1; } else if (key_data->key == GHOST_kKeyR) { invalidate_window(); } else if (key_data->key == GHOST_kKeyT) { if (!timer) timer = GHOST_InstallTimer(ghost_system, 0, 10, timer_proc, NULL); else { GHOST_RemoveTimer(ghost_system, timer); timer = NULL; } } else if (key_data->key == GHOST_kKeyF) { if (GHOST_GetFullScreen(ghost_system)) { GHOST_EndFullScreen(ghost_system); full_screen_window = NULL; } else { GHOST_DisplaySetting setting; setting.bpp = 16; setting.frequency = 65; setting.xPixels = 640; setting.yPixels = 480; full_screen_window = GHOST_BeginFullScreen(ghost_system, &setting, 0); } } } break; } return handled; } int main(int argc, char ** argv) { // create the system ghost_system = GHOST_CreateSystem(); if (!ghost_system) { printf("Coun't not create the system, dying\n"); exit(-1); } // create the event consumer and add to the system consumer = GHOST_CreateEventConsumer(process_event, NULL); if (!consumer) { printf("Failed to create consumer\n"); GHOST_DisposeSystem(ghost_system); exit(-1); } GHOST_AddEventConsumer(ghost_system, consumer); // make the main window win = GHOST_CreateWindow(ghost_system, "Realtime Reflection-or", 10, 64, 320, 200, GHOST_kWindowStateNormal, GHOST_kDrawingContextTypeOpenGL, 0); if (!win) { printf("Couldn't not create window\n"); GHOST_DisposeSystem(ghost_system); GHOST_DisposeEventConsumer(consumer); exit(-1); } InitGL(); setup_window(win); /* the event loop */ while(!exit_requested) { // could sleep if there are no events, but hey i'm cruel, heh. GHOST_ProcessEvents(ghost_system, 0); GHOST_DispatchEvents(ghost_system); GHOST_SwapWindowBuffers(win); } /* exit full screen if we are in it */ if (GHOST_GetFullScreen(ghost_system)) GHOST_EndFullScreen(ghost_system); /* delete the timer */ if (timer) GHOST_RemoveTimer(ghost_system, timer); /* clean it all up */ if (GHOST_ValidWindow(ghost_system, win)) GHOST_DisposeWindow(ghost_system, win); GHOST_DisposeSystem(ghost_system); GHOST_DisposeEventConsumer(consumer); return 0; } |
| Code: |
| void DrawObject(void) {
glColor3f(1.0f, 0.5f, 0.5f); // Set Color gluSphere(q, 0.35f, 32, 16); // Draw First Sphere // begin change glPushMatrix(); glTranslatef(0.0f, -1.0f, 0.0f); glPopMatrix(); // end change glColor4f(1.0f, 1.0f, 1.0f, 0.4f); // Set Color To White With 40% Alpha glEnable(GL_BLEND); // Enable Blending glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Set Blending Mode To Mix Based On SRC Alpha gluSphere(q, 0.35f, 32, 16); // Draw Another Sphere Using New Texture glDisable(GL_BLEND); } |