Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SDLUnitTest.cpp 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
  2. #ifdef SDL_UNIT_TEST
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #ifdef USING_OPENGL
  7. #ifdef __APPLE__
  8. #include <OpenGL/gl.h>
  9. #include <OpenGL/glu.h>
  10. #else
  11. #include <GL/gl.h>
  12. #include <GL/glu.h>
  13. #endif
  14. # include <SDL/SDL.h>
  15. # include <Texture.h>
  16. // Implement these functions in your Unit Test
  17. void renderScene(float time, float lastTime);
  18. void handleKey(int key);
  19. void handleArgKey(char key);
  20. void initScene(int argc, char *argv[]);
  21. // Call this function to start SDL Unit Test
  22. int runSDLUnitTest(int argc, char *argv[]);
  23. //////////////////////////////////////////////////////////////////
  24. Texture gTexture;
  25. char gTitle[128];
  26. float gYaw = 0.0f;
  27. bool gYawOn = true;
  28. float gPitch = -20.0f;
  29. float gScale = 1.0f;
  30. float gLightPos[] = { 0.0, 512.0, 1024.0, 0.0 };
  31. unsigned int gWidth = 640, gHeight = 460;
  32. void event_resize(unsigned int width, unsigned int height);
  33. void handle_key(int key)
  34. {
  35. static bool wireframe = false;
  36. static bool alphaBlend = false;
  37. static bool lighting = false;
  38. switch (key)
  39. {
  40. case SDLK_F5:
  41. wireframe = !wireframe;
  42. if (wireframe)
  43. {
  44. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  45. }
  46. else
  47. {
  48. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  49. }
  50. printf("%sabled wireframe rendering\n", wireframe ? "En" : "Dis");
  51. break;
  52. case SDLK_F6:
  53. alphaBlend = !alphaBlend;
  54. if (alphaBlend)
  55. {
  56. glEnable(GL_BLEND);
  57. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  58. glAlphaFunc(GL_GREATER, 0);
  59. }
  60. else
  61. {
  62. glDisable(GL_BLEND);
  63. }
  64. printf("%sabled alpha blending\n", alphaBlend ? "En" : "Dis");
  65. break;
  66. case SDLK_F7:
  67. lighting = !lighting;
  68. if (lighting)
  69. {
  70. static bool firsttime = true;
  71. glEnable(GL_LIGHTING);
  72. if (firsttime)
  73. {
  74. float specular[] = { 0.6, 0.6, 0.6, 1.0 };
  75. float ambient[] = { 0.64, 0.64, 0.64, 1.0 };
  76. float shine[] = { 50.0 };
  77. // Caustic fx possible with mod amb?
  78. glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
  79. glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
  80. //glMaterialfv(GL_FRONT, GL_DIFFUSE, ambient);
  81. glMaterialfv(GL_FRONT, GL_SHININESS, shine);
  82. glLightfv(GL_LIGHT0, GL_POSITION, gLightPos);
  83. glEnable(GL_LIGHT0);
  84. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
  85. //glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
  86. //glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, WHITE);
  87. //glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, WHITE);
  88. //glLightModelfv(GL_LIGHT_MODEL_AMBIENT, DIM_WHITE);
  89. //glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, cutoff);
  90. //glLightfv(GL_LIGHT0, GL_POSITION, pos);
  91. //glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir);
  92. //glLightfv(GL_LIGHT0, GL_DIFFUSE, color);
  93. firsttime = false;
  94. }
  95. }
  96. else
  97. {
  98. glDisable(GL_LIGHTING);
  99. }
  100. break;
  101. case SDLK_F8:
  102. gYawOn = !gYawOn;
  103. break;
  104. case SDLK_F9:
  105. gTexture.glScreenShot("screenshot", gWidth, gHeight);
  106. break;
  107. case SDLK_F10:
  108. event_resize(640, 460);
  109. break;
  110. case SDLK_F11:
  111. event_resize(800, 600);
  112. break;
  113. case SDLK_F12:
  114. event_resize(1024, 768);
  115. break;
  116. case SDLK_RIGHT:
  117. ++gYaw;
  118. break;
  119. case SDLK_LEFT:
  120. --gYaw;
  121. break;
  122. case SDLK_UP:
  123. ++gPitch;
  124. break;
  125. case SDLK_DOWN:
  126. --gPitch;
  127. break;
  128. case '-':
  129. if (gScale *= 0.75f > 0.000001)
  130. gScale *= 0.75f;
  131. break;
  132. case '=':
  133. gScale *= 1.25f;
  134. break;
  135. case 'i':
  136. gLightPos[1] += 16.0f;
  137. glLightfv(GL_LIGHT0, GL_POSITION, gLightPos);
  138. break;
  139. case 'k':
  140. gLightPos[1] -= 16.0f;
  141. glLightfv(GL_LIGHT0, GL_POSITION, gLightPos);
  142. break;
  143. case 'j':
  144. gLightPos[2] -= 16.0f;
  145. glLightfv(GL_LIGHT0, GL_POSITION, gLightPos);
  146. break;
  147. case 'l':
  148. gLightPos[2] += 16.0f;
  149. glLightfv(GL_LIGHT0, GL_POSITION, gLightPos);
  150. break;
  151. case 'h':
  152. printf("[SDLUnitTest.test]\n");
  153. printf("----------------------------------\n");
  154. printf("ESC - Exit\n");
  155. printf("F5 - Toggle wireframe rendering\n");
  156. printf("F6 - Toggle alpha blending\n");
  157. printf("F8 - Toggle scene rotation\n");
  158. printf("F7 - Toggle lighting\n");
  159. printf("F9 - Take screenshot\n");
  160. printf("F11 - Set window to 640x460\n");
  161. printf("F11 - Set window to 800x600\n");
  162. printf("F12 - Set window to 1024x768\n");
  163. printf("ALT+ENTER - Toogle fullscreen\n");
  164. printf("UP/DOWN - Adjust scene pitch\n");
  165. printf("RIGHT/LEFT - Adjust scene yaw\n");
  166. printf("-/= - Adjust model scaling\n");
  167. printf("----------------------------------\n");
  168. printf("i,k,j,l - Move light\n");
  169. printf("h - Help\n");
  170. default:
  171. handleKey(key);
  172. }
  173. }
  174. ///////////////////////////////////////////////////
  175. SDL_Surface *gSDLWindow = NULL;
  176. void updateWindowTitle(char *newTitle)
  177. {
  178. static char title[64];
  179. memcpy(title, newTitle, 64);
  180. title[63] = 0;
  181. SDL_WM_SetCaption(title, "PSKModel.test");
  182. }
  183. unsigned int getTicks()
  184. {
  185. return SDL_GetTicks();
  186. }
  187. void swap_buffers()
  188. {
  189. SDL_GL_SwapBuffers();
  190. }
  191. void event_resize(unsigned int width, unsigned int height)
  192. {
  193. GLfloat aspect;
  194. gWidth = width;
  195. gHeight = height;
  196. aspect = (GLfloat)width/(GLfloat)height;
  197. glViewport(0, 0, width, height);
  198. glMatrixMode(GL_PROJECTION);
  199. glLoadIdentity();
  200. gluPerspective(45.0f, aspect, 8.0f, 4600.0f);
  201. glMatrixMode(GL_MODELVIEW);
  202. glLoadIdentity();
  203. // Resize window
  204. gSDLWindow = SDL_SetVideoMode(width, height, 16, SDL_OPENGL);
  205. }
  206. #ifdef FIXME
  207. void draw_axis(float length, float arrowLenght)
  208. {
  209. /* Draw axis list to show bone orientation */
  210. glBegin(GL_LINES);
  211. /* X axis */
  212. glColor3f(1.0f, 0.0f, 0.0f);
  213. glVertex3f(-8.0f, 0.0f, 0.0f);
  214. glVertex3f(8.0f, 0.0f, 0.0f);
  215. /* X direction */
  216. glVertex3f(8.0f, 0.0f, 0.0f);
  217. glVertex3f(7.0f, 1.0f, 0.0f);
  218. glVertex3f(8.0f, 0.0f, 0.0f);
  219. glVertex3f(7.0f, -1.0f, 0.0f);
  220. /* Y axis */
  221. glColor3f(0.0f, 1.0f, 0.0f);
  222. glVertex3f(0.0f, -8.0f, 0.0f);
  223. glVertex3f(0.0f, 8.0f, 0.0f);
  224. /* Y direction */
  225. glVertex3f(0.0f, 8.0f, 0.0f);
  226. glVertex3f(0.0f, 7.0f, 1.0f);
  227. glVertex3f(0.0f, 8.0f, 0.0f);
  228. glVertex3f(0.0f, 7.0f, -1.0f);
  229. /* Z axis */
  230. glColor3f(0.0f, 0.0f, 1.0f);
  231. glVertex3f(0.0f, 0.0f, -8.0f);
  232. glVertex3f(0.0f, 0.0f, 8.0f);
  233. /* Z direction */
  234. glVertex3f(0.0f, 0.0f, 8.0f);
  235. glVertex3f(0.0f, 1.0f, 7.0f);
  236. glVertex3f(0.0f, 0.0f, 8.0f);
  237. glVertex3f(0.0f, -1.0f, 7.0f);
  238. glEnd();
  239. }
  240. #endif
  241. void renderUnitTestScene()
  242. {
  243. static float lastTime = 0.0f;
  244. const float size = 500.0f, step = 50.0f;
  245. float x, y, time;
  246. gluLookAt(0.0, 0.0, -256.0,
  247. 0.0, 8.0, 0.0,
  248. 0.0, 1.0, 0.0);
  249. glDisable(GL_TEXTURE_2D);
  250. time = getTicks() * 0.1f;
  251. if (time - lastTime > 5.0f)
  252. {
  253. lastTime = time;
  254. if (gYawOn)
  255. ++gYaw;
  256. }
  257. #ifdef DRAW_ACTUAL_ORIGIN_AXIS_WITH_ROTATION
  258. glPushMatrix();
  259. glRotatef(yaw, 0, 1, 0);
  260. glBegin(GL_LINES);
  261. glColor3f(1.0f, 0.0f, 0.0f);
  262. glVertex3f(0.0f, 0.0f, 0.0f);
  263. glVertex3f(10.0f, 0.0f, 0.0f);
  264. glColor3f(0.0f, 1.0f, 0.0f);
  265. glVertex3f(0.0f, 0.0f, 0.0f);
  266. glVertex3f(0.0f, 10.0f, 0.0f);
  267. glColor3f(0.0f, 0.0f, 1.0f);
  268. glVertex3f(0.0f, 0.0f, 0.0f);
  269. glVertex3f(0.0f, 0.0f, 10.0f);
  270. glEnd();
  271. glPopMatrix();
  272. #endif
  273. // Draw light symbol
  274. glPushMatrix();
  275. glTranslatef(gLightPos[0], gLightPos[1], gLightPos[2]);
  276. glBegin(GL_LINES);
  277. glColor3f(1.0f, 1.0f, 1.0f);
  278. glVertex3f(0.0f, 0.0f, 0.0f);
  279. glVertex3f(10.0f, 0.0f, 0.0f);
  280. glVertex3f(0.0f, 0.0f, 0.0f);
  281. glVertex3f(0.0f, 10.0f, 0.0f);
  282. glVertex3f(0.0f, 0.0f, 0.0f);
  283. glVertex3f(0.0f, 0.0f, 10.0f);
  284. glEnd();
  285. glPopMatrix();
  286. glTranslatef(0.0f, -128.0f, 512.0f);
  287. glRotatef(gPitch, 1, 0, 0);
  288. glRotatef(gYaw, 0, 1, 0);
  289. // Draw transformed origin axis
  290. glBegin(GL_LINES);
  291. glColor3f(1.0f, 0.0f, 0.0f);
  292. glVertex3f(-30.0f, 0.0f, 0.0f);
  293. glVertex3f(30.0f, 0.0f, 0.0f);
  294. glColor3f(0.0f, 1.0f, 0.0f);
  295. glVertex3f(0.0f, -30.0f, 0.0f);
  296. glVertex3f(0.0f, 30.0f, 0.0f);
  297. glColor3f(0.0f, 0.0f, 1.0f);
  298. glVertex3f(0.0f, 0.0f, -30.0f);
  299. glVertex3f(0.0f, 0.0f, 30.0f);
  300. glEnd();
  301. // Draw grid
  302. glPushMatrix();
  303. glScalef(2.0f, 2.0f, 2.0f);
  304. glColor3f(0.4f, 0.4f, 0.6f);
  305. for (x = -size; x < size; x += step)
  306. {
  307. glBegin(GL_LINE_LOOP);
  308. for (y = -size; y < size; y += step)
  309. {
  310. glVertex3f(x + step, 0.0f, y);
  311. glVertex3f(x, 0.0f, y);
  312. glVertex3f(x, 0.0f, y + step);
  313. glVertex3f(x + step, 0.0f, y + step);
  314. }
  315. glEnd();
  316. }
  317. glPopMatrix();
  318. glEnable(GL_TEXTURE_2D);
  319. glColor3f(1.0f, 1.0f, 1.0f);
  320. glPushMatrix();
  321. glTranslatef(0.0f, 8.0f, 0.0f);
  322. glScalef(gScale, gScale, gScale);
  323. renderScene(time, lastTime);
  324. glPopMatrix();
  325. }
  326. void event_display(int width, int height)
  327. {
  328. glClearColor(0.3, 0.3, 0.5, 1.0);
  329. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  330. glLoadIdentity();
  331. renderUnitTestScene();
  332. glFlush();
  333. swap_buffers();
  334. }
  335. void shutdown_gl()
  336. {
  337. SDL_Quit();
  338. }
  339. void init_gl(unsigned int width, unsigned int height)
  340. {
  341. // Print driver support information
  342. printf("\n\n\t## GL Driver Info ##\n");
  343. printf("\tVendor : %s\n", glGetString(GL_VENDOR));
  344. printf("\tRenderer : %s\n", glGetString(GL_RENDERER));
  345. printf("\tVersion : %s\n", glGetString(GL_VERSION));
  346. printf("\tExtensions : %s\n\n\n", (char*)glGetString(GL_EXTENSIONS));
  347. // Setup GL
  348. glClearColor(0.3, 0.3, 0.5, 1.0);
  349. event_resize(width, height);
  350. // Texture setup
  351. //gTexture.reset();
  352. //gTexture.setMaxTextureCount(64);
  353. }
  354. int main_gl(int argc, char *argv[])
  355. {
  356. SDL_Event event;
  357. unsigned int mkeys, mod, key, flags;
  358. unsigned int width = gWidth;
  359. unsigned int height = gHeight;
  360. bool fullscreen = false;
  361. char *driver = 0x0;
  362. // Setup clean up on exit
  363. atexit(shutdown_gl);
  364. // NOTE: Removed fullscreen/driver option parser args
  365. // Create GL context
  366. SDL_Init(SDL_INIT_VIDEO);
  367. printf("\n@Created OpenGL Context...\n");
  368. if (!driver || !driver[0] || SDL_GL_LoadLibrary(driver) < 0)
  369. {
  370. SDL_ClearError();
  371. // Fallback 1
  372. if (SDL_GL_LoadLibrary("libGL.so") < 0)
  373. {
  374. SDL_ClearError();
  375. // Fallback 2
  376. if (SDL_GL_LoadLibrary("libGL.so.1") < 0)
  377. {
  378. fprintf(stderr, "main_gl> SDL_GL_LoadLibrary failed!\n");
  379. fprintf(stderr, "main_gl> Error is [%s].\n", SDL_GetError());
  380. exit(1);
  381. }
  382. }
  383. }
  384. flags = SDL_OPENGL;
  385. if (fullscreen)
  386. {
  387. flags |= SDL_FULLSCREEN;
  388. SDL_ShowCursor(SDL_DISABLE);
  389. }
  390. SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
  391. SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
  392. SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
  393. SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
  394. SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  395. gSDLWindow = SDL_SetVideoMode(width, height, 16, flags);
  396. SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
  397. // Init rendering
  398. init_gl(width, height);
  399. initScene(argc, argv);
  400. printf("\n@Starting event loop...\n");
  401. updateWindowTitle(argv[0]);
  402. for (;;)
  403. {
  404. while (SDL_PollEvent(&event))
  405. {
  406. switch (event.type)
  407. {
  408. case SDL_QUIT:
  409. exit(0);
  410. break;
  411. case SDL_MOUSEMOTION:
  412. break;
  413. case SDL_MOUSEBUTTONDOWN:
  414. case SDL_MOUSEBUTTONUP:
  415. break;
  416. case SDL_KEYDOWN:
  417. mkeys = (unsigned int)SDL_GetModState();
  418. mod = 0;
  419. if (mkeys & KMOD_LSHIFT)
  420. mod |= KMOD_LSHIFT;
  421. if (mkeys & KMOD_RSHIFT)
  422. mod |= KMOD_RSHIFT;
  423. if (mkeys & KMOD_LCTRL)
  424. mod |= KMOD_LCTRL;
  425. if (mkeys & KMOD_RCTRL)
  426. mod |= KMOD_RCTRL;
  427. if (mkeys & KMOD_LALT)
  428. mod |= KMOD_LALT;
  429. if (mkeys & KMOD_RALT)
  430. mod |= KMOD_RALT;
  431. key = event.key.keysym.sym;
  432. switch (key)
  433. {
  434. case SDLK_ESCAPE: // 0x1B, 27d, ESC
  435. exit(0);
  436. break;
  437. case SDLK_RETURN:
  438. if (mod & KMOD_LALT)
  439. {
  440. SDL_ShowCursor(SDL_DISABLE);
  441. SDL_WM_ToggleFullScreen(gSDLWindow);
  442. }
  443. }
  444. handle_key(key);
  445. break;
  446. case SDL_KEYUP:
  447. break;
  448. case SDL_VIDEORESIZE:
  449. event_resize(event.resize.w, event.resize.h);
  450. width = event.resize.w;
  451. height = event.resize.h;
  452. event_display(width, height);
  453. break;
  454. }
  455. }
  456. event_display(width, height);
  457. }
  458. return 0;
  459. }
  460. #endif
  461. int runSDLUnitTest(int argc, char *argv[])
  462. {
  463. handle_key('h');
  464. if (argc > 1)
  465. {
  466. for (int i = 0; argv[1][i] != 0; ++i)
  467. {
  468. switch (argv[1][i])
  469. {
  470. default:
  471. handleArgKey(argv[1][i]);
  472. }
  473. }
  474. }
  475. else
  476. {
  477. printf("'%s h' for help\n", argv[0]);
  478. }
  479. #ifdef USING_OPENGL
  480. main_gl(argc, argv);
  481. #else
  482. printf("Build not OpenGL enabled\n");
  483. #endif
  484. return 0;
  485. }
  486. #endif