Main.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <fstream>
  4. #include "anki/input/Input.h"
  5. #include "anki/Math.h"
  6. #include "anki/renderer/Renderer.h"
  7. #include "anki/core/App.h"
  8. #include "anki/resource/Mesh.h"
  9. #include "anki/resource/Material.h"
  10. #include "anki/resource/SkelAnim.h"
  11. #include "anki/physics/Character.h"
  12. #include "anki/renderer/Renderer.h"
  13. #include "anki/renderer/MainRenderer.h"
  14. #include "anki/physics/Character.h"
  15. #include "anki/physics/RigidBody.h"
  16. #include "anki/script/ScriptManager.h"
  17. #include "anki/core/StdinListener.h"
  18. #include "anki/resource/Model.h"
  19. #include "anki/core/Logger.h"
  20. #include "anki/Util.h"
  21. #include "anki/resource/Skin.h"
  22. #include "anki/resource/ShaderProgramPrePreprocessor.h"
  23. #include "anki/resource/Material.h"
  24. #include "anki/core/Threadpool.h"
  25. #include "anki/core/NativeWindow.h"
  26. #include "anki/core/Counters.h"
  27. #include "anki/Scene.h"
  28. #include "anki/Event.h"
  29. using namespace anki;
  30. //==============================================================================
  31. void initSubsystems()
  32. {
  33. // Logger
  34. LoggerSingleton::get().init(
  35. Logger::INIT_SYSTEM_MESSAGE_HANDLER
  36. | Logger::INIT_LOG_FILE_MESSAGE_HANDLER);
  37. // App
  38. AppSingleton::get().init();
  39. // Window
  40. NativeWindowInitializer nwinit;
  41. nwinit.width = 1280;
  42. nwinit.height = 720;
  43. #if ANKI_GL == ANKI_GL_ES
  44. nwinit.majorVersion = 3;
  45. nwinit.minorVersion = 0;
  46. #else
  47. nwinit.majorVersion = 3;
  48. nwinit.minorVersion = 3;
  49. #endif
  50. nwinit.depthBits = 0;
  51. nwinit.stencilBits = 0;
  52. nwinit.fullscreenDesktopRez = false;
  53. nwinit.debugContext = false;
  54. NativeWindowSingleton::get().create(nwinit);
  55. // GL stuff
  56. GlStateCommonSingleton::get().init(
  57. nwinit.majorVersion, nwinit.minorVersion, nwinit.debugContext);
  58. // Input
  59. InputSingleton::get().init(&NativeWindowSingleton::get());
  60. InputSingleton::get().lockCursor(true);
  61. InputSingleton::get().hideCursor(true);
  62. InputSingleton::get().moveCursor(Vec2(0.0));
  63. // Main renderer
  64. RendererInitializer initializer;
  65. initializer.get("ms.ez.enabled") = false;
  66. initializer.get("ms.ez.maxObjectsToDraw") = 100;
  67. initializer.get("dbg.enabled") = false;
  68. initializer.get("is.sm.bilinearEnabled") = true;
  69. initializer.get("is.groundLightEnabled") = true;
  70. initializer.get("is.sm.enabled") = true;
  71. initializer.get("is.sm.resolution") = 512;
  72. initializer.get("pps.enabled") = true;
  73. initializer.get("pps.hdr.enabled") = true;
  74. initializer.get("pps.hdr.renderingQuality") = 0.5;
  75. initializer.get("pps.hdr.blurringDist") = 1.0;
  76. initializer.get("pps.hdr.blurringIterationsCount") = 1;
  77. initializer.get("pps.hdr.exposure") = 8.0;
  78. initializer.get("pps.ssao.enabled") = false;
  79. initializer.get("pps.ssao.blurringIterationsNum") = 1;
  80. initializer.get("pps.ssao.renderingQuality") = 0.5;
  81. initializer.get("pps.bl.enabled") = true;
  82. initializer.get("pps.bl.blurringIterationsNum") = 2;
  83. initializer.get("pps.bl.sideBlurFactor") = 1.0;
  84. initializer.get("pps.lf.enabled") = true;
  85. initializer.get("pps.sharpen") = true;
  86. initializer.get("renderingQuality") = 1.0;
  87. initializer.get("width") = NativeWindowSingleton::get().getWidth();
  88. initializer.get("height") = NativeWindowSingleton::get().getHeight();
  89. initializer.get("lodDistance") = 20.0;
  90. initializer.get("samples") = 16;
  91. //#if ANKI_GL == ANKI_GL_ES
  92. #if 1
  93. initializer.get("samples") = 1;
  94. initializer.get("is.groundLightEnabled") = true;
  95. initializer.get("is.maxPointLights") = 64;
  96. initializer.get("is.maxPointLightsPerTile") = 8;
  97. initializer.get("is.maxSpotLightsPerTile") = 4;
  98. initializer.get("is.maxSpotTexLightsPerTile") = 4;
  99. initializer.get("is.sm.poissonEnabled") = false;
  100. initializer.get("is.sm.bilinearEnabled") = false;
  101. initializer.get("renderingQuality") = 0.5;
  102. initializer.get("pps.hdr.enabled") = true;
  103. initializer.get("pps.hdr.renderingQuality") = 0.4;
  104. initializer.get("pps.hdr.blurringDist") = 1.0;
  105. initializer.get("pps.hdr.samples") = 5;
  106. initializer.get("pps.hdr.blurringIterationsCount") = 1;
  107. initializer.get("pps.hdr.exposure") = 8.0;
  108. initializer.get("maxTextureSize") = 1024;
  109. initializer.get("mrt") = false;
  110. initializer.get("tilesXCount") = 16;
  111. initializer.get("tilesYCount") = 16;
  112. initializer.get("pps.sharpen") = false;
  113. initializer.get("pps.gammaCorrection") = true;
  114. #endif
  115. MainRendererSingleton::get().init(initializer);
  116. // Stdin listener
  117. StdinListenerSingleton::get().start();
  118. // Parallel jobs
  119. ThreadpoolSingleton::get().init(getCpuCoresCount());
  120. }
  121. //==============================================================================
  122. void initScene()
  123. {
  124. SceneGraph& scene = SceneGraphSingleton::get();
  125. scene.setAmbientColor(Vec4(0.1, 0.05, 0.05, 0.0) * 2);
  126. PerspectiveCamera* cam = nullptr;
  127. scene.newSceneNode(
  128. cam, "main_camera");
  129. const F32 ang = 45.0;
  130. cam->setAll(
  131. MainRendererSingleton::get().getAspectRatio() * toRad(ang),
  132. toRad(ang), 0.5, 500.0);
  133. cam->setLocalTransform(Transform(Vec3(18.0, 5.2, 0.0),
  134. Mat3(Euler(toRad(-10.0), toRad(90.0), toRad(0.0))),
  135. 1.0));
  136. scene.setActiveCamera(cam);
  137. #if 1
  138. AnimationResourcePointer anim;
  139. anim.load("maps/sponza/animation_0.ankianim");
  140. AnimationEvent* event;
  141. scene.getEventManager().newEvent(event, anim, cam);
  142. #endif
  143. #if 1
  144. F32 x = 8.5;
  145. F32 y = 2.25;
  146. F32 z = 2.49;
  147. Array<Vec3, 4> vaseLightPos = {{Vec3(x, y, -z - 1.4), Vec3(x, y, z),
  148. Vec3(-x - 2.3, y, z), Vec3(-x - 2.3, y, -z - 1.4)}};
  149. for(U i = 0; i < vaseLightPos.getSize(); i++)
  150. {
  151. Vec3 lightPos = vaseLightPos[i];
  152. PointLight* point;
  153. scene.newSceneNode(point, ("vase_plight" + std::to_string(i)).c_str());
  154. point->loadLensFlare("textures/lens_flare/flares0.ankitex");
  155. point->setRadius(2.0);
  156. point->setLocalOrigin(lightPos);
  157. point->setDiffuseColor(Vec4(3.0, 0.2, 0.0, 0.0));
  158. point->setSpecularColor(Vec4(1.0, 1.0, 0.0, 0.0));
  159. point->setLensFlaresStretchMultiplier(Vec2(10.0, 1.0));
  160. point->setLensFlaresAlpha(1.0);
  161. LightEventData eventData;
  162. eventData.radiusMultiplier = 0.2;
  163. eventData.intensityMultiplier = Vec4(-1.2, 0.0, 0.0, 0.0);
  164. eventData.specularIntensityMultiplier = Vec4(0.1, 0.1, 0.0, 0.0);
  165. LightEvent* event;
  166. scene.getEventManager().newEvent(event, 0.0, 0.8, point, eventData);
  167. event->enableBits(Event::EF_REANIMATE);
  168. MoveEventData moveData;
  169. moveData.posMin = Vec3(-0.5, 0.0, -0.5);
  170. moveData.posMax = Vec3(0.5, 0.0, 0.5);
  171. MoveEvent* mevent;
  172. scene.getEventManager().newEvent(mevent, 0.0, 2.0, point, moveData);
  173. mevent->enableBits(Event::EF_REANIMATE);
  174. if(i == 0)
  175. {
  176. ParticleEmitter* pe;
  177. scene.newSceneNode(pe, "pefire", "particles/fire.ankipart");
  178. pe->setLocalOrigin(lightPos);
  179. scene.newSceneNode(pe, "pesmoke", "particles/smoke.ankipart");
  180. pe->setLocalOrigin(lightPos);
  181. }
  182. else
  183. {
  184. InstanceNode* instance;
  185. scene.newSceneNode(instance,
  186. ("pefire_inst" + std::to_string(i)).c_str());
  187. instance->setLocalOrigin(lightPos);
  188. SceneNode& sn = scene.findSceneNode("pefire");
  189. sn.addChild(instance);
  190. scene.newSceneNode(instance,
  191. ("pesmoke_inst" + std::to_string(i)).c_str());
  192. instance->setLocalOrigin(lightPos);
  193. scene.findSceneNode("pesmoke").addChild(instance);
  194. }
  195. {
  196. ParticleEmitter* pe;
  197. scene.newSceneNode(pe, ("pesparks" + std::to_string(i)).c_str(),
  198. "particles/sparks.ankipart");
  199. pe->setLocalOrigin(lightPos);
  200. }
  201. }
  202. #endif
  203. // horse
  204. ModelNode* horse;
  205. scene.newSceneNode(horse, "horse", "models/horse/horse.ankimdl");
  206. horse->setLocalTransform(Transform(Vec3(-2, 0, 0), Mat3::getIdentity(),
  207. 0.7));
  208. // Light
  209. SpotLight* spot;
  210. scene.newSceneNode(spot, "spot0");
  211. spot->setOuterAngle(toRad(45.0));
  212. spot->setInnerAngle(toRad(15.0));
  213. spot->setLocalTransform(Transform(Vec3(7.769279, 8.472027, -0.324927),
  214. Mat3(Quat(-0.267508, 0.664765, 0.244565, 0.653239)), 1.0));
  215. spot->setDiffuseColor(Vec4(2.0));
  216. spot->setSpecularColor(Vec4(1.0, 0.0, 1.0, 1.0));
  217. spot->setDistance(30.0);
  218. spot->setShadowEnabled(true);
  219. // Scene
  220. scene.load("maps/sponza/master.ankiscene");
  221. PointLight* pl;
  222. scene.newSceneNode(pl, "pl0");
  223. pl->setRadius(8.5);
  224. pl->setDiffuseColor(Vec4(0.5, 0.3, 0.2, 1.0));
  225. pl->setSpecularColor(Vec4(0.1, 0.0, 0.0, 1.0));
  226. pl->setLocalOrigin(Vec3(10, 2.0, -0.8));
  227. /*scene.newSceneNode(pl, "pl1");
  228. pl->setRadius(12.5);
  229. pl->setDiffuseColor(Vec4(0.5, 0.3, 0.2, 1.0));
  230. pl->setSpecularColor(Vec4(0.1, 0.0, 0.0, 1.0));
  231. pl->setLocalOrigin(Vec3(0, 2.0, -0.8));*/
  232. scene.newSceneNode(pl, "pl2");
  233. pl->setRadius(8.5);
  234. pl->setDiffuseColor(Vec4(0.5, 0.3, 0.2, 1.0));
  235. pl->setSpecularColor(Vec4(0.1, 0.0, 0.0, 1.0));
  236. pl->setLocalOrigin(Vec3(-11, 2.0, -0.8));
  237. // bounce lights
  238. const F32 bounceRadius = 2.0;
  239. const F32 lightPower = 0.3;
  240. const F32 posy = 9.844058;
  241. F32 posz = -5.550180;
  242. scene.newSceneNode(pl, "bpl0");
  243. pl->setRadius(bounceRadius);
  244. pl->setDiffuseColor(Vec4(0.0, lightPower, 0.0, 1.0));
  245. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  246. pl->setLocalOrigin(Vec3(10.270232, posy, posz));
  247. scene.newSceneNode(pl, "bpl1");
  248. pl->setRadius(bounceRadius);
  249. pl->setDiffuseColor(Vec4(0.0, lightPower, 0.0, 1.0));
  250. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  251. pl->setLocalOrigin(Vec3(6.570232, posy, posz));
  252. scene.newSceneNode(pl, "bpl2");
  253. pl->setRadius(bounceRadius);
  254. pl->setDiffuseColor(Vec4(0.0, 0.0, lightPower, 1.0));
  255. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  256. pl->setLocalOrigin(Vec3(10.270232 - 6.5, posy, posz));
  257. scene.newSceneNode(pl, "bpl3");
  258. pl->setRadius(bounceRadius);
  259. pl->setDiffuseColor(Vec4(0.0, 0.0, lightPower, 1.0));
  260. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  261. pl->setLocalOrigin(Vec3(6.570232 - 6.5, posy, posz));
  262. scene.newSceneNode(pl, "bpl4");
  263. pl->setRadius(bounceRadius);
  264. pl->setDiffuseColor(Vec4(lightPower, 0.0, 0.0, 1.0));
  265. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  266. pl->setLocalOrigin(Vec3(10.270232 - 13, posy, posz));
  267. scene.newSceneNode(pl, "bpl5");
  268. pl->setRadius(bounceRadius);
  269. pl->setDiffuseColor(Vec4(lightPower, 0.0, 0.0, 1.0));
  270. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  271. pl->setLocalOrigin(Vec3(6.570232 - 13, posy, posz));
  272. scene.newSceneNode(pl, "bpl6");
  273. pl->setRadius(bounceRadius);
  274. pl->setDiffuseColor(Vec4(lightPower, 0.0, 0.0, 1.0));
  275. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  276. pl->setLocalOrigin(Vec3(10.270232 - 13 - 6.5, posy, posz));
  277. scene.newSceneNode(pl, "bpl7");
  278. pl->setRadius(bounceRadius);
  279. pl->setDiffuseColor(Vec4(lightPower, 0.0, 0.0, 1.0));
  280. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  281. pl->setLocalOrigin(Vec3(6.570232 - 13 - 6.5, posy, posz));
  282. posz = 4.050180;
  283. scene.newSceneNode(pl, "bpl0_");
  284. pl->setRadius(bounceRadius);
  285. pl->setDiffuseColor(Vec4(0.0, 0.0, lightPower, 1.0));
  286. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  287. pl->setLocalOrigin(Vec3(10.270232, posy, posz));
  288. /*scene.newSceneNode(pl, "bpl1_");
  289. pl->setRadius(bounceRadius);
  290. pl->setDiffuseColor(Vec4(0.0, 0.0, lightPower, 1.0));
  291. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  292. pl->setLocalOrigin(Vec3(6.570232, posy, posz));*/
  293. scene.newSceneNode(pl, "bpl2_");
  294. pl->setRadius(bounceRadius);
  295. pl->setDiffuseColor(Vec4(lightPower, 0.0, 0.0, 1.0));
  296. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  297. pl->setLocalOrigin(Vec3(10.270232 - 6.5, posy, posz));
  298. scene.newSceneNode(pl, "bpl3_");
  299. pl->setRadius(bounceRadius);
  300. pl->setDiffuseColor(Vec4(lightPower, 0.0, 0.0, 1.0));
  301. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  302. pl->setLocalOrigin(Vec3(6.570232 - 6.5, posy, posz));
  303. scene.newSceneNode(pl, "bpl4_");
  304. pl->setRadius(bounceRadius);
  305. pl->setDiffuseColor(Vec4(0.0, lightPower, 0.0, 1.0));
  306. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  307. pl->setLocalOrigin(Vec3(10.270232 - 13, posy, posz));
  308. scene.newSceneNode(pl, "bpl5_");
  309. pl->setRadius(bounceRadius);
  310. pl->setDiffuseColor(Vec4(0.0, lightPower, 0.0, 1.0));
  311. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  312. pl->setLocalOrigin(Vec3(6.570232 - 13, posy, posz));
  313. scene.newSceneNode(pl, "bpl6_");
  314. pl->setRadius(bounceRadius);
  315. pl->setDiffuseColor(Vec4(0.0, 0.0, lightPower, 1.0));
  316. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  317. pl->setLocalOrigin(Vec3(10.270232 - 13 - 6.5, posy, posz));
  318. /*scene.newSceneNode(pl, "bpl7_");
  319. pl->setRadius(bounceRadius);
  320. pl->setDiffuseColor(Vec4(0.0, lightPower, 0.0, 1.0));
  321. pl->setSpecularColor(Vec4(0.0, 0.0, 0.0, 1.0));
  322. pl->setLocalOrigin(Vec3(6.570232 - 13 - 6.5, posy, posz));*/
  323. }
  324. //==============================================================================
  325. #if ANKI_OS == ANKI_OS_ANDROID
  326. static void handleEvents(android_app* app, int32_t cmd)
  327. {
  328. switch(cmd)
  329. {
  330. case APP_CMD_SAVE_STATE:
  331. ANKI_LOGI("APP_CMD_SAVE_STATE");
  332. break;
  333. case APP_CMD_INIT_WINDOW:
  334. ANKI_LOGI("APP_CMD_INIT_WINDOW");
  335. break;
  336. case APP_CMD_TERM_WINDOW:
  337. ANKI_LOGI("APP_CMD_TERM_WINDOW");
  338. break;
  339. case APP_CMD_GAINED_FOCUS:
  340. ANKI_LOGI("APP_CMD_GAINED_FOCUS");
  341. break;
  342. case APP_CMD_LOST_FOCUS:
  343. ANKI_LOGI("APP_CMD_LOST_FOCUS");
  344. break;
  345. }
  346. }
  347. #endif
  348. //==============================================================================
  349. static Bool mainLoopExtra()
  350. {
  351. const F32 dist = 0.2;
  352. const F32 ang = toRad(3.0);
  353. const F32 mouseSensivity = 9.0;
  354. Input& in = InputSingleton::get();
  355. MoveComponent& mover =
  356. SceneGraphSingleton::get().getActiveCamera().
  357. getComponent<MoveComponent>();
  358. if(in.getKey(KC_UP)) mover.rotateLocalX(ang);
  359. if(in.getKey(KC_DOWN)) mover.rotateLocalX(-ang);
  360. if(in.getKey(KC_LEFT)) mover.rotateLocalY(ang);
  361. if(in.getKey(KC_RIGHT)) mover.rotateLocalY(-ang);
  362. if(in.getKey(KC_A)) mover.moveLocalX(-dist);
  363. if(in.getKey(KC_D)) mover.moveLocalX(dist);
  364. if(in.getKey(KC_Z)) mover.moveLocalY(dist);
  365. if(in.getKey(KC_SPACE)) mover.moveLocalY(-dist);
  366. if(in.getKey(KC_W)) mover.moveLocalZ(-dist);
  367. if(in.getKey(KC_S)) mover.moveLocalZ(dist);
  368. if(in.getKey(KC_Q)) mover.rotateLocalZ(ang);
  369. if(in.getKey(KC_E)) mover.rotateLocalZ(-ang);
  370. if(in.getMousePosition() != Vec2(0.0))
  371. {
  372. F32 angY = -ang * in.getMousePosition().x() * mouseSensivity *
  373. MainRendererSingleton::get().getAspectRatio();
  374. mover.rotateLocalY(angY);
  375. mover.rotateLocalX(ang * in.getMousePosition().y() * mouseSensivity);
  376. }
  377. if(in.getKey(KC_F1) == 1)
  378. {
  379. MainRendererSingleton::get().getDbg().setEnabled(
  380. !MainRendererSingleton::get().getDbg().getEnabled());
  381. }
  382. if(InputSingleton::get().getKey(KC_ESCAPE))
  383. {
  384. return false;
  385. }
  386. return true;
  387. }
  388. //==============================================================================
  389. static void mainLoop()
  390. {
  391. ANKI_LOGI("Entering main loop");
  392. HighRezTimer::Scalar prevUpdateTime = HighRezTimer::getCurrentTime();
  393. HighRezTimer::Scalar crntTime = prevUpdateTime;
  394. SceneGraph& scene = SceneGraphSingleton::get();
  395. MainRenderer& renderer = MainRendererSingleton::get();
  396. Input& input = InputSingleton::get();
  397. NativeWindow& window = NativeWindowSingleton::get();
  398. ANKI_COUNTER_START_TIMER(C_FPS);
  399. while(true)
  400. {
  401. HighRezTimer timer;
  402. timer.start();
  403. prevUpdateTime = crntTime;
  404. crntTime = HighRezTimer::getCurrentTime();
  405. // Update
  406. input.handleEvents();
  407. if(input.getEvent(Input::WINDOW_CLOSED_EVENT) > 0)
  408. {
  409. break;
  410. }
  411. if(!mainLoopExtra())
  412. {
  413. break;
  414. }
  415. scene.update(prevUpdateTime, crntTime, renderer);
  416. renderer.render(scene);
  417. window.swapBuffers();
  418. ANKI_COUNTERS_RESOLVE_FRAME();
  419. // Sleep
  420. timer.stop();
  421. if(timer.getElapsedTime() < AppSingleton::get().getTimerTick())
  422. {
  423. HighRezTimer::sleep(
  424. AppSingleton::get().getTimerTick() - timer.getElapsedTime());
  425. }
  426. // Timestamp
  427. increaseGlobTimestamp();
  428. }
  429. // Counters end
  430. ANKI_COUNTER_STOP_TIMER_INC(C_FPS);
  431. ANKI_COUNTERS_FLUSH();
  432. }
  433. //==============================================================================
  434. #if ANKI_OS == ANKI_OS_ANDROID
  435. void android_main(android_app* app)
  436. {
  437. app_dummy();
  438. // First thing to do
  439. gAndroidApp = app;
  440. app->onAppCmd = handleEvents;
  441. #else
  442. int main(int, char**)
  443. {
  444. #endif
  445. try
  446. {
  447. initSubsystems();
  448. initScene();
  449. mainLoop();
  450. ANKI_LOGI("Exiting...");
  451. }
  452. catch(std::exception& e)
  453. {
  454. ANKI_LOGE("Aborting: %s", e.what());
  455. }
  456. ANKI_LOGI("Bye!!");
  457. #if ANKI_OS == ANKI_OS_ANDROID
  458. exit(0);
  459. #else
  460. return 0;
  461. #endif
  462. }