* Forgot to commit CMake change for the Brick texture.
[blender.git] / intern / ghost / test / gears / GHOST_C-Test.c
1 /**
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /**
29  * Copyright (C) 2001 NaN Technologies B.V.
30  *
31  * Simple test file for the GHOST library.
32  * The OpenGL gear code is taken from the Qt sample code which,
33  * in turn, is probably taken from somewhere as well.
34  * @author      Maarten Gribnau
35  * @date        May 31, 2001
36  */
37
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <math.h>
42
43 #define FALSE 0
44
45 #include "GHOST_C-api.h"
46
47 #if defined(WIN32) || defined(__APPLE__)
48 #  ifdef WIN32
49 #    include <windows.h>
50 #    include <GL/gl.h>
51 #  else /* WIN32 */
52      /* __APPLE__ is defined */
53 #    include <AGL/gl.h>
54 #  endif /* WIN32 */
55 #else /* defined(WIN32) || defined(__APPLE__) */
56 #  include <GL/gl.h>
57 #endif /* defined(WIN32) || defined(__APPLE__) */
58
59
60 static void gearsTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time);
61 int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData);
62
63 static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
64 static GLfloat fAngle = 0.0;
65 static int sExitRequested = 0;
66 static GHOST_SystemHandle shSystem = NULL;
67 static GHOST_WindowHandle sMainWindow = NULL;
68 static GHOST_WindowHandle sSecondaryWindow = NULL;
69 static GHOST_TStandardCursor sCursor = GHOST_kStandardCursorFirstCursor;
70 static GHOST_WindowHandle sFullScreenWindow = NULL;
71 static GHOST_TimerTaskHandle sTestTimer;
72 static GHOST_TimerTaskHandle sGearsTimer;
73
74 static void testTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time)
75 {
76         printf("timer1, time=%d\n", (int)time);
77 }
78
79
80 static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
81 {
82         GLint i;
83         GLfloat r0, r1, r2;
84         GLfloat angle, da;
85         GLfloat u, v, len;
86         const double pi = 3.14159264;
87         
88         r0 = inner_radius;
89         r1 = (float)(outer_radius - tooth_depth / 2.0);
90         r2 = (float)(outer_radius + tooth_depth / 2.0);
91         
92         da = (float)(2.0 * pi / teeth / 4.0);
93         
94         glShadeModel(GL_FLAT);
95         glNormal3f(0.0, 0.0, 1.0);
96         
97         /* draw front face */
98         glBegin(GL_QUAD_STRIP);
99         for (i = 0; i <= teeth; i++) {
100                 angle = (float)(i * 2.0 * pi / teeth);
101                 glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
102                 glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
103                 glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
104                 glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(width * 0.5));
105         }
106         glEnd();
107         
108         /* draw front sides of teeth */
109         glBegin(GL_QUADS);
110         da = (float)(2.0 * pi / teeth / 4.0);
111         for (i = 0; i < teeth; i++) {
112                 angle = (float)(i * 2.0 * pi / teeth);
113                 glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
114                 glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(width * 0.5));
115                 glVertex3f((float)(r2 * cos(angle + 2 * da)), (float)(r2 * sin(angle + 2 * da)), (float)(width * 0.5));
116                 glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(width * 0.5));
117         }
118         glEnd();
119         
120         glNormal3f(0.0, 0.0, -1.0);
121         
122         /* draw back face */
123         glBegin(GL_QUAD_STRIP);
124         for (i = 0; i <= teeth; i++) {
125                 angle = (float)(i * 2.0 * pi / teeth);
126                 glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
127                 glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
128                 glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(-width * 0.5));
129                 glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
130         }
131         glEnd();
132         
133         /* draw back sides of teeth */
134         glBegin(GL_QUADS);
135         da = (float)(2.0 * pi / teeth / 4.0);
136         for (i = 0; i < teeth; i++) {
137                 angle = (float)(i * 2.0 * pi / teeth);
138                 glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(-width * 0.5));
139                 glVertex3f((float)(r2 * cos(angle + 2 * da)), (float)(r2 * sin(angle + 2 * da)), (float)(-width * 0.5));
140                 glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(-width * 0.5));
141                 glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
142         }
143         glEnd();
144         
145         /* draw outward faces of teeth */
146         glBegin(GL_QUAD_STRIP);
147         for (i = 0; i < teeth; i++) {
148                 angle = (float)(i * 2.0 * pi / teeth);
149                 glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
150                 glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
151                 u = (float)(r2 * cos(angle + da) - r1 * cos(angle));
152                 v = (float)(r2 * sin(angle + da) - r1 * sin(angle));
153                 len = (float)(sqrt(u * u + v * v));
154                 u /= len;
155                 v /= len;
156                 glNormal3f(v, -u, 0.0);
157                 glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(width * 0.5));
158                 glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(-width * 0.5));
159                 glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
160                 glVertex3f((float)(r2 * cos(angle + 2 * da)), (float)(r2 * sin(angle + 2 * da)), (float)(width * 0.5));
161                 glVertex3f((float)(r2 * cos(angle + 2 * da)), (float)(r2 * sin(angle + 2 * da)), (float)(-width * 0.5));
162                 u = (float)(r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da));
163                 v = (float)(r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da));
164                 glNormal3f(v, -u, 0.0);
165                 glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(width * 0.5));
166                 glVertex3f((float)(r1 * cos(angle + 3 * da)), (float)(r1 * sin(angle + 3 * da)), (float)(-width * 0.5));
167                 glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
168         }
169         glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(width * 0.5));
170         glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(-width * 0.5));
171         glEnd();
172         
173         glShadeModel(GL_SMOOTH);
174         
175         /* draw inside radius cylinder */
176         glBegin(GL_QUAD_STRIP);
177         for (i = 0; i <= teeth; i++) {
178                 angle = (float)(i * 2.0 * pi / teeth);
179                 glNormal3f((float)(-cos(angle)), (float)(-sin(angle)), 0.0);
180                 glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
181                 glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
182         }
183         glEnd();
184 }
185
186
187
188 static void drawGearGL(int id)
189 {
190         static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
191         static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
192         static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
193         static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
194         
195         glLightfv(GL_LIGHT0, GL_POSITION, pos);
196         glEnable(GL_CULL_FACE);
197         glEnable(GL_LIGHTING);
198         glEnable(GL_LIGHT0);
199         glEnable(GL_DEPTH_TEST);
200         
201         switch (id)
202         {
203                 case 1:
204                         glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
205                         gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
206                         break;
207                 case 2:
208                         glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
209                         gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
210                         break;
211                 case 3:
212                         glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
213                         gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
214                         break;
215                 default:
216                         break;
217         }
218         glEnable(GL_NORMALIZE);
219 }
220
221
222 static void drawGL(void)
223 {
224         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
225         
226         glPushMatrix();
227         
228         glRotatef(view_rotx, 1.0, 0.0, 0.0);
229         glRotatef(view_roty, 0.0, 1.0, 0.0);
230         glRotatef(view_rotz, 0.0, 0.0, 1.0);
231         
232         glPushMatrix();
233         glTranslatef(-3.0, -2.0, 0.0);
234         glRotatef(fAngle, 0.0, 0.0, 1.0);
235         drawGearGL(1);
236         glPopMatrix();
237         
238         glPushMatrix();
239         glTranslatef(3.1f, -2.0f, 0.0f);
240         glRotatef((float)(-2.0 * fAngle - 9.0), 0.0, 0.0, 1.0);
241         drawGearGL(2);
242         glPopMatrix();
243         
244         glPushMatrix();
245         glTranslatef(-3.1f, 2.2f, -1.8f);
246         glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
247         glRotatef((float)(2.0 * fAngle - 2.0), 0.0, 0.0, 1.0);
248         drawGearGL(3);
249         glPopMatrix();
250         
251         glPopMatrix();
252 }
253
254
255 static void setViewPortGL(GHOST_WindowHandle hWindow)
256 {
257         GHOST_RectangleHandle hRect = NULL;
258         GLfloat w, h;
259         
260         GHOST_ActivateWindowDrawingContext(hWindow);
261         hRect = GHOST_GetClientBounds(hWindow);
262         
263         w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect);
264         h = 1.0;
265         
266         glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect));
267
268         glMatrixMode(GL_PROJECTION);
269         glLoadIdentity();
270         glFrustum(-w, w, -h, h, 5.0, 60.0);
271         /* glOrtho(0, bnds.getWidth(), 0, bnds.getHeight(), -10, 10); */
272         glMatrixMode(GL_MODELVIEW);
273         glLoadIdentity();
274         glTranslatef(0.0, 0.0, -40.0);
275         
276         glClearColor(.2f, 0.0f, 0.0f, 0.0f);
277         glClear(GL_COLOR_BUFFER_BIT);
278
279         GHOST_DisposeRectangle(hRect);
280 }
281
282
283
284 int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
285 {
286         int handled = 1;
287         int cursor;
288         int visibility;
289         GHOST_TEventKeyData *keyData = NULL;
290         GHOST_TEventWheelData *wheelData = NULL;
291         GHOST_DisplaySetting setting;
292         GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
293         
294         switch (GHOST_GetEventType(hEvent))
295         {
296 #if 0
297                 case GHOST_kEventUnknown:
298                         break;
299                 case GHOST_kEventCursorButton:
300                         break;
301                 case GHOST_kEventCursorMove:
302                         break;
303 #endif
304                 case GHOST_kEventWheel:
305                 {
306                         wheelData = (GHOST_TEventWheelData *)GHOST_GetEventData(hEvent);
307                         if (wheelData->z > 0)
308                         {
309                                 view_rotz += 5.f;
310                         }
311                         else {
312                                 view_rotz -= 5.f;
313                         }
314                 }
315                 break;
316
317                 case GHOST_kEventKeyUp:
318                         break;
319                 
320                 case GHOST_kEventKeyDown:
321                 {
322                         keyData = (GHOST_TEventKeyData *)GHOST_GetEventData(hEvent);
323                         switch (keyData->key)
324                         {
325                                 case GHOST_kKeyC:
326                                 {
327                                         cursor = sCursor;
328                                         cursor++;
329                                         if (cursor >= GHOST_kStandardCursorNumCursors)
330                                         {
331                                                 cursor = GHOST_kStandardCursorFirstCursor;
332                                         }
333                                         sCursor = (GHOST_TStandardCursor)cursor;
334                                         GHOST_SetCursorShape(window, sCursor);
335                                 }
336                                 break;
337                                 case GHOST_kKeyF:
338                                         if (!GHOST_GetFullScreen(shSystem))
339                                         {
340                                                 /* Begin fullscreen mode */
341                                                 setting.bpp = 24;
342                                                 setting.frequency = 85;
343                                                 setting.xPixels = 640;
344                                                 setting.yPixels = 480;
345
346                                                 /*
347                                                  * setting.bpp = 16;
348                                                  * setting.frequency = 75;
349                                                  * setting.xPixels = 640;
350                                                  * setting.yPixels = 480;
351                                                  */
352
353                                                 sFullScreenWindow = GHOST_BeginFullScreen(shSystem, &setting,
354
355                                                                                           FALSE /* stereo flag */);
356                                         }
357                                         else {
358                                                 GHOST_EndFullScreen(shSystem);
359                                                 sFullScreenWindow = 0;
360                                         }
361                                         break;
362                                 case GHOST_kKeyH:
363                                 {
364                                         visibility = GHOST_GetCursorVisibility(window);
365                                         GHOST_SetCursorVisibility(window, !visibility);
366                                 }
367                                 break;
368                                 case GHOST_kKeyQ:
369                                         if (GHOST_GetFullScreen(shSystem))
370                                         {
371                                                 GHOST_EndFullScreen(shSystem);
372                                                 sFullScreenWindow = 0;
373                                         }
374                                         sExitRequested = 1;
375                                 case GHOST_kKeyT:
376                                         if (!sTestTimer)
377                                         {
378                                                 sTestTimer = GHOST_InstallTimer(shSystem, 0, 1000, testTimerProc, NULL);
379                                         }
380                                         else {
381                                                 GHOST_RemoveTimer(shSystem, sTestTimer);
382                                                 sTestTimer = 0;
383                                         }
384                                         break;
385                                 case GHOST_kKeyW:
386                                 {
387                                         if (sMainWindow)
388                                         {
389                                                 char *title = GHOST_GetTitle(sMainWindow);
390                                                 char *ntitle = malloc(strlen(title) + 2);
391
392                                                 sprintf(ntitle, "%s-", title);
393                                                 GHOST_SetTitle(sMainWindow, ntitle);
394                                                 
395                                                 free(ntitle);
396                                                 free(title);
397                                         }
398                                 }
399                                 break;
400                                 default:
401                                         break;
402                         }
403                 }
404                 break;
405                 
406                 case GHOST_kEventWindowClose:
407                 {
408                         GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
409                         if (window2 == sMainWindow)
410                         {
411                                 sExitRequested = 1;
412                         }
413                         else {
414                                 if (sGearsTimer)
415                                 {
416                                         GHOST_RemoveTimer(shSystem, sGearsTimer);
417                                         sGearsTimer = 0;
418                                 }
419                                 GHOST_DisposeWindow(shSystem, window2);
420                         }
421                 }
422                 break;
423                 
424                 case GHOST_kEventWindowActivate:
425                         handled = 0;
426                         break;
427                 case GHOST_kEventWindowDeactivate:
428                         handled = 0;
429                         break;
430                 case GHOST_kEventWindowUpdate:
431                 {
432                         GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
433                         if (!GHOST_ValidWindow(shSystem, window2))
434                                 break;
435                         setViewPortGL(window2);
436                         drawGL();
437                         GHOST_SwapWindowBuffers(window2);
438                 }
439                 break;
440                 
441                 default:
442                         handled = 0;
443                         break;
444         }
445         return handled;
446 }
447
448
449 int main(int argc, char **argv)
450 {
451         char *title1 = "gears - main window";
452         char *title2 = "gears - secondary window";
453         GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(processEvent, NULL);
454
455         /* Create the system */
456         shSystem = GHOST_CreateSystem();
457         GHOST_AddEventConsumer(shSystem, consumer);
458         
459         if (shSystem)
460         {
461                 /* Create the main window */
462                 sMainWindow = GHOST_CreateWindow(shSystem,
463                                                  title1,
464                                                  10,
465                                                  64,
466                                                  320,
467                                                  200,
468                                                  GHOST_kWindowStateNormal,
469                                                  GHOST_kDrawingContextTypeOpenGL,
470                                                  FALSE,
471                                                  FALSE);
472                 if (!sMainWindow)
473                 {
474                         printf("could not create main window\n");
475                         exit(-1);
476                 }
477                 
478                 /* Create a secondary window */
479                 sSecondaryWindow = GHOST_CreateWindow(shSystem,
480                                                       title2,
481                                                       340,
482                                                       64,
483                                                       320,
484                                                       200,
485                                                       GHOST_kWindowStateNormal,
486                                                       GHOST_kDrawingContextTypeOpenGL,
487                                                       FALSE,
488                                                       FALSE);
489                 if (!sSecondaryWindow)
490                 {
491                         printf("could not create secondary window\n");
492                         exit(-1);
493                 }
494                 
495                 /* Install a timer to have the gears running */
496                 sGearsTimer = GHOST_InstallTimer(shSystem,
497                                                  0,
498                                                  10,
499                                                  gearsTimerProc,
500                                                  sMainWindow);
501
502                 /* Enter main loop */
503                 while (!sExitRequested)
504                 {
505                         if (!GHOST_ProcessEvents(shSystem, 0)) 
506                         {
507 #ifdef WIN32
508                                 /* If there were no events, be nice to other applications */
509                                 Sleep(10);
510 #endif
511                         }
512                         GHOST_DispatchEvents(shSystem);
513                 }
514         }
515
516         /* Dispose windows */
517         if (GHOST_ValidWindow(shSystem, sMainWindow))
518         {
519                 GHOST_DisposeWindow(shSystem, sMainWindow);
520         }
521         if (GHOST_ValidWindow(shSystem, sSecondaryWindow))
522         {
523                 GHOST_DisposeWindow(shSystem, sSecondaryWindow);
524         }
525
526         /* Dispose the system */
527         GHOST_DisposeSystem(shSystem);
528         
529         return 0;
530 }
531
532
533 static void gearsTimerProc(GHOST_TimerTaskHandle hTask, GHOST_TUns64 time)
534 {
535         GHOST_WindowHandle hWindow = NULL;
536         fAngle += 2.0;
537         view_roty += 1.0;
538         hWindow = (GHOST_WindowHandle)GHOST_GetTimerTaskUserData(hTask);
539         if (GHOST_GetFullScreen(shSystem))
540         {
541                 /* Running full screen */
542                 GHOST_InvalidateWindow(sFullScreenWindow);
543         }
544         else {
545                 if (GHOST_ValidWindow(shSystem, hWindow))
546                 {
547                         GHOST_InvalidateWindow(hWindow);
548                 }
549         }
550 }