GHOST_C-Test.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  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. *
  22. * Simple test file for the GHOST library.
  23. * The OpenGL gear code is taken from the Qt sample code which,
  24. * in turn, is probably taken from somewhere as well.
  25. */
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <math.h>
  30. #define FALSE 0
  31. #include "GHOST_C-api.h"
  32. #if defined(WIN32) || defined(__APPLE__)
  33. # ifdef WIN32
  34. # include <windows.h>
  35. # include <GL/gl.h>
  36. # else /* WIN32 */
  37. /* __APPLE__ is defined */
  38. # include <AGL/gl.h>
  39. # endif /* WIN32 */
  40. #else /* defined(WIN32) || defined(__APPLE__) */
  41. # include <GL/gl.h>
  42. #endif /* defined(WIN32) || defined(__APPLE__) */
  43. static void gearsTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time);
  44. int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData);
  45. static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
  46. static GLfloat fAngle = 0.0;
  47. static int sExitRequested = 0;
  48. static GHOST_SystemHandle shSystem = NULL;
  49. static GHOST_WindowHandle sMainWindow = NULL;
  50. static GHOST_WindowHandle sSecondaryWindow = NULL;
  51. static GHOST_TStandardCursor sCursor = GHOST_kStandardCursorFirstCursor;
  52. static GHOST_WindowHandle sFullScreenWindow = NULL;
  53. static GHOST_TimerTaskHandle sTestTimer;
  54. static GHOST_TimerTaskHandle sGearsTimer;
  55. static void testTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time)
  56. {
  57. printf("timer1, time=%d\n", (int)time);
  58. }
  59. static void gearGL(
  60. GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
  61. {
  62. GLint i;
  63. GLfloat r0, r1, r2;
  64. GLfloat angle, da;
  65. GLfloat u, v, len;
  66. const double pi = 3.14159264;
  67. r0 = inner_radius;
  68. r1 = (float)(outer_radius - tooth_depth / 2.0);
  69. r2 = (float)(outer_radius + tooth_depth / 2.0);
  70. da = (float)(2.0 * pi / teeth / 4.0);
  71. glShadeModel(GL_FLAT);
  72. glNormal3f(0.0, 0.0, 1.0);
  73. /* draw front face */
  74. glBegin(GL_QUAD_STRIP);
  75. for (i = 0; i <= teeth; i++) {
  76. angle = (float)(i * 2.0 * pi / teeth);
  77. glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
  78. glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
  79. glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
  80. glVertex3f((float)(r1 * cos(angle + 3 * da)),
  81. (float)(r1 * sin(angle + 3 * da)),
  82. (float)(width * 0.5));
  83. }
  84. glEnd();
  85. /* draw front sides of teeth */
  86. glBegin(GL_QUADS);
  87. da = (float)(2.0 * pi / teeth / 4.0);
  88. for (i = 0; i < teeth; i++) {
  89. angle = (float)(i * 2.0 * pi / teeth);
  90. glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
  91. glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(width * 0.5));
  92. glVertex3f((float)(r2 * cos(angle + 2 * da)),
  93. (float)(r2 * sin(angle + 2 * da)),
  94. (float)(width * 0.5));
  95. glVertex3f((float)(r1 * cos(angle + 3 * da)),
  96. (float)(r1 * sin(angle + 3 * da)),
  97. (float)(width * 0.5));
  98. }
  99. glEnd();
  100. glNormal3f(0.0, 0.0, -1.0);
  101. /* draw back face */
  102. glBegin(GL_QUAD_STRIP);
  103. for (i = 0; i <= teeth; i++) {
  104. angle = (float)(i * 2.0 * pi / teeth);
  105. glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
  106. glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
  107. glVertex3f((float)(r1 * cos(angle + 3 * da)),
  108. (float)(r1 * sin(angle + 3 * da)),
  109. (float)(-width * 0.5));
  110. glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
  111. }
  112. glEnd();
  113. /* draw back sides of teeth */
  114. glBegin(GL_QUADS);
  115. da = (float)(2.0 * pi / teeth / 4.0);
  116. for (i = 0; i < teeth; i++) {
  117. angle = (float)(i * 2.0 * pi / teeth);
  118. glVertex3f((float)(r1 * cos(angle + 3 * da)),
  119. (float)(r1 * sin(angle + 3 * da)),
  120. (float)(-width * 0.5));
  121. glVertex3f((float)(r2 * cos(angle + 2 * da)),
  122. (float)(r2 * sin(angle + 2 * da)),
  123. (float)(-width * 0.5));
  124. glVertex3f(
  125. (float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(-width * 0.5));
  126. glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
  127. }
  128. glEnd();
  129. /* draw outward faces of teeth */
  130. glBegin(GL_QUAD_STRIP);
  131. for (i = 0; i < teeth; i++) {
  132. angle = (float)(i * 2.0 * pi / teeth);
  133. glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
  134. glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
  135. u = (float)(r2 * cos(angle + da) - r1 * cos(angle));
  136. v = (float)(r2 * sin(angle + da) - r1 * sin(angle));
  137. len = (float)(sqrt(u * u + v * v));
  138. u /= len;
  139. v /= len;
  140. glNormal3f(v, -u, 0.0);
  141. glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(width * 0.5));
  142. glVertex3f(
  143. (float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(-width * 0.5));
  144. glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
  145. glVertex3f((float)(r2 * cos(angle + 2 * da)),
  146. (float)(r2 * sin(angle + 2 * da)),
  147. (float)(width * 0.5));
  148. glVertex3f((float)(r2 * cos(angle + 2 * da)),
  149. (float)(r2 * sin(angle + 2 * da)),
  150. (float)(-width * 0.5));
  151. u = (float)(r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da));
  152. v = (float)(r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da));
  153. glNormal3f(v, -u, 0.0);
  154. glVertex3f((float)(r1 * cos(angle + 3 * da)),
  155. (float)(r1 * sin(angle + 3 * da)),
  156. (float)(width * 0.5));
  157. glVertex3f((float)(r1 * cos(angle + 3 * da)),
  158. (float)(r1 * sin(angle + 3 * da)),
  159. (float)(-width * 0.5));
  160. glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
  161. }
  162. glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(width * 0.5));
  163. glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(-width * 0.5));
  164. glEnd();
  165. glShadeModel(GL_SMOOTH);
  166. /* draw inside radius cylinder */
  167. glBegin(GL_QUAD_STRIP);
  168. for (i = 0; i <= teeth; i++) {
  169. angle = (float)(i * 2.0 * pi / teeth);
  170. glNormal3f((float)(-cos(angle)), (float)(-sin(angle)), 0.0);
  171. glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
  172. glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
  173. }
  174. glEnd();
  175. }
  176. static void drawGearGL(int id)
  177. {
  178. static GLfloat pos[4] = {5.0f, 5.0f, 10.0f, 1.0f};
  179. static GLfloat ared[4] = {0.8f, 0.1f, 0.0f, 1.0f};
  180. static GLfloat agreen[4] = {0.0f, 0.8f, 0.2f, 1.0f};
  181. static GLfloat ablue[4] = {0.2f, 0.2f, 1.0f, 1.0f};
  182. glLightfv(GL_LIGHT0, GL_POSITION, pos);
  183. glEnable(GL_CULL_FACE);
  184. glEnable(GL_LIGHTING);
  185. glEnable(GL_LIGHT0);
  186. glEnable(GL_DEPTH_TEST);
  187. switch (id) {
  188. case 1:
  189. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
  190. gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
  191. break;
  192. case 2:
  193. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
  194. gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
  195. break;
  196. case 3:
  197. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
  198. gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
  199. break;
  200. default:
  201. break;
  202. }
  203. glEnable(GL_NORMALIZE);
  204. }
  205. static void drawGL(void)
  206. {
  207. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  208. glPushMatrix();
  209. glRotatef(view_rotx, 1.0, 0.0, 0.0);
  210. glRotatef(view_roty, 0.0, 1.0, 0.0);
  211. glRotatef(view_rotz, 0.0, 0.0, 1.0);
  212. glPushMatrix();
  213. glTranslatef(-3.0, -2.0, 0.0);
  214. glRotatef(fAngle, 0.0, 0.0, 1.0);
  215. drawGearGL(1);
  216. glPopMatrix();
  217. glPushMatrix();
  218. glTranslatef(3.1f, -2.0f, 0.0f);
  219. glRotatef((float)(-2.0 * fAngle - 9.0), 0.0, 0.0, 1.0);
  220. drawGearGL(2);
  221. glPopMatrix();
  222. glPushMatrix();
  223. glTranslatef(-3.1f, 2.2f, -1.8f);
  224. glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
  225. glRotatef((float)(2.0 * fAngle - 2.0), 0.0, 0.0, 1.0);
  226. drawGearGL(3);
  227. glPopMatrix();
  228. glPopMatrix();
  229. }
  230. static void setViewPortGL(GHOST_WindowHandle hWindow)
  231. {
  232. GHOST_RectangleHandle hRect = NULL;
  233. GLfloat w, h;
  234. GHOST_ActivateWindowDrawingContext(hWindow);
  235. hRect = GHOST_GetClientBounds(hWindow);
  236. w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect);
  237. h = 1.0;
  238. glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect));
  239. glMatrixMode(GL_PROJECTION);
  240. glLoadIdentity();
  241. glFrustum(-w, w, -h, h, 5.0, 60.0);
  242. /* glOrtho(0, bnds.getWidth(), 0, bnds.getHeight(), -10, 10); */
  243. glMatrixMode(GL_MODELVIEW);
  244. glLoadIdentity();
  245. glTranslatef(0.0, 0.0, -40.0);
  246. glClearColor(.2f, 0.0f, 0.0f, 0.0f);
  247. glClear(GL_COLOR_BUFFER_BIT);
  248. GHOST_DisposeRectangle(hRect);
  249. }
  250. int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
  251. {
  252. int handled = 1;
  253. int cursor;
  254. int visibility;
  255. GHOST_TEventKeyData *keyData = NULL;
  256. GHOST_TEventWheelData *wheelData = NULL;
  257. GHOST_DisplaySetting setting;
  258. GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
  259. switch (GHOST_GetEventType(hEvent)) {
  260. #if 0
  261. case GHOST_kEventUnknown:
  262. break;
  263. case GHOST_kEventCursorButton:
  264. break;
  265. case GHOST_kEventCursorMove:
  266. break;
  267. #endif
  268. case GHOST_kEventWheel: {
  269. wheelData = (GHOST_TEventWheelData *)GHOST_GetEventData(hEvent);
  270. if (wheelData->z > 0) {
  271. view_rotz += 5.f;
  272. }
  273. else {
  274. view_rotz -= 5.f;
  275. }
  276. } break;
  277. case GHOST_kEventKeyUp:
  278. break;
  279. case GHOST_kEventKeyDown: {
  280. keyData = (GHOST_TEventKeyData *)GHOST_GetEventData(hEvent);
  281. switch (keyData->key) {
  282. case GHOST_kKeyC: {
  283. cursor = sCursor;
  284. cursor++;
  285. if (cursor >= GHOST_kStandardCursorNumCursors) {
  286. cursor = GHOST_kStandardCursorFirstCursor;
  287. }
  288. sCursor = (GHOST_TStandardCursor)cursor;
  289. GHOST_SetCursorShape(window, sCursor);
  290. } break;
  291. case GHOST_kKeyF:
  292. if (!GHOST_GetFullScreen(shSystem)) {
  293. /* Begin fullscreen mode */
  294. setting.bpp = 24;
  295. setting.frequency = 85;
  296. setting.xPixels = 640;
  297. setting.yPixels = 480;
  298. /*
  299. * setting.bpp = 16;
  300. * setting.frequency = 75;
  301. * setting.xPixels = 640;
  302. * setting.yPixels = 480;
  303. */
  304. sFullScreenWindow = GHOST_BeginFullScreen(shSystem,
  305. &setting,
  306. FALSE /* stereo flag */);
  307. }
  308. else {
  309. GHOST_EndFullScreen(shSystem);
  310. sFullScreenWindow = 0;
  311. }
  312. break;
  313. case GHOST_kKeyH: {
  314. visibility = GHOST_GetCursorVisibility(window);
  315. GHOST_SetCursorVisibility(window, !visibility);
  316. } break;
  317. case GHOST_kKeyQ:
  318. if (GHOST_GetFullScreen(shSystem)) {
  319. GHOST_EndFullScreen(shSystem);
  320. sFullScreenWindow = 0;
  321. }
  322. sExitRequested = 1;
  323. case GHOST_kKeyT:
  324. if (!sTestTimer) {
  325. sTestTimer = GHOST_InstallTimer(shSystem, 0, 1000, testTimerProc, NULL);
  326. }
  327. else {
  328. GHOST_RemoveTimer(shSystem, sTestTimer);
  329. sTestTimer = 0;
  330. }
  331. break;
  332. case GHOST_kKeyW: {
  333. if (sMainWindow) {
  334. char *title = GHOST_GetTitle(sMainWindow);
  335. char *ntitle = malloc(strlen(title) + 2);
  336. sprintf(ntitle, "%s-", title);
  337. GHOST_SetTitle(sMainWindow, ntitle);
  338. free(ntitle);
  339. free(title);
  340. }
  341. } break;
  342. default:
  343. break;
  344. }
  345. } break;
  346. case GHOST_kEventWindowClose: {
  347. GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
  348. if (window2 == sMainWindow) {
  349. sExitRequested = 1;
  350. }
  351. else {
  352. if (sGearsTimer) {
  353. GHOST_RemoveTimer(shSystem, sGearsTimer);
  354. sGearsTimer = 0;
  355. }
  356. GHOST_DisposeWindow(shSystem, window2);
  357. }
  358. } break;
  359. case GHOST_kEventWindowActivate:
  360. handled = 0;
  361. break;
  362. case GHOST_kEventWindowDeactivate:
  363. handled = 0;
  364. break;
  365. case GHOST_kEventWindowUpdate: {
  366. GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
  367. if (!GHOST_ValidWindow(shSystem, window2))
  368. break;
  369. setViewPortGL(window2);
  370. drawGL();
  371. GHOST_SwapWindowBuffers(window2);
  372. } break;
  373. default:
  374. handled = 0;
  375. break;
  376. }
  377. return handled;
  378. }
  379. int main(int argc, char **argv)
  380. {
  381. GHOST_GLSettings glSettings = {0};
  382. char *title1 = "gears - main window";
  383. char *title2 = "gears - secondary window";
  384. GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(processEvent, NULL);
  385. /* Create the system */
  386. shSystem = GHOST_CreateSystem();
  387. GHOST_AddEventConsumer(shSystem, consumer);
  388. if (shSystem) {
  389. /* Create the main window */
  390. sMainWindow = GHOST_CreateWindow(shSystem,
  391. title1,
  392. 10,
  393. 64,
  394. 320,
  395. 200,
  396. GHOST_kWindowStateNormal,
  397. GHOST_kDrawingContextTypeOpenGL,
  398. glSettings);
  399. if (!sMainWindow) {
  400. printf("could not create main window\n");
  401. exit(-1);
  402. }
  403. /* Create a secondary window */
  404. sSecondaryWindow = GHOST_CreateWindow(shSystem,
  405. title2,
  406. 340,
  407. 64,
  408. 320,
  409. 200,
  410. GHOST_kWindowStateNormal,
  411. GHOST_kDrawingContextTypeOpenGL,
  412. glSettings);
  413. if (!sSecondaryWindow) {
  414. printf("could not create secondary window\n");
  415. exit(-1);
  416. }
  417. /* Install a timer to have the gears running */
  418. sGearsTimer = GHOST_InstallTimer(shSystem, 0, 10, gearsTimerProc, sMainWindow);
  419. /* Enter main loop */
  420. while (!sExitRequested) {
  421. if (!GHOST_ProcessEvents(shSystem, 0)) {
  422. #ifdef WIN32
  423. /* If there were no events, be nice to other applications */
  424. Sleep(10);
  425. #endif
  426. }
  427. GHOST_DispatchEvents(shSystem);
  428. }
  429. }
  430. /* Dispose windows */
  431. if (GHOST_ValidWindow(shSystem, sMainWindow)) {
  432. GHOST_DisposeWindow(shSystem, sMainWindow);
  433. }
  434. if (GHOST_ValidWindow(shSystem, sSecondaryWindow)) {
  435. GHOST_DisposeWindow(shSystem, sSecondaryWindow);
  436. }
  437. /* Dispose the system */
  438. GHOST_DisposeSystem(shSystem);
  439. return 0;
  440. }
  441. static void gearsTimerProc(GHOST_TimerTaskHandle hTask, GHOST_TUns64 time)
  442. {
  443. GHOST_WindowHandle hWindow = NULL;
  444. fAngle += 2.0;
  445. view_roty += 1.0;
  446. hWindow = (GHOST_WindowHandle)GHOST_GetTimerTaskUserData(hTask);
  447. if (GHOST_GetFullScreen(shSystem)) {
  448. /* Running full screen */
  449. GHOST_InvalidateWindow(sFullScreenWindow);
  450. }
  451. else {
  452. if (GHOST_ValidWindow(shSystem, hWindow)) {
  453. GHOST_InvalidateWindow(hWindow);
  454. }
  455. }
  456. }