Blender  V2.59
GHOST_C-Test.c
Go to the documentation of this file.
00001 
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 #include <string.h>
00044 #include <math.h>
00045 
00046 #define FALSE 0
00047 
00048 #include "GHOST_C-api.h"
00049 
00050 #if defined(WIN32) || defined(__APPLE__)
00051         #ifdef WIN32
00052                 #include <windows.h>
00053                 #include <GL/gl.h>
00054         #else /* WIN32 */
00055                 /* __APPLE__ is defined */
00056                 #include <AGL/gl.h>
00057         #endif /* WIN32 */
00058 #else /* defined(WIN32) || defined(__APPLE__) */
00059         #include <GL/gl.h>
00060 #endif /* defined(WIN32) || defined(__APPLE__) */
00061 
00062 
00063 static void gearsTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time);
00064 int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData);
00065 
00066 static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0;
00067 static GLfloat fAngle = 0.0;
00068 static int sExitRequested = 0;
00069 static GHOST_SystemHandle shSystem = NULL;
00070 static GHOST_WindowHandle sMainWindow = NULL;
00071 static GHOST_WindowHandle sSecondaryWindow = NULL;
00072 static GHOST_TStandardCursor sCursor = GHOST_kStandardCursorFirstCursor;
00073 static GHOST_WindowHandle sFullScreenWindow = NULL;
00074 static GHOST_TimerTaskHandle sTestTimer;
00075 static GHOST_TimerTaskHandle sGearsTimer;
00076 
00077 static void testTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time)
00078 {
00079         printf("timer1, time=%d\n", (int)time);
00080 }
00081 
00082 
00083 static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
00084 {
00085         GLint i;
00086         GLfloat r0, r1, r2;
00087         GLfloat angle, da;
00088         GLfloat u, v, len;
00089         const double pi = 3.14159264;
00090         
00091         r0 = inner_radius;
00092         r1 = (float)(outer_radius - tooth_depth/2.0);
00093         r2 = (float)(outer_radius + tooth_depth/2.0);
00094         
00095         da = (float)(2.0*pi / teeth / 4.0);
00096         
00097         glShadeModel(GL_FLAT);
00098         glNormal3f(0.0, 0.0, 1.0);
00099         
00100         /* draw front face */
00101         glBegin(GL_QUAD_STRIP);
00102         for (i=0;i<=teeth;i++) {
00103                 angle = (float)(i * 2.0*pi / teeth);
00104                 glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5));
00105                 glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5));
00106                 glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5));
00107                 glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(width*0.5));
00108         }
00109         glEnd();
00110         
00111         /* draw front sides of teeth */
00112         glBegin(GL_QUADS);
00113         da = (float)(2.0*pi / teeth / 4.0);
00114         for (i=0;i<teeth;i++) {
00115                 angle = (float)(i * 2.0*pi / teeth);
00116                 glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5));
00117                 glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(width*0.5));
00118                 glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(width*0.5));
00119                 glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(width*0.5));
00120         }
00121         glEnd();
00122         
00123         glNormal3f(0.0, 0.0, -1.0);
00124         
00125         /* draw back face */
00126         glBegin(GL_QUAD_STRIP);
00127         for (i=0;i<=teeth;i++) {
00128                 angle = (float)(i * 2.0*pi / teeth);
00129                 glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5));
00130                 glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5));
00131                 glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5));
00132                 glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5));
00133         }
00134         glEnd();
00135         
00136         /* draw back sides of teeth */
00137         glBegin(GL_QUADS);
00138         da = (float)(2.0*pi / teeth / 4.0);
00139         for (i=0;i<teeth;i++) {
00140                 angle = (float)(i * 2.0*pi / teeth);
00141                 glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5));
00142                 glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(-width*0.5));
00143                 glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(-width*0.5));
00144                 glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5));
00145         }
00146         glEnd();
00147         
00148         /* draw outward faces of teeth */
00149         glBegin(GL_QUAD_STRIP);
00150         for (i=0;i<teeth;i++) {
00151                 angle = (float)(i * 2.0*pi / teeth);
00152                 glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5));
00153                 glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5));
00154                 u = (float)(r2*cos(angle+da) - r1*cos(angle));
00155                 v = (float)(r2*sin(angle+da) - r1*sin(angle));
00156                 len = (float)(sqrt(u*u + v*v));
00157                 u /= len;
00158                 v /= len;
00159                 glNormal3f(v, -u, 0.0);
00160                 glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(width*0.5));
00161                 glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(-width*0.5));
00162                 glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
00163                 glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(width*0.5));
00164                 glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(-width*0.5));
00165                 u = (float)(r1*cos(angle+3*da) - r2*cos(angle+2*da));
00166                 v = (float)(r1*sin(angle+3*da) - r2*sin(angle+2*da));
00167                 glNormal3f(v, -u, 0.0);
00168                 glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(width*0.5));
00169                 glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5));
00170                 glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
00171         }
00172         glVertex3f((float)(r1*cos(0.0)), (float)(r1*sin(0.0)), (float)(width*0.5));
00173         glVertex3f((float)(r1*cos(0.0)), (float)(r1*sin(0.0)), (float)(-width*0.5));
00174         glEnd();
00175         
00176         glShadeModel(GL_SMOOTH);
00177         
00178         /* draw inside radius cylinder */
00179         glBegin(GL_QUAD_STRIP);
00180         for (i=0;i<=teeth;i++) {
00181                 angle = (float)(i * 2.0*pi / teeth);
00182                 glNormal3f((float)(-cos(angle)), (float)(-sin(angle)), 0.0);
00183                 glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5));
00184                 glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5));
00185         }
00186         glEnd();
00187 }
00188 
00189 
00190 
00191 static void drawGearGL(int id)
00192 {
00193     static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
00194     static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
00195     static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
00196     static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
00197         
00198     glLightfv(GL_LIGHT0, GL_POSITION, pos);
00199     glEnable(GL_CULL_FACE);
00200     glEnable(GL_LIGHTING);
00201     glEnable(GL_LIGHT0);
00202     glEnable(GL_DEPTH_TEST);
00203         
00204         switch (id)
00205         {
00206         case 1:
00207                 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
00208                 gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
00209                 break;
00210         case 2:
00211                 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
00212                 gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
00213                 break;
00214         case 3:
00215                 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
00216                 gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
00217                 break;
00218         default:
00219                 break;
00220         }
00221     glEnable(GL_NORMALIZE);
00222 }
00223 
00224 
00225 static void drawGL(void)
00226 {
00227     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00228         
00229     glPushMatrix();
00230         
00231     glRotatef(view_rotx, 1.0, 0.0, 0.0);
00232     glRotatef(view_roty, 0.0, 1.0, 0.0);
00233     glRotatef(view_rotz, 0.0, 0.0, 1.0);
00234         
00235     glPushMatrix();
00236     glTranslatef(-3.0, -2.0, 0.0);
00237     glRotatef(fAngle, 0.0, 0.0, 1.0);
00238     drawGearGL(1);
00239     glPopMatrix();
00240         
00241     glPushMatrix();
00242     glTranslatef(3.1f, -2.0f, 0.0f);
00243     glRotatef((float)(-2.0*fAngle-9.0), 0.0, 0.0, 1.0);
00244     drawGearGL(2);
00245     glPopMatrix();
00246         
00247     glPushMatrix();
00248     glTranslatef(-3.1f, 2.2f, -1.8f);
00249     glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
00250     glRotatef((float)(2.0*fAngle-2.0), 0.0, 0.0, 1.0);
00251     drawGearGL(3);
00252     glPopMatrix();
00253         
00254     glPopMatrix();
00255 }
00256 
00257 
00258 static void setViewPortGL(GHOST_WindowHandle hWindow)
00259 {
00260         GHOST_RectangleHandle hRect = NULL;
00261         GLfloat w, h;
00262         
00263     GHOST_ActivateWindowDrawingContext(hWindow);
00264     hRect = GHOST_GetClientBounds(hWindow);
00265         
00266     w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect);
00267     h = 1.0;
00268         
00269         glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect));
00270 
00271         glMatrixMode(GL_PROJECTION);
00272         glLoadIdentity();
00273     glFrustum(-w, w, -h, h, 5.0, 60.0);
00274         /* glOrtho(0, bnds.getWidth(), 0, bnds.getHeight(), -10, 10); */
00275         glMatrixMode(GL_MODELVIEW);
00276         glLoadIdentity();
00277     glTranslatef(0.0, 0.0, -40.0);
00278         
00279         glClearColor(.2f,0.0f,0.0f,0.0f);
00280         glClear(GL_COLOR_BUFFER_BIT);
00281 
00282         GHOST_DisposeRectangle(hRect);
00283 }
00284 
00285 
00286 
00287 int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
00288 {
00289         int handled = 1;
00290         int cursor;
00291         int visibility;
00292         GHOST_TEventKeyData* keyData = NULL;
00293         GHOST_TEventWheelData* wheelData = NULL;
00294         GHOST_DisplaySetting setting;
00295         GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
00296         
00297         switch (GHOST_GetEventType(hEvent))
00298         {
00299         /*
00300         case GHOST_kEventUnknown:
00301                 break;
00302         case GHOST_kEventCursorButton:
00303                 break;
00304         case GHOST_kEventCursorMove:
00305                 break;
00306         */
00307         case GHOST_kEventWheel:
00308                 {
00309                 wheelData = (GHOST_TEventWheelData*)GHOST_GetEventData(hEvent);
00310                 if (wheelData->z > 0)
00311                 {
00312                         view_rotz += 5.f;
00313                 }
00314                 else
00315                 {
00316                         view_rotz -= 5.f;
00317                 }
00318                 }
00319                 break;
00320 
00321         case GHOST_kEventKeyUp:
00322                 break;
00323                 
00324         case GHOST_kEventKeyDown:
00325                 {
00326                         keyData = (GHOST_TEventKeyData*)GHOST_GetEventData(hEvent);
00327                         switch (keyData->key)
00328                         {
00329                         case GHOST_kKeyC:
00330                                 {
00331                                         cursor = sCursor;
00332                                         cursor++;
00333                                         if (cursor >= GHOST_kStandardCursorNumCursors)
00334                                         {
00335                                                 cursor = GHOST_kStandardCursorFirstCursor;
00336                                         }
00337                                         sCursor = (GHOST_TStandardCursor)cursor;
00338                                         GHOST_SetCursorShape(window, sCursor);
00339                                 }
00340                                 break;
00341                         case GHOST_kKeyF:
00342                                 if (!GHOST_GetFullScreen(shSystem))
00343                                 {
00344                                         /* Begin fullscreen mode */
00345                                         setting.bpp = 24;
00346                                         setting.frequency = 85;
00347                                         setting.xPixels = 640;
00348                                         setting.yPixels = 480;
00349                                         
00350                                         /*
00351                                         setting.bpp = 16;
00352                                         setting.frequency = 75;
00353                                         setting.xPixels = 640;
00354                                         setting.yPixels = 480;
00355                                         */
00356 
00357                                         sFullScreenWindow = GHOST_BeginFullScreen(shSystem, &setting,
00358 
00359                                                 FALSE /* stereo flag */);
00360                                 }
00361                                 else
00362                                 {
00363                                         GHOST_EndFullScreen(shSystem);
00364                                         sFullScreenWindow = 0;
00365                                 }
00366                                 break;
00367                         case GHOST_kKeyH:
00368                                 {
00369                                         visibility = GHOST_GetCursorVisibility(window);
00370                                         GHOST_SetCursorVisibility(window, !visibility);
00371                                 }
00372                                 break;
00373                         case GHOST_kKeyQ:
00374                                 if (GHOST_GetFullScreen(shSystem))
00375                                 {
00376                                         GHOST_EndFullScreen(shSystem);
00377                                         sFullScreenWindow = 0;
00378                                 }
00379                                 sExitRequested = 1;
00380                         case GHOST_kKeyT:
00381                                 if (!sTestTimer)
00382                                 {
00383                                         sTestTimer = GHOST_InstallTimer(shSystem, 0, 1000, testTimerProc, NULL);
00384                                 }
00385                                 else
00386                                 {
00387                                         GHOST_RemoveTimer(shSystem, sTestTimer);
00388                                         sTestTimer = 0;
00389                                 }
00390                                 break;
00391                         case GHOST_kKeyW:
00392                                 {
00393                                         if (sMainWindow)
00394                                         {
00395                                                 char *title = GHOST_GetTitle(sMainWindow);
00396                                                 char *ntitle = malloc(strlen(title)+2);
00397 
00398                                                 sprintf(ntitle, "%s-", title);
00399                                                 GHOST_SetTitle(sMainWindow, ntitle);
00400                                                 
00401                                                 free(ntitle);
00402                                                 free(title);
00403                                         }
00404                                 }
00405                                 break;
00406                         default:
00407                                 break;
00408                         }
00409                 }
00410                 break;
00411                 
00412         case GHOST_kEventWindowClose:
00413                 {
00414                         GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
00415                         if (window2 == sMainWindow)
00416                         {
00417                                 sExitRequested = 1;
00418                         }
00419                         else
00420                         {
00421                                 if (sGearsTimer)
00422                                 {
00423                                         GHOST_RemoveTimer(shSystem, sGearsTimer);
00424                                         sGearsTimer = 0;
00425                                 }
00426                                 GHOST_DisposeWindow(shSystem, window2);
00427                         }
00428                 }
00429                 break;
00430                 
00431         case GHOST_kEventWindowActivate:
00432                 handled = 0;
00433                 break;
00434         case GHOST_kEventWindowDeactivate:
00435                 handled = 0;
00436                 break;
00437         case GHOST_kEventWindowUpdate:
00438                 {
00439                         GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
00440                         if (!GHOST_ValidWindow(shSystem, window2))
00441                                 break;
00442                         setViewPortGL(window2);
00443                         drawGL();
00444                         GHOST_SwapWindowBuffers(window2);
00445                 }
00446                 break;
00447                 
00448         default:
00449                 handled = 0;
00450                 break;
00451         }
00452         return handled;
00453 }
00454 
00455 
00456 int main(int argc, char** argv)
00457 {
00458         char* title1 = "gears - main window";
00459         char* title2 = "gears - secondary window";
00460         GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(processEvent, NULL);
00461 
00462         /* Create the system */
00463         shSystem = GHOST_CreateSystem();
00464         GHOST_AddEventConsumer(shSystem, consumer);
00465         
00466         if (shSystem)
00467         {
00468                 /* Create the main window */
00469                 sMainWindow = GHOST_CreateWindow(shSystem,
00470                         title1,
00471                         10,
00472                         64,
00473                         320,
00474                         200,
00475                         GHOST_kWindowStateNormal,
00476                         GHOST_kDrawingContextTypeOpenGL,
00477                         FALSE,
00478                         FALSE);
00479                 if (!sMainWindow)
00480                 {
00481                         printf("could not create main window\n");
00482                         exit(-1);
00483                 }
00484                 
00485                 /* Create a secondary window */
00486                 sSecondaryWindow = GHOST_CreateWindow(shSystem,
00487                         title2,
00488                         340,
00489                         64,
00490                         320,
00491                         200,
00492                         GHOST_kWindowStateNormal,
00493                         GHOST_kDrawingContextTypeOpenGL,
00494                         FALSE,
00495                         FALSE);
00496                 if (!sSecondaryWindow)
00497                 {
00498                         printf("could not create secondary window\n");
00499                         exit(-1);
00500                 }
00501                 
00502                 /* Install a timer to have the gears running */
00503                  sGearsTimer = GHOST_InstallTimer(shSystem,
00504                         0,
00505                         10,
00506                         gearsTimerProc,
00507                         sMainWindow);
00508 
00509                 /* Enter main loop */
00510                 while (!sExitRequested)
00511                 {
00512                         if (!GHOST_ProcessEvents(shSystem, 0)) 
00513                         {
00514 #ifdef WIN32
00515                                 /* If there were no events, be nice to other applications */
00516                                 Sleep(10);
00517 #endif
00518                         }
00519                         GHOST_DispatchEvents(shSystem);
00520                 }
00521         }
00522 
00523         /* Dispose windows */
00524         if (GHOST_ValidWindow(shSystem, sMainWindow))
00525         {
00526                 GHOST_DisposeWindow(shSystem, sMainWindow);
00527         }
00528         if (GHOST_ValidWindow(shSystem, sSecondaryWindow))
00529         {
00530                 GHOST_DisposeWindow(shSystem, sSecondaryWindow);
00531         }
00532 
00533         /* Dispose the system */
00534         GHOST_DisposeSystem(shSystem);
00535         GHOST_DisposeEventConsumer(consumer);
00536         
00537         return 0;
00538 }
00539 
00540 
00541 static void gearsTimerProc(GHOST_TimerTaskHandle hTask, GHOST_TUns64 time)
00542 {
00543         GHOST_WindowHandle hWindow = NULL;
00544     fAngle += 2.0;
00545     view_roty += 1.0;
00546         hWindow = (GHOST_WindowHandle)GHOST_GetTimerTaskUserData(hTask);
00547         if (GHOST_GetFullScreen(shSystem))
00548         {
00549                 /* Running full screen */
00550                 GHOST_InvalidateWindow(sFullScreenWindow);
00551         }
00552         else
00553         {
00554                 if (GHOST_ValidWindow(shSystem, hWindow))
00555                 {
00556                         GHOST_InvalidateWindow(hWindow);
00557                 }
00558         }
00559 }