helper.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. /**
  2. Helper code for tinyphysicsengine example programs which handle things like
  3. SDL rendering, I/O, small3dlib rendering etc.
  4. */
  5. #define TPE_LOG puts
  6. #include "../tinyphysicsengine.h"
  7. #include <SDL2/SDL.h>
  8. #include <math.h>
  9. #include <sys/time.h> // for measuring time
  10. #ifndef RES_X
  11. #define RES_X 640
  12. #endif
  13. #ifndef RES_Y
  14. #define RES_Y 480
  15. #endif
  16. #ifndef FPS
  17. #define FPS 30
  18. #endif
  19. #ifndef CAMERA_STEP
  20. #define CAMERA_STEP 100
  21. #endif
  22. #ifndef CAMERA_ROT_STEP
  23. #define CAMERA_ROT_STEP 5
  24. #endif
  25. #define MSPF (1000 / (FPS))
  26. #define S3L_RESOLUTION_X RES_X
  27. #define S3L_RESOLUTION_Y RES_Y
  28. #define S3L_PIXEL_FUNCTION s3l_drawPixel
  29. #ifndef SCALE_3D_RENDERING
  30. #define SCALE_3D_RENDERING 1 // helper divider for preveneting overflows
  31. #endif
  32. #define S3L_NEAR (S3L_FRACTIONS_PER_UNIT / (4 * SCALE_3D_RENDERING))
  33. #ifndef S3L_SORT
  34. #define S3L_SORT 0
  35. #endif
  36. #ifndef S3L_Z_BUFFER
  37. #define S3L_Z_BUFFER 1
  38. #endif
  39. #ifndef S3L_PERSPECTIVE_CORRECTION
  40. #define S3L_PERSPECTIVE_CORRECTION 2
  41. #endif
  42. #ifndef S3L_NEAR_CROSS_STRATEGY
  43. #define S3L_NEAR_CROSS_STRATEGY 2
  44. #endif
  45. #define S3L_USE_WIDER_TYPES 1
  46. #include "small3dlib.h"
  47. #define PIXELS_SIZE (S3L_RESOLUTION_X * S3L_RESOLUTION_Y * 4)
  48. S3L_Unit cubeVertices[] = { S3L_CUBE_VERTICES(TPE_FRACTIONS_PER_UNIT) };
  49. S3L_Index cubeTriangles[] = { S3L_CUBE_TRIANGLES };
  50. S3L_Model3D cubeModel;
  51. S3L_Unit triangleVertices[9];
  52. S3L_Index triangleTriangles[] = {0, 1, 2, 0, 2, 1};
  53. S3L_Model3D triangleModel;
  54. S3L_Unit planeVerices[] =
  55. {
  56. #define a S3L_FRACTIONS_PER_UNIT / 2
  57. #define b -1 * S3L_FRACTIONS_PER_UNIT / 2
  58. a,0,a,
  59. a,0,b,
  60. b,0,a,
  61. b,0,b
  62. #undef a
  63. #undef b
  64. };
  65. S3L_Index planeTriangles[] =
  66. { 0,2,1, 1,2,3 };
  67. S3L_Model3D planeModel;
  68. #define SPHERE_VERTEX_COUNT 42
  69. const S3L_Unit sphereVertices[SPHERE_VERTEX_COUNT * 3] = {
  70. 0, -512, 0, // 0
  71. 370, -228, -269, // 3
  72. -141, -228, -435, // 6
  73. -457, -228, 0, // 9
  74. -141, -228, 435, // 12
  75. 370, -228, 269, // 15
  76. 141, 228, -435, // 18
  77. -370, 228, -269, // 21
  78. -370, 228, 269, // 24
  79. 141, 228, 435, // 27
  80. 457, 228, 0, // 30
  81. 0, 512, 0, // 33
  82. -83, -435, -255, // 36
  83. 217, -435, -158, // 39
  84. 134, -269, -414, // 42
  85. 435, -269, 0, // 45
  86. 217, -435, 158, // 48
  87. -269, -435, 0, // 51
  88. -352, -269, -255, // 54
  89. -83, -435, 255, // 57
  90. -352, -269, 255, // 60
  91. 134, -269, 414, // 63
  92. 486, 0, -158, // 66
  93. 486, 0, 158, // 69
  94. 0, 0, -512, // 72
  95. 300, 0, -414, // 75
  96. -486, 0, -158, // 78
  97. -300, 0, -414, // 81
  98. -300, 0, 414, // 84
  99. -486, 0, 158, // 87
  100. 300, 0, 414, // 90
  101. 0, 0, 512, // 93
  102. 352, 269, -255, // 96
  103. -134, 269, -414, // 99
  104. -435, 269, 0, // 102
  105. -134, 269, 414, // 105
  106. 352, 269, 255, // 108
  107. 83, 435, -255, // 111
  108. 269, 435, 0, // 114
  109. -217, 435, -158, // 117
  110. -217, 435, 158, // 120
  111. 83, 435, 255 // 123
  112. }; // sphereVertices
  113. #define SPHERE_TRIANGLE_COUNT 80
  114. const S3L_Index sphereTriangleIndices[SPHERE_TRIANGLE_COUNT * 3] = {
  115. 0, 13, 12, // 0
  116. 1, 13, 15, // 3
  117. 0, 12, 17, // 6
  118. 0, 17, 19, // 9
  119. 0, 19, 16, // 12
  120. 1, 15, 22, // 15
  121. 2, 14, 24, // 18
  122. 3, 18, 26, // 21
  123. 4, 20, 28, // 24
  124. 5, 21, 30, // 27
  125. 1, 22, 25, // 30
  126. 2, 24, 27, // 33
  127. 3, 26, 29, // 36
  128. 4, 28, 31, // 39
  129. 5, 30, 23, // 42
  130. 6, 32, 37, // 45
  131. 7, 33, 39, // 48
  132. 8, 34, 40, // 51
  133. 9, 35, 41, // 54
  134. 10, 36, 38, // 57
  135. 38, 41, 11, // 60
  136. 38, 36, 41, // 63
  137. 36, 9, 41, // 66
  138. 41, 40, 11, // 69
  139. 41, 35, 40, // 72
  140. 35, 8, 40, // 75
  141. 40, 39, 11, // 78
  142. 40, 34, 39, // 81
  143. 34, 7, 39, // 84
  144. 39, 37, 11, // 87
  145. 39, 33, 37, // 90
  146. 33, 6, 37, // 93
  147. 37, 38, 11, // 96
  148. 37, 32, 38, // 99
  149. 32, 10, 38, // 102
  150. 23, 36, 10, // 105
  151. 23, 30, 36, // 108
  152. 30, 9, 36, // 111
  153. 31, 35, 9, // 114
  154. 31, 28, 35, // 117
  155. 28, 8, 35, // 120
  156. 29, 34, 8, // 123
  157. 29, 26, 34, // 126
  158. 26, 7, 34, // 129
  159. 27, 33, 7, // 132
  160. 27, 24, 33, // 135
  161. 24, 6, 33, // 138
  162. 25, 32, 6, // 141
  163. 25, 22, 32, // 144
  164. 22, 10, 32, // 147
  165. 30, 31, 9, // 150
  166. 30, 21, 31, // 153
  167. 21, 4, 31, // 156
  168. 28, 29, 8, // 159
  169. 28, 20, 29, // 162
  170. 20, 3, 29, // 165
  171. 26, 27, 7, // 168
  172. 26, 18, 27, // 171
  173. 18, 2, 27, // 174
  174. 24, 25, 6, // 177
  175. 24, 14, 25, // 180
  176. 14, 1, 25, // 183
  177. 22, 23, 10, // 186
  178. 22, 15, 23, // 189
  179. 15, 5, 23, // 192
  180. 16, 21, 5, // 195
  181. 16, 19, 21, // 198
  182. 19, 4, 21, // 201
  183. 19, 20, 4, // 204
  184. 19, 17, 20, // 207
  185. 17, 3, 20, // 210
  186. 17, 18, 3, // 213
  187. 17, 12, 18, // 216
  188. 12, 2, 18, // 219
  189. 15, 16, 5, // 222
  190. 15, 13, 16, // 225
  191. 13, 0, 16, // 228
  192. 12, 14, 2, // 231
  193. 12, 13, 14, // 234
  194. 13, 1, 14 // 237
  195. }; // sphereTriangleIndices
  196. S3L_Model3D sphereModel;
  197. #define MAX_BODIES 128
  198. #define MAX_JOINTS 1024
  199. #define MAX_CONNECTIONS 2048
  200. TPE_Body tpe_bodies[MAX_BODIES];
  201. TPE_Joint tpe_joints[MAX_JOINTS];
  202. TPE_Connection tpe_connections[MAX_CONNECTIONS];
  203. int helper_debugDrawOn = 0,
  204. helper_debugDrawOnCountdown = 0;
  205. unsigned int
  206. helper_jointsUsed = 0,
  207. helper_connectionsUsed = 0;
  208. TPE_World tpe_world;
  209. uint8_t sdl_pixels[PIXELS_SIZE];
  210. SDL_Window *sdl_window;
  211. SDL_Renderer *sdl_renderer;
  212. SDL_Texture *sdl_texture;
  213. SDL_Surface *sdl_screenSurface;
  214. int helper_frameStartTime;
  215. int helper_frameMsLeft;
  216. int helper_running;
  217. int helper_frame;
  218. const uint8_t *sdl_keyboard;
  219. S3L_Scene s3l_scene;
  220. S3L_Vec4 helper_cameraForw, helper_cameraRight, helper_cameraUp;
  221. unsigned long helper_getMicroSecs(void)
  222. {
  223. struct timeval t;
  224. gettimeofday(&t,NULL);
  225. return 1000000 * t.tv_sec + t.tv_usec;
  226. }
  227. void _helper_bodyAdded(int joints, int conns, TPE_Unit mass)
  228. {
  229. TPE_bodyInit(&tpe_bodies[tpe_world.bodyCount],
  230. &tpe_joints[helper_jointsUsed],joints,
  231. &tpe_connections[helper_connectionsUsed],conns,mass);
  232. helper_jointsUsed += joints;
  233. helper_connectionsUsed += conns;
  234. tpe_world.bodyCount++;
  235. }
  236. void helper_addBox(TPE_Unit w, TPE_Unit h, TPE_Unit d, TPE_Unit jointSize, TPE_Unit mass)
  237. {
  238. TPE_makeBox(
  239. tpe_joints + helper_jointsUsed,
  240. tpe_connections + helper_connectionsUsed,w,h,d,jointSize);
  241. _helper_bodyAdded(8,16,mass);
  242. }
  243. void helper_add2Line(TPE_Unit w, TPE_Unit jointSize, TPE_Unit mass)
  244. {
  245. TPE_make2Line(
  246. tpe_joints + helper_jointsUsed,
  247. tpe_connections + helper_connectionsUsed,w,jointSize);
  248. _helper_bodyAdded(2,1,mass);
  249. }
  250. void helper_addTriangle(TPE_Unit s, TPE_Unit d, TPE_Unit mass)
  251. {
  252. TPE_makeTriangle(
  253. tpe_joints + helper_jointsUsed,
  254. tpe_connections + helper_connectionsUsed,s,d);
  255. _helper_bodyAdded(3,3,mass);
  256. }
  257. void helper_addCenterRect(TPE_Unit w, TPE_Unit d, TPE_Unit jointSize, TPE_Unit mass)
  258. {
  259. TPE_makeCenterRect(
  260. tpe_joints + helper_jointsUsed,
  261. tpe_connections + helper_connectionsUsed,w,d,jointSize);
  262. _helper_bodyAdded(5,8,mass);
  263. }
  264. void helper_addRect(TPE_Unit w, TPE_Unit d, TPE_Unit jointSize, TPE_Unit mass)
  265. {
  266. TPE_makeRect(
  267. tpe_joints + helper_jointsUsed,
  268. tpe_connections + helper_connectionsUsed,w,d,jointSize);
  269. _helper_bodyAdded(4,6,mass);
  270. }
  271. void helper_addBall(TPE_Unit s, TPE_Unit mass)
  272. {
  273. tpe_joints[helper_jointsUsed] = TPE_joint(TPE_vec3(0,0,0),s);
  274. _helper_bodyAdded(1,0,mass);
  275. }
  276. void helper_printCamera(void)
  277. {
  278. printf("camera: %ld %ld %ld (%ld %ld %ld)\n",
  279. s3l_scene.camera.transform.translation.x,
  280. s3l_scene.camera.transform.translation.y,
  281. s3l_scene.camera.transform.translation.z,
  282. s3l_scene.camera.transform.rotation.x,
  283. s3l_scene.camera.transform.rotation.y,
  284. s3l_scene.camera.transform.rotation.z);
  285. }
  286. void helper_printCPU(void)
  287. {
  288. printf("CPU (%d FPS): %d \n",FPS,((MSPF - helper_frameMsLeft) * 100) / MSPF);
  289. }
  290. void helper_cameraFreeMovement(void)
  291. {
  292. if (sdl_keyboard[SDL_SCANCODE_LSHIFT])
  293. {
  294. if (sdl_keyboard[SDL_SCANCODE_UP])
  295. S3L_vec3Add(&s3l_scene.camera.transform.translation,helper_cameraForw);
  296. else if (sdl_keyboard[SDL_SCANCODE_DOWN])
  297. S3L_vec3Sub(&s3l_scene.camera.transform.translation,helper_cameraForw);
  298. else if (sdl_keyboard[SDL_SCANCODE_LEFT])
  299. S3L_vec3Sub(&s3l_scene.camera.transform.translation,helper_cameraRight);
  300. else if (sdl_keyboard[SDL_SCANCODE_RIGHT])
  301. S3L_vec3Add(&s3l_scene.camera.transform.translation,helper_cameraRight);
  302. }
  303. else
  304. {
  305. if (sdl_keyboard[SDL_SCANCODE_UP])
  306. s3l_scene.camera.transform.rotation.x += CAMERA_ROT_STEP;
  307. else if (sdl_keyboard[SDL_SCANCODE_DOWN])
  308. s3l_scene.camera.transform.rotation.x -= CAMERA_ROT_STEP;
  309. else if (sdl_keyboard[SDL_SCANCODE_LEFT])
  310. s3l_scene.camera.transform.rotation.y += CAMERA_ROT_STEP;
  311. else if (sdl_keyboard[SDL_SCANCODE_RIGHT])
  312. s3l_scene.camera.transform.rotation.y -= CAMERA_ROT_STEP;
  313. else if (sdl_keyboard[SDL_SCANCODE_Q])
  314. s3l_scene.camera.transform.rotation.z += CAMERA_ROT_STEP;
  315. else if (sdl_keyboard[SDL_SCANCODE_E])
  316. s3l_scene.camera.transform.rotation.z -= CAMERA_ROT_STEP;
  317. }
  318. }
  319. void sdl_drawPixel(int x, int y, uint8_t r, uint8_t g, uint8_t b)
  320. {
  321. uint8_t *pixel = sdl_pixels + (y * S3L_RESOLUTION_X + x) * 4 + 1;
  322. *pixel = b;
  323. pixel++;
  324. *pixel = g;
  325. pixel++;
  326. *pixel = r;
  327. }
  328. void helper_drawLine2D(int x1, int y1, int x2, int y2, uint8_t r, uint8_t g,
  329. uint8_t b)
  330. {
  331. // stupid algorithm
  332. x2 -= x1;
  333. y2 -= y1;
  334. int max = (x2 * x2 > y2 * y2) ? x2 : y2;
  335. if (max < 0)
  336. max *= -1;
  337. for (int i = 0; i < max; ++i)
  338. sdl_drawPixel(x1 + (x2 * i) / max,y1 + (y2 * i) / max,r,g,b);
  339. }
  340. void helper_drawLine3D(TPE_Vec3 p1, TPE_Vec3 p2, uint8_t rr, uint8_t gg,
  341. uint8_t bb)
  342. {
  343. S3L_Vec4 a, b, c, d;
  344. a.x = p1.x; a.y = p1.y; a.z = p1.z; a.w = 0;
  345. b.x = p2.x; b.y = p2.y; b.z = p2.z; b.w = 0;
  346. S3L_project3DPointToScreen(a,s3l_scene.camera,&c);
  347. S3L_project3DPointToScreen(b,s3l_scene.camera,&d);
  348. if (c.x >= 0 && c.x < S3L_RESOLUTION_X && c.y >= 0 && c.y < S3L_RESOLUTION_Y && c.z > 0 &&
  349. d.x >= 0 && d.x < S3L_RESOLUTION_X && d.y >= 0 && d.y < S3L_RESOLUTION_Y && d.z > 0)
  350. helper_drawLine2D(c.x,c.y,d.x,d.y,rr,gg,bb);
  351. }
  352. void tpe_debugDrawPixel(uint16_t x, uint16_t y, uint8_t color)
  353. {
  354. if (x < S3L_RESOLUTION_X - 2 && y < S3L_RESOLUTION_Y - 2)
  355. {
  356. uint8_t r, g, b;
  357. switch (color)
  358. {
  359. case 0: r = 100; g = 255; b = 200; break;
  360. case 1: r = 255; g = 100; b = 100; break;
  361. case 2: r = 0; g = 50; b = 50; break;
  362. default: r = 0; g = 0; b = 0; break;
  363. }
  364. for (int i = 0; i < 3; ++i)
  365. for (int j = 0; j < 3; ++j)
  366. sdl_drawPixel(x + i,y + j,r,g,b);
  367. }
  368. }
  369. void helper_debugDraw(void)
  370. {
  371. TPE_Vec3 camPos =
  372. TPE_vec3(
  373. s3l_scene.camera.transform.translation.x,
  374. s3l_scene.camera.transform.translation.y,
  375. s3l_scene.camera.transform.translation.z);
  376. TPE_Vec3 camRot =
  377. TPE_vec3(
  378. s3l_scene.camera.transform.rotation.x,
  379. s3l_scene.camera.transform.rotation.y,
  380. s3l_scene.camera.transform.rotation.z);
  381. TPE_worldDebugDraw(&tpe_world,tpe_debugDrawPixel,camPos,camRot,
  382. TPE_vec3(S3L_RESOLUTION_X,S3L_RESOLUTION_Y,s3l_scene.camera.focalLength),
  383. 16,256);
  384. }
  385. uint8_t s3l_r = 0, s3l_g = 255, s3l_b = 0;
  386. uint8_t s3l_rr = 0, s3l_gg = 255, s3l_bb = 0;
  387. int s3l_previousTriangleID = -1;
  388. void s3l_drawPixel(S3L_PixelInfo *p)
  389. {
  390. if (p->triangleIndex != s3l_previousTriangleID)
  391. {
  392. s3l_rr = s3l_r + ((p->triangleIndex * 5) % 128) * (((s3l_r < 128) * 2) - 1);
  393. s3l_gg = s3l_g + ((p->triangleIndex * 3) % 128) * (((s3l_g < 128) * 2) - 1);
  394. s3l_bb = s3l_b + ((p->triangleIndex * 7) % 128) * (((s3l_b < 128) * 2) - 1);
  395. s3l_previousTriangleID = p->triangleIndex;
  396. }
  397. sdl_drawPixel(p->x,p->y,s3l_rr,s3l_gg,s3l_bb);
  398. }
  399. void helper_set3dColor(uint8_t r, uint8_t g, uint8_t b)
  400. {
  401. s3l_r = r;
  402. s3l_g = g;
  403. s3l_b = b;
  404. }
  405. void helper_drawModel(S3L_Model3D *model, TPE_Vec3 pos, TPE_Vec3 scale,
  406. TPE_Vec3 rot)
  407. {
  408. s3l_previousTriangleID = -1;
  409. model->transform.translation.x = pos.x;
  410. model->transform.translation.y = pos.y;
  411. model->transform.translation.z = pos.z;
  412. model->transform.scale.x = scale.x;
  413. model->transform.scale.y = scale.y;
  414. model->transform.scale.z = scale.z;
  415. model->transform.rotation.x = rot.x;
  416. model->transform.rotation.y = rot.y;
  417. model->transform.rotation.z = rot.z;
  418. s3l_scene.models = model;
  419. #if SCALE_3D_RENDERING != 1
  420. S3L_Vec4 cp = s3l_scene.camera.transform.translation;
  421. S3L_Vec4 ms = s3l_scene.models[0].transform.scale;
  422. S3L_Vec4 mp = s3l_scene.models[0].transform.translation;
  423. s3l_scene.camera.transform.translation.x /= SCALE_3D_RENDERING;
  424. s3l_scene.camera.transform.translation.y /= SCALE_3D_RENDERING;
  425. s3l_scene.camera.transform.translation.z /= SCALE_3D_RENDERING;
  426. s3l_scene.models[0].transform.scale.x /= SCALE_3D_RENDERING;
  427. s3l_scene.models[0].transform.scale.y /= SCALE_3D_RENDERING;
  428. s3l_scene.models[0].transform.scale.z /= SCALE_3D_RENDERING;
  429. s3l_scene.models[0].transform.translation.x /= SCALE_3D_RENDERING;
  430. s3l_scene.models[0].transform.translation.y /= SCALE_3D_RENDERING;
  431. s3l_scene.models[0].transform.translation.z /= SCALE_3D_RENDERING;
  432. #endif
  433. S3L_drawScene(s3l_scene);
  434. #if SCALE_3D_RENDERING != 1
  435. s3l_scene.camera.transform.translation = cp;
  436. s3l_scene.models[0].transform.scale = ms;
  437. s3l_scene.models[0].transform.translation = mp;
  438. #endif
  439. }
  440. void helper_draw3dTriangle(TPE_Vec3 v1, TPE_Vec3 v2, TPE_Vec3 v3)
  441. {
  442. triangleVertices[0] = v1.x;
  443. triangleVertices[1] = v1.y;
  444. triangleVertices[2] = v1.z;
  445. triangleVertices[3] = v2.x;
  446. triangleVertices[4] = v2.y;
  447. triangleVertices[5] = v2.z;
  448. triangleVertices[6] = v3.x;
  449. triangleVertices[7] = v3.y;
  450. triangleVertices[8] = v3.z;
  451. helper_drawModel(&triangleModel,TPE_vec3(0,0,0),
  452. TPE_vec3(S3L_FRACTIONS_PER_UNIT,S3L_FRACTIONS_PER_UNIT,S3L_FRACTIONS_PER_UNIT),
  453. TPE_vec3(0,0,0));
  454. }
  455. void helper_draw3dCube(TPE_Vec3 pos, TPE_Vec3 scale, TPE_Vec3 rot)
  456. {
  457. cubeModel.config.backfaceCulling = 2;
  458. helper_drawModel(&cubeModel,pos,scale,rot);
  459. }
  460. void helper_draw3dCubeInside(TPE_Vec3 pos, TPE_Vec3 scale, TPE_Vec3 rot)
  461. {
  462. cubeModel.config.backfaceCulling = 1;
  463. helper_drawModel(&cubeModel,pos,scale,rot);
  464. }
  465. void helper_draw3dPlane(TPE_Vec3 pos, TPE_Vec3 scale, TPE_Vec3 rot)
  466. {
  467. helper_drawModel(&planeModel,pos,scale,rot);
  468. }
  469. void helper_draw3dSphere(TPE_Vec3 pos, TPE_Vec3 scale, TPE_Vec3 rot)
  470. {
  471. helper_drawModel(&sphereModel,pos,scale,rot);
  472. }
  473. void helper_init(void)
  474. {
  475. sdl_window = SDL_CreateWindow("program",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,S3L_RESOLUTION_X,S3L_RESOLUTION_Y,SDL_WINDOW_SHOWN);
  476. sdl_renderer = SDL_CreateRenderer(sdl_window,-1,0);
  477. sdl_texture = SDL_CreateTexture(sdl_renderer,SDL_PIXELFORMAT_RGBX8888,SDL_TEXTUREACCESS_STATIC,S3L_RESOLUTION_X,S3L_RESOLUTION_Y);
  478. sdl_screenSurface = SDL_GetWindowSurface(sdl_window);
  479. sdl_keyboard = SDL_GetKeyboardState(NULL);
  480. helper_running = 1;
  481. helper_frame = 0;
  482. helper_frameMsLeft = 0;
  483. S3L_model3DInit(cubeVertices,S3L_CUBE_VERTEX_COUNT,cubeTriangles,
  484. S3L_CUBE_TRIANGLE_COUNT,&cubeModel);
  485. S3L_model3DInit(planeVerices,4,planeTriangles,2,&planeModel);
  486. S3L_model3DInit(sphereVertices,SPHERE_VERTEX_COUNT,sphereTriangleIndices,
  487. SPHERE_TRIANGLE_COUNT,&sphereModel);
  488. S3L_model3DInit(triangleVertices,3,triangleTriangles,2,&triangleModel);
  489. S3L_sceneInit(0,1,&s3l_scene);
  490. TPE_worldInit(&tpe_world,tpe_bodies,0,0);
  491. }
  492. void helper_frameStart(void)
  493. {
  494. helper_frameStartTime = SDL_GetTicks();
  495. for (uint32_t i = 0; i < PIXELS_SIZE; ++i)
  496. sdl_pixels[i] = 0;
  497. S3L_newFrame();
  498. SDL_Event event;
  499. while (SDL_PollEvent(&event))
  500. if (
  501. (event.type == SDL_QUIT) ||
  502. ((event.type == SDL_KEYDOWN) && (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE))
  503. )
  504. helper_running = 0;
  505. S3L_rotationToDirections(s3l_scene.camera.transform.rotation,
  506. CAMERA_STEP,&helper_cameraForw,&helper_cameraRight,&helper_cameraUp);
  507. sdl_keyboard = SDL_GetKeyboardState(NULL);
  508. if (helper_debugDrawOnCountdown == 0 && sdl_keyboard[SDL_SCANCODE_F1])
  509. {
  510. helper_debugDrawOn = !helper_debugDrawOn;
  511. helper_debugDrawOnCountdown = FPS / 4;
  512. }
  513. else if (helper_debugDrawOnCountdown > 0)
  514. helper_debugDrawOnCountdown--;
  515. }
  516. void helper_frameEnd(void)
  517. {
  518. SDL_UpdateTexture(sdl_texture,NULL,sdl_pixels,S3L_RESOLUTION_X * sizeof(uint32_t));
  519. SDL_RenderClear(sdl_renderer);
  520. SDL_RenderCopy(sdl_renderer,sdl_texture,NULL,NULL);
  521. SDL_RenderPresent(sdl_renderer);
  522. helper_frame++;
  523. helper_frameMsLeft = helper_frameStartTime + MSPF - SDL_GetTicks();
  524. if (helper_frameMsLeft > 0)
  525. usleep(helper_frameMsLeft * 1000); // ofc this isn't accurate
  526. }
  527. void helper_end(void)
  528. {
  529. // TODO
  530. }