engineGL3DSupport.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. #include "engineGL3DSupport.h"
  2. #include <stringManipulation/stringManipulation.h>
  3. #undef min
  4. #undef max
  5. void errorCallbackCustom(std::string err, void *userData)
  6. {
  7. RequestedContainerInfo *data = (RequestedContainerInfo *)userData;
  8. data->consoleWrite((err + "\n").c_str());
  9. }
  10. std::string readEntireFileCustom(const char *fileName, bool &couldNotOpen, void *userData)
  11. {
  12. RequestedContainerInfo *data = (RequestedContainerInfo *)userData;
  13. couldNotOpen = false;
  14. size_t size = 0;
  15. if (!data->getFileSize(fileName, size))
  16. {
  17. couldNotOpen = true;
  18. return "";
  19. }
  20. std::string buffer;
  21. buffer.resize(size + 1);
  22. if (!data->readEntireFile(fileName, &buffer.at(0), size))
  23. {
  24. couldNotOpen = true;
  25. return "";
  26. }
  27. return buffer;
  28. }
  29. std::vector<char> readEntireFileBinaryCustom(const char *fileName, bool &couldNotOpen, void *userData)
  30. {
  31. RequestedContainerInfo *data = (RequestedContainerInfo *)userData;
  32. couldNotOpen = false;
  33. size_t size = 0;
  34. if (!data->getFileSizeBinary(fileName, size))
  35. {
  36. couldNotOpen = true;
  37. return {};
  38. }
  39. std::vector<char> buffer;
  40. buffer.resize(size + 1, 0);
  41. if (!data->readEntireFileBinary(fileName, &buffer.at(0), size))
  42. {
  43. couldNotOpen = true;
  44. return {};
  45. }
  46. return buffer;
  47. }
  48. bool defaultFileExistsCustom(const char *fileName, void *userData)
  49. {
  50. RequestedContainerInfo *data = (RequestedContainerInfo *)userData;
  51. size_t s = 0;
  52. return data->getFileSizeBinary(fileName, s);
  53. }
  54. void pika::gl3d::generalSettingsWindow(int imguiId, ::gl3d::Renderer3D &renderer)
  55. {
  56. ImGui::PushID(imguiId);
  57. //ImGui::SliderFloat("Gama Corections", &gamaCorection, 1, 3);
  58. ImGui::SliderFloat("Exposure", &renderer.internal.lightShader.lightPassUniformBlockCpuData.exposure, 0.1, 10);
  59. auto normalMap = renderer.isNormalMappingEnabeled();
  60. ImGui::Checkbox("Normal map", &normalMap);
  61. renderer.enableNormalMapping(normalMap);
  62. static bool lightSubScater = renderer.isLightSubScatteringEnabeled();
  63. ImGui::Checkbox("Light sub scater", &lightSubScater);
  64. renderer.enableLightSubScattering(lightSubScater);
  65. ImGui::Checkbox("Adaptive resolution", &renderer.adaptiveResolution.useAdaptiveResolution);
  66. ImGui::Text("Adaptive rez ratio: %.1f", renderer.adaptiveResolution.rezRatio);
  67. //ImGui::Checkbox("Z pre pass", &renderer.zPrePass);
  68. ImGui::Checkbox("Frustum culling", &renderer.frustumCulling);
  69. ImGui::PopID();
  70. }
  71. void pika::gl3d::fxaaSettingsWindow(int imguiId, ::gl3d::Renderer3D &renderer)
  72. {
  73. ImGui::PushID(imguiId);
  74. ImGui::Checkbox("FXAA", &renderer.antiAlias.usingFXAA);
  75. auto &fxaaData = renderer.getFxaaSettings();
  76. ImGui::DragFloat("edgeDarkTreshold", &fxaaData.edgeDarkTreshold, 0.001, 0, 1);
  77. ImGui::DragFloat("edgeMinTreshold", &fxaaData.edgeMinTreshold, 0.001, 0, 1);
  78. ImGui::DragFloat("quaityMultiplier", &fxaaData.quaityMultiplier, 0.001, 0, 1);
  79. ImGui::DragInt("ITERATIONS", &fxaaData.ITERATIONS, 1, 1, 32);
  80. ImGui::DragFloat("SUBPIXEL_QUALITY", &fxaaData.SUBPIXEL_QUALITY, 0.001, 0, 1);
  81. ImGui::PopID();
  82. }
  83. void pika::gl3d::ssaoSettingsWindow(int imguiId, ::gl3d::Renderer3D &renderer)
  84. {
  85. ImGui::PushID(imguiId);
  86. ImGui::Checkbox("SSAO", &renderer.internal.lightShader.useSSAO);
  87. ImGui::SliderFloat("SSAO bias", &renderer.internal.ssao.ssaoShaderUniformBlockData.bias, 0, 0.5);
  88. ImGui::SliderFloat("SSAO radius", &renderer.internal.ssao.ssaoShaderUniformBlockData.radius, 0, 2);
  89. ImGui::SliderInt("SSAO sample count", &renderer.internal.ssao.ssaoShaderUniformBlockData.samplesTestSize, 0, 64);
  90. ImGui::SliderFloat("SSAO exponent", &renderer.internal.ssao.ssao_finalColor_exponent, 0, 16);
  91. ImGui::PopID();
  92. }
  93. void pika::gl3d::ssrSettingsWindow(int imguiId, ::gl3d::Renderer3D &renderer)
  94. {
  95. ImGui::PushID(imguiId);
  96. ImGui::Checkbox("SSR", &renderer.internal.hasLastFrameTexture);
  97. auto d = renderer.getSSRdata();
  98. ImGui::SliderFloat("max ray delta", &d.maxRayDelta, 0.0001f, 2.f); //for clamping infinity
  99. ImGui::SliderFloat("max ray step", &d.maxRayStep, 0.01f, 5.f);
  100. ImGui::SliderInt("max steps", &d.maxSteps, 5, 150);
  101. ImGui::SliderFloat("min ray step", &d.minRayStep, 0.001f, 1.f);
  102. ImGui::SliderInt("binary search steps", &d.numBinarySearchSteps, 2, 20);
  103. renderer.setSSRdata(d);
  104. ImGui::PopID();
  105. }
  106. void pika::gl3d::bloomSettingsWindow(int imguiId, ::gl3d::Renderer3D &renderer)
  107. {
  108. ImGui::PushID(imguiId);
  109. ImGui::Checkbox("Bloom", &renderer.bloom());
  110. ImGui::DragFloat("Bloom tresshold", &renderer.internal.lightShader.lightPassUniformBlockCpuData.bloomTresshold,
  111. 0.01, 0, 1);
  112. ImGui::DragFloat("Bloom intensity", &renderer.postProcess.bloomIntensty, 0.01, 0, 10);
  113. ImGui::Checkbox("High quality down sample", &renderer.bloomHighQualityDownSample());
  114. ImGui::Checkbox("High quality up sample", &renderer.bloomHighQualityUpSample());
  115. ImGui::PopID();
  116. }
  117. void pika::gl3d::chromaticAberationSettingsWindow(int imguiId, ::gl3d::Renderer3D &renderer)
  118. {
  119. ImGui::PushID(imguiId);
  120. ImGui::Checkbox("Chromatic aberation", &renderer.chromaticAberationEnabeled());
  121. ImGui::DragFloat("Chromatic aberation strength", &renderer.postProcess.chromaticAberationStrength,
  122. 1, 0, 200);
  123. ImGui::DragFloat("Chromatic aberation defocus", &renderer.postProcess.unfocusDistance,
  124. 0.01, 0, 100);
  125. ImGui::PopID();
  126. }
  127. void pika::gl3d::lightEditorSettingsWindow(int imguiId, ::gl3d::Renderer3D &renderer)
  128. {
  129. ImGui::PushID(imguiId);
  130. auto &pointLights = renderer.internal.pointLightIndexes;
  131. static int pointLightSelector = -1;
  132. ImGui::Text("Point lightd Count %d", pointLights.size());
  133. ImGui::InputInt("Current Point light:", &pointLightSelector);
  134. int n = ImGui::Button("New Light"); ImGui::SameLine();
  135. int remove = ImGui::Button("Remove Light");
  136. int lightSize = renderer.getPointLightShadowSize();
  137. ImGui::DragInt("Point light shadow texture size", &lightSize);
  138. renderer.setPointLightShadowSize(lightSize);
  139. if (pointLightSelector < -1)
  140. {
  141. pointLightSelector = -1;
  142. }
  143. if (n || (pointLightSelector >= (int)pointLights.size()))
  144. {
  145. //pointLights.push_back(
  146. renderer.createPointLight({0,0,0});
  147. }
  148. pointLightSelector = std::min(pointLightSelector, (int)pointLights.size() - 1);
  149. if (remove)
  150. {
  151. if (pointLightSelector >= 0)
  152. {
  153. ::gl3d::PointLight light;
  154. light.id_ = pointLights[pointLightSelector];
  155. renderer.detletePointLight(light);
  156. pointLightSelector = std::min(pointLightSelector, (int)pointLights.size() - 1);
  157. }
  158. }
  159. ImGui::NewLine();
  160. if (pointLightSelector >= 0)
  161. {
  162. ImGui::PushID(12);
  163. ::gl3d::PointLight light;
  164. light.id_ = pointLights[pointLightSelector];
  165. glm::vec3 color = renderer.getPointLightColor(light);
  166. ImGui::ColorEdit3("Color", &color[0]);
  167. renderer.setPointLightColor(light, color);
  168. glm::vec3 position = renderer.getPointLightPosition(light);
  169. ImGui::DragFloat3("Position", &position[0], 0.1);
  170. renderer.setPointLightPosition(light, position);
  171. float distance = renderer.getPointLightDistance(light);
  172. ImGui::DragFloat("Distance##point", &distance, 0.05, 0);
  173. renderer.setPointLightDistance(light, distance);
  174. float attenuation = renderer.getPointLightAttenuation(light);
  175. ImGui::DragFloat("Attenuation##point", &attenuation, 0.05, 0);
  176. renderer.setPointLightAttenuation(light, attenuation);
  177. float hardness = renderer.getPointLightHardness(light);
  178. ImGui::DragFloat("Hardness##point", &hardness, 0.05, 0.001);
  179. renderer.setPointLightHardness(light, hardness);
  180. bool shadows = renderer.getPointLightShadows(light);
  181. ImGui::Checkbox("Cast shadows##point", &shadows);
  182. renderer.setPointLightShadows(light, shadows);
  183. ImGui::PopID();
  184. }
  185. {
  186. ImGui::NewLine();
  187. auto &directionalLights = renderer.internal.directionalLightIndexes;
  188. static int directionalLightSelector = -1;
  189. ImGui::Text("Directional lightd Count %d", directionalLights.size());
  190. ImGui::InputInt("Current directional light:", &directionalLightSelector);
  191. int n = ImGui::Button("New Directional Light"); ImGui::SameLine();
  192. int remove = ImGui::Button("Remove Directional Light");
  193. int lightSize = renderer.getDirectionalLightShadowSize();
  194. ImGui::DragInt("Directional light shadow texture size", &lightSize);
  195. renderer.setDirectionalLightShadowSize(lightSize);
  196. ImGui::DragFloat3("cascades", renderer.directionalShadows.frustumSplits, 0.01, 0, 1);
  197. if (directionalLightSelector < -1)
  198. {
  199. directionalLightSelector = -1;
  200. }
  201. if (n || directionalLightSelector >= (int)directionalLights.size())
  202. {
  203. renderer.createDirectionalLight(glm::vec3(0.f));
  204. }
  205. directionalLightSelector
  206. = std::min(directionalLightSelector, (int)directionalLights.size() - 1);
  207. if (remove)
  208. {
  209. if (directionalLightSelector >= 0)
  210. {
  211. ::gl3d::DirectionalLight light;
  212. light.id_ = directionalLights[directionalLightSelector];
  213. renderer.deleteDirectionalLight(light);
  214. directionalLightSelector = std::min(directionalLightSelector, (int)directionalLights.size() - 1);
  215. }
  216. }
  217. ImGui::NewLine();
  218. if (directionalLightSelector >= 0)
  219. {
  220. ::gl3d::DirectionalLight light;
  221. light.id_ = directionalLights[directionalLightSelector];
  222. ImGui::PushID(13);
  223. glm::vec3 color = renderer.getDirectionalLightColor(light);
  224. ImGui::ColorEdit3("Color##dir", &color[0]);
  225. renderer.setDirectionalLightColor(light, color);
  226. glm::vec3 direction = renderer.getDirectionalLightDirection(light);
  227. ImGui::DragFloat3("Direction##dir", &direction[0], 0.01);
  228. renderer.setDirectionalLightDirection(light, direction);
  229. float hardness = renderer.getDirectionalLightHardness(light);
  230. ImGui::SliderFloat("Hardness##dir", &hardness, 0.1, 10);
  231. renderer.setDirectionalLightHardness(light, hardness);
  232. bool castShadows = renderer.getDirectionalLightShadows(light);
  233. ImGui::Checkbox("Cast shadows##dir", &castShadows);
  234. renderer.setDirectionalLightShadows(light, castShadows);
  235. //ImGui::SliderFloat3("frustumSplit",
  236. // &renderer.directionalShadows.frustumSplits[0], 0, 1);
  237. ImGui::PopID();
  238. }
  239. }
  240. {
  241. auto &spotLights = renderer.internal.spotLightIndexes;
  242. ImGui::NewLine();
  243. static int spotLightSelector = -1;
  244. ImGui::Text("Spot lightd Count %d", spotLights.size());
  245. ImGui::InputInt("Current spot light:", &spotLightSelector);
  246. int n = ImGui::Button("New Spot Light"); ImGui::SameLine();
  247. int remove = ImGui::Button("Remove Spot Light");
  248. int lightSize = renderer.getSpotLightShadowSize();
  249. ImGui::DragInt("Spot light shadow texture size", &lightSize);
  250. renderer.setSpotLightShadowSize(lightSize);
  251. if (spotLightSelector < -1)
  252. {
  253. spotLightSelector = -1;
  254. }
  255. if (n || spotLightSelector >= (int)spotLights.size())
  256. {
  257. renderer.createSpotLight({0,0,0}, glm::radians(90.f),
  258. {0,-1,0});
  259. }
  260. spotLightSelector
  261. = std::min(spotLightSelector, (int)spotLights.size() - 1);
  262. if (remove)
  263. {
  264. if (spotLightSelector >= 0)
  265. {
  266. ::gl3d::SpotLight light;
  267. light.id_ = spotLights[spotLightSelector];
  268. renderer.deleteSpotLight(light);
  269. spotLightSelector = std::min(spotLightSelector,
  270. (int)renderer.internal.spotLights.size() - 1);
  271. }
  272. }
  273. ImGui::NewLine();
  274. if (spotLightSelector >= 0)
  275. {
  276. ImGui::PushID(14);
  277. ::gl3d::SpotLight light;
  278. light.id_ = spotLights[spotLightSelector];
  279. glm::vec3 color = renderer.getSpotLightColor(light);
  280. ImGui::ColorEdit3("Color##spot", &color[0]);
  281. renderer.setSpotLightColor(light, color);
  282. glm::vec3 position = renderer.getSpotLightPosition(light);
  283. ImGui::DragFloat3("Position##spot", &position[0], 0.1);
  284. renderer.setSpotLightPosition(light, position);
  285. glm::vec3 direction = renderer.getSpotLightDirection(light);
  286. ImGui::DragFloat3("Direction##spot", &direction[0], 0.05);
  287. renderer.setSpotLightDirection(light, direction);
  288. float distance = renderer.getSpotLightDistance(light);
  289. ImGui::DragFloat("Distance##spot", &distance, 0.05, 0);
  290. renderer.setSpotLightDistance(light, distance);
  291. float attenuation = renderer.getSpotLightAttenuation(light);
  292. ImGui::DragFloat("Attenuation##spot", &attenuation, 0.05, 0);
  293. renderer.setSpotLightAttenuation(light, attenuation);
  294. float hardness = renderer.getSpotLightHardness(light);
  295. ImGui::DragFloat("Hardness##spot", &hardness, 0.05, 0, 20);
  296. renderer.setSpotLightHardness(light, hardness);
  297. float angle = renderer.getSpotLightFov(light);
  298. ImGui::SliderAngle("fov", &angle, 0, 180);
  299. renderer.setSpotLightFov(light, angle);
  300. bool castShadows = renderer.getSpotLightShadows(light);
  301. ImGui::Checkbox("Cast shadows##spot", &castShadows);
  302. renderer.setSpotLightShadows(light, castShadows);
  303. ImGui::PopID();
  304. }
  305. }
  306. ImGui::PopID();
  307. }
  308. void pika::gl3d::fpsInput(::gl3d::Renderer3D &renderer, pika::Input &input, float speed, glm::dvec2 &lastMousePos,
  309. RequestedContainerInfo &requestedInfo, glm::ivec2 windowSize)
  310. {
  311. glm::vec3 dir = {};
  312. if (input.buttons[pika::Button::W].held())
  313. {
  314. dir.z -= speed * input.deltaTime;
  315. }
  316. if (input.buttons[pika::Button::S].held())
  317. {
  318. dir.z += speed * input.deltaTime;
  319. }
  320. if (input.buttons[pika::Button::A].held())
  321. {
  322. dir.x -= speed * input.deltaTime;
  323. }
  324. if (input.buttons[pika::Button::D].held())
  325. {
  326. dir.x += speed * input.deltaTime;
  327. }
  328. if (input.buttons[pika::Button::Q].held())
  329. {
  330. dir.y -= speed * input.deltaTime;
  331. }
  332. if (input.buttons[pika::Button::E].held())
  333. {
  334. dir.y += speed * input.deltaTime;
  335. }
  336. renderer.camera.moveFPS(dir);
  337. {
  338. if (input.hasFocus && input.lastFrameHasFocus)
  339. {
  340. requestedInfo.setFpsCursor();
  341. glm::dvec2 currentMousePos = {input.mouseX, input.mouseY};
  342. float speed = 0.2f * (1.f/60.f);
  343. glm::vec2 delta = lastMousePos - currentMousePos;
  344. delta *= speed; //* input.deltaTime;
  345. renderer.camera.rotateCamera(delta);
  346. lastMousePos = currentMousePos;
  347. }
  348. else
  349. {
  350. requestedInfo.setNormalCursor();
  351. lastMousePos = {input.mouseX, input.mouseY};
  352. }
  353. }
  354. }
  355. bool pika::gl3d::loadSettingsFromFileName(::gl3d::Renderer3D &renderer, std::string file, RequestedContainerInfo &info)
  356. {
  357. std::string data;
  358. if (info.readEntireFile(file.c_str(), data))
  359. {
  360. if (data.size() > 0)
  361. {
  362. renderer.loadSettingsFromJson(data.c_str(), 1, 0, 0);
  363. return 1;
  364. }
  365. return 0;
  366. }
  367. else
  368. {
  369. return 0;
  370. }
  371. }
  372. void pika::gl3d::General3DEditor::loadFromFile(::gl3d::Renderer3D &renderer, std::string file, RequestedContainerInfo &info)
  373. {
  374. std::string data;
  375. if (info.readEntireFile(file.c_str(), data))
  376. {
  377. if (data.size() > 0)
  378. {
  379. renderer.loadSettingsFromJson(data.c_str(), 1, 1, 0);
  380. }
  381. pika::strlcpy(settingsFileSelector.file, file, sizeof(settingsFileSelector.file));
  382. }
  383. }
  384. void pika::gl3d::General3DEditor::update(int imguiId, ::gl3d::Renderer3D &renderer,
  385. pika::Input &input, float moveSpeed, RequestedContainerInfo &info, glm::ivec2 windowSize)
  386. {
  387. ImGui::PushID(imguiId);
  388. if (ImGui::Begin("General3DEditor"))
  389. {
  390. if (ImGui::CollapsingHeader("Camera", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_FramePadding))
  391. {
  392. pika::gl3d::generalSettingsWindow(imguiId, renderer);
  393. }
  394. if (ImGui::CollapsingHeader("Basic settings", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_FramePadding))
  395. {
  396. pika::gl3d::generalSettingsWindow(imguiId, renderer);
  397. }
  398. if (ImGui::CollapsingHeader("fxaa settings", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_FramePadding))
  399. {
  400. pika::gl3d::fxaaSettingsWindow(imguiId, renderer);
  401. }
  402. if (ImGui::CollapsingHeader("ssao settings", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_FramePadding))
  403. {
  404. pika::gl3d::ssaoSettingsWindow(imguiId, renderer);
  405. }
  406. if (ImGui::CollapsingHeader("ssr settings", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_FramePadding))
  407. {
  408. pika::gl3d::ssrSettingsWindow(imguiId, renderer);
  409. }
  410. if (ImGui::CollapsingHeader("bloom settings", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_FramePadding))
  411. {
  412. pika::gl3d::bloomSettingsWindow(imguiId, renderer);
  413. }
  414. if (ImGui::CollapsingHeader("chromatic aberation settings", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_FramePadding))
  415. {
  416. pika::gl3d::chromaticAberationSettingsWindow(imguiId, renderer);
  417. }
  418. if (ImGui::CollapsingHeader("lights settings", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_FramePadding))
  419. {
  420. pika::gl3d::lightEditorSettingsWindow(imguiId, renderer);
  421. }
  422. if (ImGui::CollapsingHeader("Sky box", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_FramePadding))
  423. {
  424. if (ImGui::Button("delete skybox"))
  425. {
  426. renderer.skyBox.clearTextures();
  427. }
  428. if (skyBoxFileSelector.run(imguiId))
  429. {
  430. auto ext = std::filesystem::path(skyBoxFileSelector.file).extension();
  431. if (ext == ".hdr") //todo pika to lower on strings
  432. {
  433. //todo api to log errors
  434. renderer.skyBox.clearTextures();
  435. renderer.skyBox = renderer.loadHDRSkyBox(skyBoxFileSelector.file);
  436. }
  437. else if (ext == ".png")
  438. {
  439. renderer.skyBox.clearTextures();
  440. renderer.skyBox = renderer.loadSkyBox(skyBoxFileSelector.file);
  441. }
  442. }
  443. ImGui::ColorEdit3("Global Ambient color", &renderer.skyBox.color[0]);
  444. ImGui::Separator();
  445. if (ImGui::Button("atmospheric scattering"))
  446. {
  447. renderer.skyBox.clearTextures();
  448. renderer.skyBox = renderer.atmosfericScattering(atmosphericScattering);
  449. }
  450. ImGui::DragFloat3("sun pos", &atmosphericScattering.sun[0], 0.1, -1, 1);
  451. ImGui::ColorEdit3("sky color", &atmosphericScattering.color1[0]);
  452. ImGui::ColorEdit3("sun color", &atmosphericScattering.color2[0]);
  453. ImGui::ColorEdit3("ground", &atmosphericScattering.ground[0]);
  454. ImGui::Checkbox("use ground", &atmosphericScattering.useGroundColor);
  455. ImGui::DragFloat("g", &atmosphericScattering.g, 0.1, 0, 50);
  456. float s = glm::length(atmosphericScattering.sun);
  457. if (s == 0)
  458. {
  459. atmosphericScattering.sun = {0,1,0};
  460. }
  461. else
  462. {
  463. atmosphericScattering.sun /= s;
  464. }
  465. }
  466. ImGui::PushID(123454);
  467. if (settingsFileSelector.run(imguiId))
  468. {
  469. //...
  470. }
  471. ImGui::PopID();
  472. if (ImGui::Button("save"))
  473. {
  474. saveToFile(renderer, info);
  475. }
  476. ImGui::SameLine();
  477. if (ImGui::Button("load"))
  478. {
  479. loadFromFile(renderer, settingsFileSelector.file, info);
  480. }
  481. }
  482. ImGui::End();
  483. ImGui::PopID();
  484. pika::gl3d::fpsInput(renderer, input, moveSpeed, lastMousePos, info, windowSize);
  485. }
  486. void pika::gl3d::General3DEditor::saveToFile(::gl3d::Renderer3D &renderer, RequestedContainerInfo &info)
  487. {
  488. auto rez = renderer.saveSettingsToJson(true);
  489. info.writeEntireFile(settingsFileSelector.file, rez);
  490. };