App.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. #include <GL/glew.h>
  2. #include <sstream>
  3. #include <SDL/SDL.h>
  4. #include <iostream>
  5. #include <iomanip>
  6. #include <boost/filesystem.hpp>
  7. #include <boost/algorithm/string.hpp>
  8. #include "App.h"
  9. #include "RendererInitializer.h"
  10. #include "MainRenderer.h"
  11. #include "ScriptingEngine.h"
  12. #include "StdinListener.h"
  13. #include "Input.h"
  14. #include "Logger.h"
  15. #include "Globals.h"
  16. //======================================================================================================================
  17. // handleMessageHanlderMsgs =
  18. //======================================================================================================================
  19. void App::handleMessageHanlderMsgs(const char* file, int line, const char* func, const char* msg)
  20. {
  21. if(boost::find_first(msg, "Warning") || boost::find_first(msg, "Error"))
  22. {
  23. std::cerr << "(" << file << ":" << line << " "<< func << ") " << msg << std::flush;
  24. }
  25. else
  26. {
  27. std::cout << "(" << file << ":" << line << " "<< func << ") " << msg << std::flush;
  28. }
  29. }
  30. //======================================================================================================================
  31. // parseCommandLineArgs =
  32. //======================================================================================================================
  33. void App::parseCommandLineArgs(int argc, char* argv[])
  34. {
  35. for(int i = 1; i < argc; i++)
  36. {
  37. char* arg = argv[i];
  38. if(strcmp(arg, "--terminal-coloring") == 0)
  39. {
  40. terminalColoringEnabled = true;
  41. }
  42. else if(strcmp(arg, "--no-terminal-coloring") == 0)
  43. {
  44. terminalColoringEnabled = false;
  45. }
  46. else
  47. {
  48. std::cerr << "Incorrect command line argument \"" << arg << "\"" << std::endl;
  49. abort();
  50. }
  51. }
  52. }
  53. //======================================================================================================================
  54. // init =
  55. //======================================================================================================================
  56. void App::init(int argc, char* argv[])
  57. {
  58. windowW = 1280;
  59. windowH = 720;
  60. terminalColoringEnabled = true,
  61. fullScreenFlag = false;
  62. // send output to handleMessageHanlderMsgs
  63. LoggerSingleton::getInstance().getSignal().connect(boost::bind(&App::handleMessageHanlderMsgs,
  64. this, _1, _2, _3, _4));
  65. INFO("Initializing the engine...");
  66. parseCommandLineArgs(argc, argv);
  67. printAppInfo();
  68. // dirs
  69. initDirs();
  70. // create the subsystems. WATCH THE ORDER
  71. const char* commonPythonCode =
  72. "import sys\n"
  73. "from Anki import *\n"
  74. "\n"
  75. "class StdoutCatcher:\n"
  76. "\tdef write(self, str_):\n"
  77. "\t\tif str_ == \"\\n\": return\n"
  78. "\t\tline = sys._getframe(1).f_lineno\n"
  79. "\t\tfile = sys._getframe(1).f_code.co_filename\n"
  80. "\t\tfunc = sys._getframe(1).f_code.co_name\n"
  81. "\t\tLoggerSingleton.getInstance().write(file, line, func, str_ + \"\\n\")\n"
  82. "\n"
  83. "class StderrCatcher:\n"
  84. "\tdef write(self, str_):\n"
  85. "\t\tline = sys._getframe(1).f_lineno\n"
  86. "\t\tfile = sys._getframe(1).f_code.co_filename\n"
  87. "\t\tfunc = sys._getframe(1).f_code.co_name\n"
  88. "\t\tLoggerSingleton.getInstance().write(file, line, func, str_)\n"
  89. "\n"
  90. "sys.stdout = StdoutCatcher()\n"
  91. "sys.stderr = StderrCatcher()\n";
  92. ScriptingEngineSingleton::getInstance().execScript(commonPythonCode);
  93. StdinListenerSingleton::getInstance().start();
  94. initWindow();
  95. initRenderer();
  96. // other
  97. activeCam = NULL;
  98. timerTick = 1000 / 40; // in ms. 1000/Hz
  99. time = 0;
  100. INFO("Engine initialization ends");
  101. }
  102. //======================================================================================================================
  103. // initWindow =
  104. //======================================================================================================================
  105. void App::initWindow()
  106. {
  107. INFO("SDL window initializing...");
  108. if(SDL_Init(SDL_INIT_VIDEO) < 0)
  109. {
  110. throw EXCEPTION("Failed to init SDL_VIDEO");
  111. }
  112. // print driver name
  113. const char* driverName = SDL_GetCurrentVideoDriver();
  114. if(driverName != NULL)
  115. {
  116. INFO("Video driver name: " << driverName);
  117. }
  118. // set GL attribs
  119. SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
  120. SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
  121. SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8); // WARNING: Set this low only in deferred shading
  122. SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  123. SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
  124. // OpenWindow
  125. windowId = SDL_CreateWindow("AnKi 3D Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, windowW, windowH,
  126. SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
  127. if(!windowId)
  128. {
  129. throw EXCEPTION("Cannot create main window");
  130. }
  131. glContext = SDL_GL_CreateContext(windowId);
  132. // the icon
  133. iconImage = SDL_LoadBMP("gfx/icon.bmp");
  134. if(iconImage == NULL)
  135. {
  136. WARNING("Cannot load window icon");
  137. }
  138. else
  139. {
  140. Uint32 colorkey = SDL_MapRGB(iconImage->format, 255, 0, 255);
  141. SDL_SetColorKey(iconImage, SDL_SRCCOLORKEY, colorkey);
  142. //SDL_WM_SetIcon(iconImage, NULL);
  143. SDL_SetWindowIcon(windowId, iconImage);
  144. }
  145. INFO("SDL window initialization ends");
  146. }
  147. //======================================================================================================================
  148. // initDirs =
  149. //======================================================================================================================
  150. void App::initDirs()
  151. {
  152. settingsPath = boost::filesystem::path(getenv("HOME")) / ".anki";
  153. if(!boost::filesystem::exists(settingsPath))
  154. {
  155. INFO("Creating settings dir \"" << settingsPath.string() << "\"");
  156. boost::filesystem::create_directory(settingsPath);
  157. }
  158. cachePath = settingsPath / "cache";
  159. if(boost::filesystem::exists(cachePath))
  160. {
  161. INFO("Deleting dir \"" << cachePath.string() << "\"");
  162. boost::filesystem::remove_all(cachePath);
  163. }
  164. INFO("Creating cache dir \"" << cachePath.string() << "\"");
  165. boost::filesystem::create_directory(cachePath);
  166. }
  167. //======================================================================================================================
  168. // initRenderer =
  169. //======================================================================================================================
  170. void App::initRenderer()
  171. {
  172. RendererInitializer initializer;
  173. initializer.ms.ez.enabled = true;
  174. initializer.dbg.enabled = true;
  175. initializer.is.sm.bilinearEnabled = true;
  176. initializer.is.sm.enabled = true;
  177. initializer.is.sm.pcfEnabled = true;
  178. initializer.is.sm.resolution = 1024;
  179. initializer.is.sm.level0Distance = 3.0;
  180. initializer.pps.hdr.enabled = true;
  181. initializer.pps.hdr.renderingQuality = 0.25;
  182. initializer.pps.hdr.blurringDist = 1.0;
  183. initializer.pps.hdr.blurringIterationsNum = 2;
  184. initializer.pps.hdr.exposure = 4.0;
  185. initializer.pps.ssao.blurringIterationsNum = 4;
  186. initializer.pps.ssao.enabled = true;
  187. initializer.pps.ssao.renderingQuality = 0.3;
  188. initializer.pps.bl.enabled = true;
  189. initializer.pps.bl.blurringIterationsNum = 2;
  190. initializer.pps.bl.sideBlurFactor = 1.0;
  191. initializer.mainRendererQuality = 1.0;
  192. MainRendererSingleton::getInstance().init(initializer);
  193. }
  194. //======================================================================================================================
  195. // togleFullScreen =
  196. //======================================================================================================================
  197. void App::togleFullScreen()
  198. {
  199. //SDL_WM_ToggleFullScreen(mainSurf);
  200. SDL_SetWindowFullscreen(windowId, fullScreenFlag ? SDL_TRUE : SDL_FALSE);
  201. fullScreenFlag = !fullScreenFlag;
  202. }
  203. //======================================================================================================================
  204. // swapBuffers =
  205. //======================================================================================================================
  206. void App::swapBuffers()
  207. {
  208. //SDL_GL_SwapBuffers();
  209. SDL_GL_SwapWindow(windowId);
  210. }
  211. //======================================================================================================================
  212. // quit =
  213. //======================================================================================================================
  214. void App::quit(int code)
  215. {
  216. SDL_FreeSurface(iconImage);
  217. SDL_GL_DeleteContext(glContext);
  218. SDL_DestroyWindow(windowId);
  219. SDL_Quit();
  220. exit(code);
  221. }
  222. //======================================================================================================================
  223. // printAppInfo =
  224. //======================================================================================================================
  225. #if !defined(REVISION)
  226. #define REVISION "unknown"
  227. #endif
  228. void App::printAppInfo()
  229. {
  230. std::stringstream msg;
  231. msg << "App info: Build: ";
  232. #if defined(NDEBUG)
  233. msg << "release, ";
  234. #else
  235. msg << "debug, ";
  236. #endif
  237. msg << "platform ";
  238. #if defined(PLATFORM_LINUX)
  239. msg << "Linux, ";
  240. #elif defined(PLATFORM_WIN)
  241. msg << "Windows, ";
  242. #else
  243. #error "See file"
  244. #endif
  245. msg << "GLEW " << glewGetString(GLEW_VERSION) << ", ";
  246. const SDL_version* v = SDL_Linked_Version();
  247. msg << "SDL " << int(v->major) << '.' << int(v->minor) << '.' << int(v->patch) << ", ";
  248. msg << "build date " __DATE__ << ", ";
  249. msg << "rev " << REVISION;
  250. INFO(msg.str());
  251. }
  252. //======================================================================================================================
  253. // getDesktopWidth =
  254. //======================================================================================================================
  255. uint App::getDesktopWidth() const
  256. {
  257. SDL_DisplayMode mode;
  258. /// @todo re-enable it
  259. //SDL_GetDesktopDisplayMode(&mode);
  260. return mode.w;
  261. }
  262. //======================================================================================================================
  263. // getDesktopHeight =
  264. //======================================================================================================================
  265. uint App::getDesktopHeight() const
  266. {
  267. SDL_DisplayMode mode;
  268. /// @todo re-enable it
  269. //SDL_GetDesktopDisplayMode(&mode);
  270. return mode.h;
  271. }
  272. //======================================================================================================================
  273. // execStdinScpripts =
  274. //======================================================================================================================
  275. void App::execStdinScpripts()
  276. {
  277. while(1)
  278. {
  279. std::string cmd = StdinListenerSingleton::getInstance().getLine();
  280. if(cmd.length() < 1)
  281. {
  282. break;
  283. }
  284. try
  285. {
  286. ScriptingEngineSingleton::getInstance().execScript(cmd.c_str(), "command line input");
  287. }
  288. catch(Exception& e)
  289. {
  290. ERROR(e.what());
  291. }
  292. }
  293. }