* Forgot to commit CMake change for the Brick texture.
[blender.git] / intern / ghost / test / gears / GHOST_Test.cpp
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  * Simple test file for the GHOST library.
31  * The OpenGL gear code is taken from the Qt sample code which,
32  * in turn, is probably taken from somewhere as well.
33  * @author      Maarten Gribnau
34  * @date        May 31, 2001
35  * Stereo code by Raymond de Vries, januari 2002
36  */
37
38 #include <iostream>
39 #include <math.h>
40
41 #if defined(WIN32) || defined(__APPLE__)
42 #  ifdef WIN32
43 #    include <windows.h>
44 #    include <atlbase.h>
45
46 #    include <GL/gl.h>
47 #  else // WIN32
48           // __APPLE__ is defined
49 #    include <AGL/gl.h>
50 #  endif // WIN32
51 #else // defined(WIN32) || defined(__APPLE__)
52 #  include <GL/gl.h>
53 #endif // defined(WIN32) || defined(__APPLE__)
54
55 #include "STR_String.h"
56 #include "GHOST_Rect.h"
57
58 #include "GHOST_ISystem.h"
59 #include "GHOST_IEvent.h"
60 #include "GHOST_IEventConsumer.h"
61
62
63 #define LEFT_EYE  0
64 #define RIGHT_EYE 1
65
66 static bool nVidiaWindows;  // very dirty but hey, it's for testing only
67
68 static void gearsTimerProc(GHOST_ITimerTask *task, GHOST_TUns64 time);
69
70 static class Application * fApp;
71 static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
72 static GLfloat fAngle = 0.0;
73 static GHOST_ISystem *fSystem = 0;
74
75
76 void StereoProjection(float left, float right, float bottom, float top, float nearplane, float farplane,
77                       float zero_plane, float dist,
78                       float eye);
79
80
81 static void testTimerProc(GHOST_ITimerTask * /*task*/, GHOST_TUns64 time)
82 {
83         std::cout << "timer1, time=" << (int)time << "\n";
84 }
85
86
87 static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
88 {
89         GLint i;
90         GLfloat r0, r1, r2;
91         GLfloat angle, da;
92         GLfloat u, v, len;
93
94         r0 = inner_radius;
95         r1 = outer_radius - tooth_depth / 2.0;
96         r2 = outer_radius + tooth_depth / 2.0;
97
98         const double pi = 3.14159264;
99         da = 2.0 * pi / teeth / 4.0;
100
101         glShadeModel(GL_FLAT);
102         glNormal3f(0.0, 0.0, 1.0);
103
104         /* draw front face */
105         glBegin(GL_QUAD_STRIP);
106         for (i = 0; i <= teeth; i++) {
107                 angle = i * 2.0 * pi / teeth;
108                 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
109                 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
110                 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
111                 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
112         }
113         glEnd();
114
115         /* draw front sides of teeth */
116         glBegin(GL_QUADS);
117         da = 2.0 * pi / teeth / 4.0;
118         for (i = 0; i < teeth; i++) {
119                 angle = i * 2.0 * pi / teeth;
120                 glVertex3f(r1 * cos(angle),      r1 * sin(angle),      width * 0.5);
121                 glVertex3f(r2 * cos(angle + da),   r2 * sin(angle + da),   width * 0.5);
122                 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
123                 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
124         }
125         glEnd();
126
127         glNormal3f(0.0, 0.0, -1.0);
128
129         /* draw back face */
130         glBegin(GL_QUAD_STRIP);
131         for (i = 0; i <= teeth; i++) {
132                 angle = i * 2.0 * pi / teeth;
133                 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
134                 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
135                 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
136                 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
137         }
138         glEnd();
139
140         /* draw back sides of teeth */
141         glBegin(GL_QUADS);
142         da = 2.0 * pi / teeth / 4.0;
143         for (i = 0; i < teeth; i++) {
144                 angle = i * 2.0 * pi / teeth;
145                 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
146                 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
147                 glVertex3f(r2 * cos(angle + da),   r2 * sin(angle + da),      -width * 0.5);
148                 glVertex3f(r1 * cos(angle),      r1 * sin(angle),     -width * 0.5);
149         }
150         glEnd();
151
152         /* draw outward faces of teeth */
153         glBegin(GL_QUAD_STRIP);
154         for (i = 0; i < teeth; i++) {
155                 angle = i * 2.0 * pi / teeth;
156                 glVertex3f(r1 * cos(angle),      r1 * sin(angle),      width * 0.5);
157                 glVertex3f(r1 * cos(angle),      r1 * sin(angle),     -width * 0.5);
158                 u = r2 * cos(angle + da) - r1 *cos(angle);
159                 v = r2 * sin(angle + da) - r1 *sin(angle);
160                 len = sqrt(u * u + v * v);
161                 u /= len;
162                 v /= len;
163                 glNormal3f(v, -u, 0.0);
164                 glVertex3f(r2 * cos(angle + da),   r2 * sin(angle + da),       width * 0.5);
165                 glVertex3f(r2 * cos(angle + da),   r2 * sin(angle + da),      -width * 0.5);
166                 glNormal3f(cos(angle), sin(angle), 0.0);
167                 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),  width * 0.5);
168                 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
169                 u = r1 * cos(angle + 3 * da) - r2 *cos(angle + 2 * da);
170                 v = r1 * sin(angle + 3 * da) - r2 *sin(angle + 2 * da);
171                 glNormal3f(v, -u, 0.0);
172                 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),  width * 0.5);
173                 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
174                 glNormal3f(cos(angle), sin(angle), 0.0);
175         }
176         glVertex3f(r1 * cos(0.0), r1 * sin(0.0), width * 0.5);
177         glVertex3f(r1 * cos(0.0), r1 * sin(0.0), -width * 0.5);
178         glEnd();
179
180         glShadeModel(GL_SMOOTH);
181
182         /* draw inside radius cylinder */
183         glBegin(GL_QUAD_STRIP);
184         for (i = 0; i <= teeth; i++) {
185                 angle = i * 2.0 * pi / teeth;
186                 glNormal3f(-cos(angle), -sin(angle), 0.0);
187                 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
188                 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
189         }
190         glEnd();
191 }
192
193
194
195 static void drawGearGL(int id)
196 {
197         static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
198         static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
199         static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
200         static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
201
202         glLightfv(GL_LIGHT0, GL_POSITION, pos);
203         glEnable(GL_CULL_FACE);
204         glEnable(GL_LIGHTING);
205         glEnable(GL_LIGHT0);
206         glEnable(GL_DEPTH_TEST);
207
208         switch (id)
209         {
210                 case 1:
211                         glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
212                         gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
213                         break;
214                 case 2:
215                         glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
216                         gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
217                         break;
218                 case 3:
219                         glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
220                         gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
221                         break;
222                 default:
223                         break;
224         }
225         glEnable(GL_NORMALIZE);
226 }
227
228
229 void RenderCamera()
230 {
231         glRotatef(view_rotx, 1.0, 0.0, 0.0);
232         glRotatef(view_roty, 0.0, 1.0, 0.0);
233         glRotatef(view_rotz, 0.0, 0.0, 1.0);
234 }
235
236
237 void RenderScene()
238 {
239         glPushMatrix();
240         glTranslatef(-3.0, -2.0, 0.0);
241         glRotatef(fAngle, 0.0, 0.0, 1.0);
242         drawGearGL(1);
243         glPopMatrix();
244
245         glPushMatrix();
246         glTranslatef(3.1f, -2.0f, 0.0f);
247         glRotatef(-2.0 * fAngle - 9.0, 0.0, 0.0, 1.0);
248         drawGearGL(2);
249         glPopMatrix();
250
251         glPushMatrix();
252         glTranslatef(-3.1f, 2.2f, -1.8f);
253         glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
254         glRotatef(2.0 * fAngle - 2.0, 0.0, 0.0, 1.0);
255         drawGearGL(3);
256         glPopMatrix();
257 }
258
259
260 static void View(GHOST_IWindow *window, bool stereo, int eye = 0)
261 {
262         window->activateDrawingContext();
263         GHOST_Rect bnds;
264         int noOfScanlines = 0, lowerScanline = 0;
265         int verticalBlankingInterval = 32;  // hard coded for testing purposes, display device dependant
266         float left, right, bottom, top;
267         float nearplane, farplane, zeroPlane, distance;
268         float eyeSeparation = 0.62f;
269         window->getClientBounds(bnds);
270
271         // viewport
272         if (stereo)
273         {
274                 if (nVidiaWindows)
275                 { 
276                         // handled by nVidia driver so act as normal (explicitly put here since
277                         // it -is- stereo)
278                         glViewport(0, 0, bnds.getWidth(), bnds.getHeight());
279                 }
280                 else { // generic cross platform above-below stereo
281                         noOfScanlines = (bnds.getHeight() - verticalBlankingInterval) / 2;
282                         switch (eye)
283                         {
284                                 case LEFT_EYE:
285                                         // upper half of window
286                                         lowerScanline = bnds.getHeight() - noOfScanlines;
287                                         break;
288                                 case RIGHT_EYE:
289                                         // lower half of window
290                                         lowerScanline = 0;
291                                         break;
292                         }
293                 }
294         }
295         else {
296                 noOfScanlines = bnds.getHeight();
297                 lowerScanline = 0;
298         }
299
300         glViewport(0, lowerScanline, bnds.getWidth(), noOfScanlines);
301
302         // projection
303         left = -6.0;
304         right = 6.0;
305         bottom = -4.8f;
306         top = 4.8f;
307         nearplane = 5.0;
308         farplane = 60.0;
309
310         if (stereo)
311         {
312                 zeroPlane = 0.0;
313                 distance = 14.5;
314                 switch (eye)
315                 {
316                         case LEFT_EYE:
317                                 StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, -eyeSeparation / 2.0);
318                                 break;
319                         case RIGHT_EYE:
320                                 StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, eyeSeparation / 2.0);
321                                 break;
322                 }
323         }
324         else {
325 //              left = -w;
326 //              right = w;
327 //              bottom = -h;
328 //              top = h;
329                 glMatrixMode(GL_PROJECTION);
330                 glLoadIdentity();
331                 glFrustum(left, right, bottom, top, 5.0, 60.0);
332                 glMatrixMode(GL_MODELVIEW);
333                 glLoadIdentity();
334                 glTranslatef(0.0, 0.0, -40.0);
335
336         }
337
338         glClearColor(.2f, 0.0f, 0.0f, 0.0f);
339 }
340
341
342 void StereoProjection(float left, float right, float bottom, float top, float nearplane, float farplane,
343                 float zero_plane, float dist,
344                 float eye)
345 /* Perform the perspective projection for one eye's subfield.
346  * The projection is in the direction of the negative z axis.
347  *
348  * -6.0, 6.0, -4.8, 4.8,
349  * left, right, bottom, top = the coordinate range, in the plane of zero
350  * parallax setting, which will be displayed on the screen.  The
351  * ratio between (right-left) and (top-bottom) should equal the aspect
352  * ratio of the display.
353  *
354  * 6.0, -6.0,
355  * near, far = the z-coordinate values of the clipping planes.
356  *
357  * 0.0,
358  * zero_plane = the z-coordinate of the plane of zero parallax setting.
359  *
360  * 14.5,
361  * dist = the distance from the center of projection to the plane
362  * of zero parallax.
363  *
364  * -0.31
365  * eye = half the eye separation; positive for the right eye subfield,
366  * negative for the left eye subfield.
367  */
368 {
369         float xmid, ymid, clip_near, clip_far, topw, bottomw, leftw, rightw,
370               dx, dy, n_over_d;
371
372         dx = right - left;
373         dy = top - bottom;
374
375         xmid = (right + left) / 2.0;
376         ymid = (top + bottom) / 2.0;
377
378         clip_near = dist + zero_plane - nearplane;
379         clip_far  = dist + zero_plane - farplane;
380
381         n_over_d = clip_near / dist;
382
383         topw = n_over_d * dy / 2.0;
384         bottomw = -topw;
385         rightw = n_over_d * (dx / 2.0 - eye);
386         leftw  = n_over_d * (-dx / 2.0 - eye);
387
388         /* Need to be in projection mode for this. */
389         glLoadIdentity();
390         glFrustum(leftw,  rightw,  bottomw,  topw,  clip_near,  clip_far);
391
392         glTranslatef(-xmid - eye,  -ymid,  -zero_plane - dist);
393         return;
394 } /* stereoproj */
395
396
397 class Application : public GHOST_IEventConsumer {
398 public:
399         Application(GHOST_ISystem *system);
400         ~Application(void);
401         virtual bool processEvent(GHOST_IEvent *event);
402
403         GHOST_ISystem *m_system;
404         GHOST_IWindow *m_mainWindow;
405         GHOST_IWindow *m_secondaryWindow;
406         GHOST_IWindow *m_fullScreenWindow;
407         GHOST_ITimerTask *m_gearsTimer, *m_testTimer;
408         GHOST_TStandardCursor m_cursor;
409         bool m_exitRequested;
410
411         bool stereo;
412 };
413
414
415 Application::Application(GHOST_ISystem *system)
416         : m_system(system), m_mainWindow(0), m_secondaryWindow(0), m_fullScreenWindow(0),
417         m_gearsTimer(0), m_testTimer(0), m_cursor(GHOST_kStandardCursorFirstCursor),
418         m_exitRequested(false), stereo(false)
419 {
420         fApp = this;
421
422         // Create the main window
423         STR_String title1("gears - main window");
424         m_mainWindow = system->createWindow(title1, 10, 64, 320, 200, GHOST_kWindowStateNormal,
425                                             GHOST_kDrawingContextTypeOpenGL, false, false);
426
427         if (!m_mainWindow) {
428                 std::cout << "could not create main window\n";
429                 exit(-1);
430         }
431
432         // Create a secondary window
433         STR_String title2("gears - secondary window");
434         m_secondaryWindow = system->createWindow(title2, 340, 64, 320, 200, GHOST_kWindowStateNormal,
435                                                  GHOST_kDrawingContextTypeOpenGL, false, false);
436         if (!m_secondaryWindow) {
437                 std::cout << "could not create secondary window\n";
438                 exit(-1);
439         }
440
441         // Install a timer to have the gears running
442         m_gearsTimer = system->installTimer(0 /*delay*/, 20 /*interval*/, gearsTimerProc, m_mainWindow);
443 }
444
445
446 Application::~Application(void)
447 {
448         // Dispose windows
449         if (m_system->validWindow(m_mainWindow)) {
450                 m_system->disposeWindow(m_mainWindow);
451         }
452         if (m_system->validWindow(m_secondaryWindow)) {
453                 m_system->disposeWindow(m_secondaryWindow);
454         }
455 }
456
457
458 bool Application::processEvent(GHOST_IEvent *event)
459 {
460         GHOST_IWindow *window = event->getWindow();
461         bool handled = true;
462
463         switch (event->getType()) {
464 #if 0
465         case GHOST_kEventUnknown:
466                 break;
467         case GHOST_kEventCursorButton:
468                 std::cout << "GHOST_kEventCursorButton"; break;
469         case GHOST_kEventCursorMove:
470                 std::cout << "GHOST_kEventCursorMove"; break;
471  #endif
472                 case GHOST_kEventWheel:
473                 {
474                         GHOST_TEventWheelData *wheelData = (GHOST_TEventWheelData *) event->getData();
475                         if (wheelData->z > 0)
476                         {
477                                 view_rotz += 5.f;
478                         }
479                         else {
480                                 view_rotz -= 5.f;
481                         }
482                 }
483                 break;
484
485                 case GHOST_kEventKeyUp:
486                         break;
487
488                 case GHOST_kEventKeyDown:
489                 {
490                         GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *) event->getData();
491                         switch (keyData->key) {
492                                 case GHOST_kKeyC:
493                                 {
494                                         int cursor = m_cursor;
495                                         cursor++;
496                                         if (cursor >= GHOST_kStandardCursorNumCursors) {
497                                                 cursor = GHOST_kStandardCursorFirstCursor;
498                                         }
499                                         m_cursor = (GHOST_TStandardCursor)cursor;
500                                         window->setCursorShape(m_cursor);
501                                 }
502                                 break;
503
504                                 case GHOST_kKeyE:
505                                 {
506                                         int x = 200, y = 200;
507                                         m_system->setCursorPosition(x, y);
508                                         break;
509                                 }
510
511                                 case GHOST_kKeyF:
512                                         if (!m_system->getFullScreen()) {
513                                                 // Begin fullscreen mode
514                                                 GHOST_DisplaySetting setting;
515
516                                                 setting.bpp = 16;
517                                                 setting.frequency = 50;
518                                                 setting.xPixels = 640;
519                                                 setting.yPixels = 480;
520                                                 m_system->beginFullScreen(setting, &m_fullScreenWindow, false /* stereo flag */);
521                                         }
522                                         else {
523                                                 m_system->endFullScreen();
524                                                 m_fullScreenWindow = 0;
525                                         }
526                                         break;
527
528                                 case GHOST_kKeyH:
529                                         window->setCursorVisibility(!window->getCursorVisibility());
530                                         break;
531
532                                 case GHOST_kKeyM:
533                                 {
534                                         bool down = false;
535                                         m_system->getModifierKeyState(GHOST_kModifierKeyLeftShift, down);
536                                         if (down) {
537                                                 std::cout << "left shift down\n";
538                                         }
539                                         m_system->getModifierKeyState(GHOST_kModifierKeyRightShift, down);
540                                         if (down) {
541                                                 std::cout << "right shift down\n";
542                                         }
543                                         m_system->getModifierKeyState(GHOST_kModifierKeyLeftAlt, down);
544                                         if (down) {
545                                                 std::cout << "left Alt down\n";
546                                         }
547                                         m_system->getModifierKeyState(GHOST_kModifierKeyRightAlt, down);
548                                         if (down) {
549                                                 std::cout << "right Alt down\n";
550                                         }
551                                         m_system->getModifierKeyState(GHOST_kModifierKeyLeftControl, down);
552                                         if (down) {
553                                                 std::cout << "left control down\n";
554                                         }
555                                         m_system->getModifierKeyState(GHOST_kModifierKeyRightControl, down);
556                                         if (down) {
557                                                 std::cout << "right control down\n";
558                                         }
559                                 }
560                                 break;
561
562                                 case GHOST_kKeyQ:
563                                         if (m_system->getFullScreen())
564                                         {
565                                                 m_system->endFullScreen();
566                                                 m_fullScreenWindow = 0;
567                                         }
568                                         m_exitRequested = true;
569                                         break;
570
571                                 case GHOST_kKeyS: // toggle mono and stereo
572                                         if (stereo)
573                                                 stereo = false;
574                                         else
575                                                 stereo = true;
576                                         break;
577
578                                 case GHOST_kKeyT:
579                                         if (!m_testTimer) {
580                                                 m_testTimer = m_system->installTimer(0, 1000, testTimerProc);
581                                         }
582
583                                         else {
584                                                 m_system->removeTimer(m_testTimer);
585                                                 m_testTimer = 0;
586                                         }
587
588                                         break;
589
590                                 case GHOST_kKeyW:
591                                         if (m_mainWindow)
592                                         {
593                                                 STR_String title;
594                                                 m_mainWindow->getTitle(title);
595                                                 title += "-";
596                                                 m_mainWindow->setTitle(title);
597
598                                         }
599                                         break;
600
601                                 default:
602                                         break;
603                         }
604                 }
605                 break;
606
607                 case GHOST_kEventWindowClose:
608                 {
609                         GHOST_IWindow *window2 = event->getWindow();
610                         if (window2 == m_mainWindow) {
611                                 m_exitRequested = true;
612                         }
613                         else {
614                                 m_system->disposeWindow(window2);
615                         }
616                 }
617                 break;
618
619                 case GHOST_kEventWindowActivate:
620                         handled = false;
621                         break;
622
623                 case GHOST_kEventWindowDeactivate:
624                         handled = false;
625                         break;
626
627                 case GHOST_kEventWindowUpdate:
628                 {
629                         GHOST_IWindow *window2 = event->getWindow();
630                         if (!m_system->validWindow(window2))
631                                 break;
632
633                         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
634
635                         if (stereo)
636                         {
637                                 View(window2, stereo, LEFT_EYE);
638                                 glPushMatrix();
639                                 RenderCamera();
640                                 RenderScene();
641                                 glPopMatrix();
642
643                                 View(window2, stereo, RIGHT_EYE);
644                                 glPushMatrix();
645                                 RenderCamera();
646                                 RenderScene();
647                                 glPopMatrix();
648                         }
649                         else {
650                                 View(window2, stereo);
651                                 glPushMatrix();
652                                 RenderCamera();
653                                 RenderScene();
654                                 glPopMatrix();
655                         }
656                         window2->swapBuffers();
657                 }
658                 break;
659                 
660                 default:
661                         handled = false;
662                         break;
663         }
664         return handled;
665 }
666
667
668 int main(int /*argc*/, char ** /*argv*/)
669 {
670         nVidiaWindows = false;
671 //      nVidiaWindows = true;
672
673 #ifdef WIN32
674         /* Set a couple of settings in the registry for the nVidia detonator driver.
675          * So this is very specific...
676          */
677         if (nVidiaWindows)
678         {
679                 LONG lresult;
680                 HKEY hkey = 0;
681                 DWORD dwd = 0;
682                 //unsigned char buffer[128];
683
684                 CRegKey regkey;
685                 //DWORD keyValue;
686 //              lresult = regkey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable");
687                 lresult = regkey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable",
688                                       KEY_ALL_ACCESS);
689
690                 if (lresult == ERROR_SUCCESS)
691                         printf("Succesfully opened key\n");
692 #if 0
693                 lresult = regkey.QueryValue(&keyValue, "StereoEnable");
694                 if (lresult == ERROR_SUCCESS)
695                         printf("Succesfully queried key\n");
696 #endif
697                 lresult = regkey.SetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable",
698                                           "1");
699                 if (lresult == ERROR_SUCCESS)
700                         printf("Succesfully set value for key\n");
701                 regkey.Close();
702                 if (lresult == ERROR_SUCCESS)
703                         printf("Succesfully closed key\n");
704 //              regkey.Write("2");
705         }
706 #endif  // WIN32
707
708         // Create the system
709         GHOST_ISystem::createSystem();
710         fSystem = GHOST_ISystem::getSystem();
711
712         if (fSystem) {
713                 // Create an application object
714                 Application app(fSystem);
715
716                 // Add the application as event consumer
717                 fSystem->addEventConsumer(&app);
718                 
719                 // Enter main loop
720                 while (!app.m_exitRequested) {
721                         //printf("main: loop\n");
722                         fSystem->processEvents(true);
723                         fSystem->dispatchEvents();
724                 }
725         }
726
727         // Dispose the system
728         GHOST_ISystem::disposeSystem();
729
730         return 0;
731 }
732
733
734 static void gearsTimerProc(GHOST_ITimerTask *task, GHOST_TUns64 /*time*/)
735 {
736         fAngle += 2.0;
737         view_roty += 1.0;
738         GHOST_IWindow *window = (GHOST_IWindow *)task->getUserData();
739         if (fApp->m_fullScreenWindow) {
740                 // Running full screen
741                 fApp->m_fullScreenWindow->invalidate();
742         }
743         else {
744                 if (fSystem->validWindow(window)) {
745                         window->invalidate();
746                 }
747         }
748 }