GHOST_Test.cpp 21 KB

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