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

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