TerraForge3D  2.3.1
3D Terrain And Landscape Generator
Main.cpp
1#include "resource.h"
2
3#include <Misc/ExplorerControls.h>
4
5#include "Platform.h"
6
7
8
9// TerraForge3D Base
10
11#include <glad/glad.h>
12
13#ifdef TERR3D_WIN32
14#define GLFW_EXPOSE_NATIVE_WIN32 // For Windows
15#include <GLFW/glfw3.h>
16#include <GLFW/glfw3native.h>
17#endif
18
19#include "Base/Base.h"
20#include "Base/EntryPoint.h"
21
22// TerraForge3D Application
23#include "Data/ProjectData.h"
24#include "Data/ApplicationState.h"
25#include "Data/VersionInfo.h"
26#include "Generators/MeshGeneratorManager.h"
27#include "TextureStore/TextureStore.h"
28#include "Foliage/FoliagePlacement.h"
29#include "Misc/ExportManager.h"
30#include "Misc/OSLiscences.h"
31#include "Sky/SkySettings.h"
32#include "Misc/AppStyles.h"
33#include "Misc/SupportersTribute.h"
34
35#include "Platform.h"
36#include "Utils/Utils.h"
37
38#undef cNear
39#undef cFar
40
41#include "json/json.hpp"
42#include <zip.h>
43#include <sys/stat.h>
44
45#ifdef TERR3D_WIN32
46#include <dirent/dirent.h>
47#else
48#include <dirent.h>
49#endif
50
51
52
53
54
55#include "NoiseLayers/LayeredNoiseManager.h"
56
57static ApplicationState *appState;
58static Application *mainApp;
59
60
61void OnAppClose(int x, int y)
62{
63 Log("Close App");
64 appState->mainApp->Close();
65}
66
67
68static void ShowStats()
69{
70 ImGui::Begin("Statistics", &appState->windows.statsWindow);
71 ImGui::Text(("Vertex Count :" + std::to_string(appState->stats.vertexCount)).c_str());
72 ImGui::Text(("Triangles Count :" + std::to_string(appState->stats.triangles)).c_str());
73 ImGui::Text(("Framerate :" + std::to_string(appState->stats.frameRate)).c_str());
74 ImGui::End();
75}
76
77static void ShowGeneralControls()
78{
79 ImGui::Begin("General Controls");
80 {
81 ImGui::Checkbox("VSync ", &appState->states.vSync);
82 }
83 ImGui::DragFloat("Mouse Speed", &appState->globals.mouseSpeed);
84 ImGui::DragFloat("Zoom Speed", &appState->globals.scrollSpeed);
85
86 if (ImGui::Button("Exit"))
87 {
88 exit(0);
89 }
90
91 ImGui::End();
92}
93
94static void ResetShader()
95{
96 bool res = false;
97
98 if(appState->shaders.foliage)
99 {
100 delete appState->shaders.foliage;
101 }
102
103 if (!appState->shaders.wireframe)
104 {
105 appState->shaders.wireframe = new Shader(ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "default" PATH_SEPARATOR "vert.glsl", &res),
106 ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "default" PATH_SEPARATOR "frag.glsl", &res),
107 ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "default" PATH_SEPARATOR "geom.glsl", &res));
108 }
109
110 // appState->shaders.textureBake = new Shader(ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "texture_bake" PATH_SEPARATOR "vert.glsl", &res),
111 // ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "texture_bake" PATH_SEPARATOR "frag.glsl", &res),
112 // ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "texture_bake" PATH_SEPARATOR "geom.glsl", &res));
113
114 // appState->shaders.terrain = new Shader(ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "default" PATH_SEPARATOR "vert.glsl", &res),
115 // ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "default" PATH_SEPARATOR "frag.glsl", &res),
116 // ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "default" PATH_SEPARATOR "geom.glsl", &res));
117
118 appState->shaders.foliage = new Shader(ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "foliage" PATH_SEPARATOR "vert.glsl", &res),
119 ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "foliage" PATH_SEPARATOR "frag.glsl", &res),
120 ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "foliage" PATH_SEPARATOR "geom.glsl", &res));
121}
122
123static void RegenerateMesh()
124{
125 appState->meshGenerator->Generate();
126}
127
128
129static void DoTheRederThing(float deltaTime, bool renderWater = false, bool bakeTexture = false, bool bakeTextureFinal = false)
130{
131 static float time;
132 time += deltaTime;
133 appState->cameras.main.UpdateCamera();
134 Shader *shader;
135
136 // Texture Bake
137 if (appState->states.textureBake)
138 {
139
140 }
141
142 else
143 {
144 if (appState->states.skyboxEnabled)
145 {
146 appState->skyManager->RenderSky(appState->cameras.main.view, appState->cameras.main.pers);
147 }
148
149 glEnable(GL_DEPTH_TEST);
150 glEnable(GL_BLEND);
151 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
152
153 if (appState->states.wireFrameMode)
154 {
155 shader = appState->shaders.wireframe;
156 }
157
158 else
159 {
160 shader = appState->shaders.terrain;
161 }
162
163 shader->SetUniformf("_TextureBake", 0.0f);
164 shader->Bind();
165 shader->SetTime(&time);
166 shader->SetMPV(appState->cameras.main.pv);
167 appState->models.coreTerrain->Update();
168 shader->SetUniformMat4("_Model", appState->models.coreTerrain->modelMatrix);
169 shader->SetLightCol(appState->lightManager->color);
170 shader->SetLightPos(appState->lightManager->position);
171 shader->SetUniformf("_LightStrength", appState->lightManager->strength);
172 float tmp[3];
173 tmp[0] = appState->globals.viewportMousePosX;
174 tmp[1] = appState->globals.viewportMousePosY;
175 tmp[2] = ImGui::GetIO().MouseDown[0];
176 shader->SetUniform3f("_MousePos", tmp);
177 tmp[0] = appState->frameBuffers.main->GetWidth();
178 tmp[1] = appState->frameBuffers.main->GetHeight();
179 tmp[2] = 1;
180 shader->SetUniform3f("_Resolution", tmp);
181 shader->SetUniformf("_SeaLevel", appState->seaManager->level);
182 shader->SetUniform3f("_CameraPos", appState->cameras.main.position);
183 shader->SetUniformf("_CameraNear", appState->cameras.main.cNear);
184 shader->SetUniformf("_CameraFar", appState->cameras.main.cFar);
185 shader->SetUniformf("_FlatShade", appState->states.useGPUForNormals ? 1.0f : 0.0f);
186 appState->shadingManager->UpdateShaders();
187
188 if(appState->mode == ApplicationMode::TERRAIN)
189 {
190 appState->models.coreTerrain->Render();
191 }
192
193 else if (appState->mode == ApplicationMode::CUSTOM_BASE)
194 {
195 appState->models.customBase->Render();
196 }
197
198 if (appState->states.showFoliage)
199 {
200 shader = appState->shaders.foliage;
201 shader->Bind();
202 shader->SetTime(&time);
203 shader->SetMPV(appState->cameras.main.pv);
204 shader->SetUniformMat4("_Model", appState->models.coreTerrain->modelMatrix);
205 shader->SetLightCol(appState->lightManager->color);
206 shader->SetLightPos(appState->lightManager->position);
207 shader->SetUniformf("_LightStrength", appState->lightManager->strength);
208 float tmp[3];
209 tmp[0] = appState->globals.viewportMousePosX;
210 tmp[1] = appState->globals.viewportMousePosY;
211 tmp[2] = ImGui::GetIO().MouseDown[0];
212 shader->SetUniform3f("_MousePos", tmp);
213 tmp[0] = appState->frameBuffers.main->GetWidth();
214 tmp[1] = appState->frameBuffers.main->GetHeight();
215 tmp[2] = 1;
216 shader->SetUniform3f("_Resolution", tmp);
217 shader->SetUniformf("_SeaLevel", appState->seaManager->level);
218 shader->SetUniform3f("_CameraPos", appState->cameras.main.position);
219 shader->SetUniformf("_CameraNear", appState->cameras.main.cNear);
220 shader->SetUniformf("_CameraFar", appState->cameras.main.cFar);
221 appState->foliageManager->RenderFoliage(appState->cameras.main);
222 }
223
224 // For Future
225 //gridTex->Bind(5);
226 //grid->Render();
227
228 if (appState->seaManager->enabled && renderWater)
229 {
230 appState->seaManager->Render(appState->cameras.main, appState->lightManager, appState->frameBuffers.reflection, time);
231 }
232 }
233}
234
235void PostProcess(float deltatime)
236{
237 float pos[3] = { 0, 0, 1.8 };
238 float rot[3] = {0, 0, 0};
239 appState->cameras.postPorcess.aspect = 1;
240 appState->cameras.postPorcess.position[0] = 0.0f;
241 appState->cameras.postPorcess.position[0] = 0.0f;
242 appState->cameras.postPorcess.position[0] = 1.8f;
243 appState->cameras.postPorcess.rotation[0] = 0.0f;
244 appState->cameras.postPorcess.rotation[1] = 0.0f;
245 appState->cameras.postPorcess.rotation[2] = 0.0f;
246 appState->cameras.postPorcess.UpdateCamera();
247 float viewDir[3] = { glm::value_ptr(appState->cameras.main.pv)[2], glm::value_ptr(appState->cameras.main.pv)[6], glm::value_ptr(appState->cameras.main.pv)[10] };
248 appState->shaders.postProcess->Bind();
249 appState->shaders.postProcess->SetUniform3f("_CameraPosition", appState->cameras.main.position);
250 appState->shaders.postProcess->SetUniform3f("_ViewDir", viewDir);
251 float cloudsBoxMinMax[3] = {0.0f}; // Temporary
252 appState->shaders.postProcess->SetUniform3f("cloudsBoxBoundsMin", cloudsBoxMinMax);
253 appState->shaders.postProcess->SetUniform3f("cloudsBoxBoundsMax", cloudsBoxMinMax);
254 appState->shaders.postProcess->SetMPV(appState->cameras.postPorcess.pv);
255 glActiveTexture(GL_TEXTURE5);
256 glBindTexture(GL_TEXTURE_2D, appState->frameBuffers.main->GetColorTexture());
257 appState->shaders.postProcess->SetUniformi("_ColorTexture", 5);
258 glActiveTexture(GL_TEXTURE6);
259 glBindTexture(GL_TEXTURE_2D, appState->frameBuffers.main->GetDepthTexture());
260 appState->shaders.postProcess->SetUniformi("_DepthTexture", 6);
261 appState->models.screenQuad->Render();
262}
263
264static void ChangeCustomModel(std::string mdstr = ShowOpenFileDialog("*.obj"))
265{
266 while (appState->states.remeshing);
267
268 if(!appState->states.usingBase)
269 {
270 delete appState->models.customBase;
271 delete appState->models.customBaseCopy;
272 }
273
274 if(mdstr.size() > 3)
275 {
276 appState->globals.currentBaseModelPath = mdstr;
277 appState->states.usingBase = false;
278 appState->models.customBase = LoadModel(appState->globals.currentBaseModelPath);
279 appState->models.customBaseCopy = LoadModel(appState->globals.currentBaseModelPath); // Will Be Replaced with something efficient
280 appState->mode = ApplicationMode::CUSTOM_BASE;
281 }
282}
283
284static void ShowChooseBaseModelPopup()
285{
286 // TEMP
287 static std::shared_ptr<Texture2D> plane = std::make_shared<Texture2D>(appState->constants.texturesDir + PATH_SEPARATOR "ui_thumbs" PATH_SEPARATOR "plane.png", false, false);
288 static std::shared_ptr<Texture2D> sphere = std::make_shared<Texture2D>(appState->constants.texturesDir + PATH_SEPARATOR "ui_thumbs" PATH_SEPARATOR "sphere.png", false, false);
289 static std::shared_ptr<Texture2D> cube = std::make_shared<Texture2D>(appState->constants.texturesDir + PATH_SEPARATOR "ui_thumbs" PATH_SEPARATOR "cube.png", false, false);
290 static std::shared_ptr<Texture2D> cone = std::make_shared<Texture2D>(appState->constants.texturesDir + PATH_SEPARATOR "ui_thumbs" PATH_SEPARATOR "cone.png", false, false);
291 static std::shared_ptr<Texture2D> cyllinder = std::make_shared<Texture2D>(appState->constants.texturesDir + PATH_SEPARATOR "ui_thumbs" PATH_SEPARATOR "cylinder.png", false, false);
292 static std::shared_ptr<Texture2D> torus = std::make_shared<Texture2D>(appState->constants.texturesDir + PATH_SEPARATOR "ui_thumbs" PATH_SEPARATOR "torus.png", false, false);
293 // TEMP
294
295 if (ImGui::BeginPopup("Choose Base Model"))
296 {
297 if (ImGui::Button("Open From File"))
298 {
299 ChangeCustomModel();
300 ImGui::CloseCurrentPopup();
301 }
302
303 if (ImGui::Button("Close"))
304 {
305 ImGui::CloseCurrentPopup();
306 }
307
308 ImGui::BeginChild("Choose Base Model##Child", ImVec2(650, 450));
309
310 if (ImGui::ImageButton((ImTextureID)plane->GetRendererID(), ImVec2(200, 200)) )
311 {
312 while (appState->states.remeshing);
313
314 delete appState->models.customBase;
315 delete appState->models.customBaseCopy;
316 appState->states.usingBase = true;
317 appState->mode = ApplicationMode::TERRAIN;
318 ImGui::CloseCurrentPopup();
319 }
320
321 ImGui::SameLine();
322
323 if (ImGui::ImageButton((ImTextureID)sphere->GetRendererID(), ImVec2(200, 200)))
324 {
325 ChangeCustomModel(appState->constants.modelsDir + PATH_SEPARATOR "Sphere.obj");
326 ImGui::CloseCurrentPopup();
327 }
328
329 ImGui::SameLine();
330
331 if (ImGui::ImageButton((ImTextureID)cube->GetRendererID(), ImVec2(200, 200)))
332 {
333 ChangeCustomModel(appState->constants.modelsDir + PATH_SEPARATOR "cube.obj");
334 ImGui::CloseCurrentPopup();
335 }
336
337 if (ImGui::ImageButton((ImTextureID)torus->GetRendererID(), ImVec2(200, 200)))
338 {
339 ChangeCustomModel(appState->constants.modelsDir + PATH_SEPARATOR "Torus.obj");
340 ImGui::CloseCurrentPopup();
341 }
342
343 ImGui::SameLine();
344
345 if (ImGui::ImageButton((ImTextureID)cone->GetRendererID(), ImVec2(200, 200)))
346 {
347 ChangeCustomModel(appState->constants.modelsDir + PATH_SEPARATOR "cone.obj");
348 ImGui::CloseCurrentPopup();
349 }
350
351 ImGui::SameLine();
352
353 if (ImGui::ImageButton((ImTextureID)cyllinder->GetRendererID(), ImVec2(200, 200)))
354 {
355 ChangeCustomModel(appState->constants.modelsDir + PATH_SEPARATOR "cylinder.obj");
356 ImGui::CloseCurrentPopup();
357 }
358
359 ImGui::EndChild();
360 ImGui::EndPopup();
361 }
362}
363
364static void ShowTerrainControls()
365{
366 static bool exp = false;
367 ImGui::Begin("Dashboard");
368 ShowChooseBaseModelPopup();
369
370 if(appState->mode != ApplicationMode::TERRAIN)
371 {
372 ImGui::Text(("Current Base Model : " + appState->globals.currentBaseModelPath).c_str());
373
374 if(ImGui::Button("Change Current Base"))
375 {
376 ImGui::OpenPopup("Choose Base Model");
377 }
378
379 if(ImGui::Button("Switch to Plane"))
380 {
381 while(appState->states.remeshing);
382
383 delete appState->models.customBase;
384 delete appState->models.customBaseCopy;
385 appState->states.usingBase = true;
386 appState->mode = ApplicationMode::TERRAIN;
387 }
388 }
389
390 else
391 {
392 ImGui::Text("Current Base Model : Default Plane");
393
394 if (ImGui::Button("Change Current Base"))
395 {
396 ImGui::OpenPopup("Choose Base Model");
397 }
398 }
399
400 if(appState->mode == ApplicationMode::TERRAIN)
401 {
402 ImGui::DragInt("Mesh Resolution", &appState->globals.resolution, 1, 2, 16 * 4096);
403 }
404
405 if(appState->mode == ApplicationMode::TERRAIN || appState->mode == ApplicationMode::CUSTOM_BASE)
406 {
407 ImGui::DragFloat("Mesh Scale", &appState->globals.scale, 0.1f, 1.0f, 5000.0f);
408 }
409
410 ImGui::NewLine();
411 ImGui::Checkbox("Auto Update", &appState->states.autoUpdate);
412 ImGui::Checkbox("Post Processing", &appState->states.postProcess);
413 ImGui::Checkbox("Auto Save", &appState->states.autoSave);
414 ImGui::Checkbox("Wireframe Mode", &appState->states.wireFrameMode);
415 ImGui::Checkbox("Show Skybox", &appState->states.skyboxEnabled);
416 ImGui::Checkbox("Show Sea", &appState->seaManager->enabled);
417 ImGui::Checkbox("Show Foliage", &appState->states.showFoliage);
418 ImGui::Checkbox("Infinite Explorer Mode", &appState->states.iExploreMode);
419 ImGui::Checkbox("Explorer Mode", &appState->states.exploreMode);
420 ImGui::Checkbox("Texture Bake Mode", &appState->states.textureBake);
421 ImGui::NewLine();
422
423 if (ImGui::Button("Update Mesh"))
424 {
425 RegenerateMesh();
426 }
427
428 if (ImGui::Button("Recalculate Normals"))
429 {
430 while (appState->states.remeshing);
431
432 if (appState->mode == ApplicationMode::TERRAIN)
433 {
434 appState->models.coreTerrain->mesh->RecalculateNormals();
435 appState->models.coreTerrain->UploadToGPU();
436 }
437
438 else if (appState->mode == ApplicationMode::CUSTOM_BASE)
439 {
440 appState->models.customBase->mesh->RecalculateNormals();
441 appState->models.customBase->UploadToGPU();
442 }
443
444 else
445 {
446 Log("Unsupported App Mode!");
447 }
448 }
449
450 if (ImGui::Button("Refresh Shaders"))
451 {
452 ResetShader();
453 }
454
455 if (ImGui::Button("Use Custom Shaders"))
456 {
457 appState->windows.shaderEditorWindow = true;
458 }
459
460 if (ImGui::Button("Texture Settings"))
461 {
462 appState->windows.texturEditorWindow = true;
463 }
464
465 if (ImGui::Button("Sea Settings"))
466 {
467 appState->windows.seaEditor = true;
468 }
469
470 if (ImGui::Button("Filter Settings"))
471 {
472 appState->windows.filtersManager = true;
473 }
474
475 if (ImGui::Button("Export Frame"))
476 {
477 ExportTexture(appState->frameBuffers.main->GetRendererID(), ShowSaveFileDialog(".png"), appState->frameBuffers.main->GetWidth(), appState->frameBuffers.main->GetHeight());
478 }
479
480 ImGui::Separator();
481 ImGui::NewLine();
482 //if(appState->modules.manager->uiModules.size() > 0)
483 // ImGui::Text("UI Modules");
484 //int i = 0;
485 //for (UIModule* mod : appState->modules.manager->uiModules)
486 //ImGui::Checkbox(MAKE_IMGUI_LABEL(i++, mod->windowName), &mod->active);
487 ImGui::Separator();
488 ImGui::End();
489}
490
491static void MouseMoveCallback(float x, float y)
492{
493 static glm::vec2 prevMousePos; // This is temporary
494 float deltaX = x - prevMousePos.x;
495 float deltaY = y - prevMousePos.y;
496
497 if (appState->states.mouseButton2)
498 {
499 if (deltaX > 200)
500 {
501 deltaX = 0;
502 }
503
504 if (deltaY > 200)
505 {
506 deltaY = 0;
507 }
508
509 appState->cameras.main.rotation[0] += deltaX * appState->globals.mouseSpeed;
510 appState->cameras.main.rotation[1] += deltaY * appState->globals.mouseSpeed;
511 }
512
513 prevMousePos.x = x;
514 prevMousePos.y = y;
515}
516
517static void MouseScrollCallback(float amount)
518{
519 appState->globals.mouseScrollAmount = amount;
520 glm::vec3 pPos = glm::vec3(appState->cameras.main.position[0], appState->cameras.main.position[1], appState->cameras.main.position[2]);
521 pPos += appState->constants.FRONT * amount * appState->globals.scrollSpeed;
522 appState->cameras.main.position[0] = pPos.x;
523 appState->cameras.main.position[1] = pPos.y;
524 appState->cameras.main.position[2] = pPos.z;
525}
526
527
528static void ShowMainScene()
529{
530 auto viewportMinRegion = ImGui::GetWindowContentRegionMin();
531 auto viewportMaxRegion = ImGui::GetWindowContentRegionMax();
532 auto viewportOffset = ImGui::GetWindowPos();
533 ImGui::Begin("Viewport");
534 {
535 ImGui::BeginChild("MainRender");
536
537 if (ImGui::IsWindowHovered())
538 {
539 ImGuiIO io = ImGui::GetIO();
540 MouseMoveCallback(io.MousePos.x, io.MousePos.y);
541 MouseScrollCallback(io.MouseWheel);
542 appState->states.mouseButton1 = io.MouseDown[0];
543 appState->states.mouseButton2 = io.MouseDown[2];
544 appState->states.mouseButton3 = io.MouseDown[1];
545
546 if (ImGui::GetIO().MouseDown[1])
547 {
548 appState->cameras.main.position[0] += -io.MouseDelta.x * 0.005f * glm::distance(glm::vec3(0.0f), glm::vec3(appState->cameras.main.position[0], appState->cameras.main.position[1], appState->cameras.main.position[2]));
549 appState->cameras.main.position[1] += io.MouseDelta.y * 0.005f * glm::distance(glm::vec3(0.0f), glm::vec3(appState->cameras.main.position[0], appState->cameras.main.position[1], appState->cameras.main.position[2]));
550 }
551
552 appState->globals.viewportMousePosX = ImGui::GetIO().MousePos.x - viewportOffset.x;
553 appState->globals.viewportMousePosY = ImGui::GetIO().MousePos.y - viewportOffset.y;
554 }
555
556 ImVec2 wsize = ImGui::GetWindowSize();
557 appState->globals.viewportSize[0] = wsize.x;
558 appState->globals.viewportSize[1] = wsize.y;
559
560
561 if (appState->states.postProcess)
562 {
563 ImGui::Image((ImTextureID)appState->frameBuffers.postProcess->GetColorTexture(), wsize, ImVec2(0, 1), ImVec2(1, 0));
564 }
565
566 else
567 {
568 ImGui::Image((ImTextureID)appState->frameBuffers.main->GetColorTexture(), wsize, ImVec2(0, 1), ImVec2(1, 0));
569 }
570
571 ImGui::EndChild();
572 }
573 ImGui::End();
574}
575
576static void SaveFile(std::string file = ShowSaveFileDialog())
577{
578 appState->serailizer->SaveFile(file);
579}
580
581static void OpenSaveFile(std::string file = ShowOpenFileDialog(".terr3d"))
582{
583 appState->serailizer->LoadFile(file);
584}
585
586
587static void PackProject(std::string path = ShowSaveFileDialog())
588{
589 appState->serailizer->PackProject(path);
590}
591
592static void LoadPackedProject(std::string path = ShowOpenFileDialog())
593{
594 appState->serailizer->LoadPackedProject(path);
595}
596
597
598static void ShowModuleManager()
599{
600 appState->modules.manager->ShowSettings(&appState->windows.modulesManager);
601}
602
603static void OnBeforeImGuiRender()
604{
605 static bool dockspaceOpen = true;
606 static bool opt_fullscreen_persistant = true;
607 bool opt_fullscreen = opt_fullscreen_persistant;
608 static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
609 ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
610
611 if (opt_fullscreen)
612 {
613 ImGuiViewport *viewport = ImGui::GetMainViewport();
614 ImGui::SetNextWindowPos(viewport->Pos);
615 ImGui::SetNextWindowSize(viewport->Size);
616 ImGui::SetNextWindowViewport(viewport->ID);
617 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.1f);
618 ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
619 window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
620 window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
621 }
622
623 if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode)
624 {
625 window_flags |= ImGuiWindowFlags_NoBackground;
626 }
627
628 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
629 ImGui::Begin("DockSpace", &dockspaceOpen, window_flags);
630 ImGui::PopStyleVar();
631
632 if (opt_fullscreen)
633 {
634 ImGui::PopStyleVar(2);
635 }
636
637 // DockSpace
638 ImGuiIO &io = ImGui::GetIO();
639 ImGuiStyle &style = ImGui::GetStyle();
640 float minWinSizeX = style.WindowMinSize.x;
641 style.WindowMinSize.x = 370.0f;
642
643 if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
644 {
645 ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
646 ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
647 }
648
649 style.WindowMinSize.x = minWinSizeX;
650}
651
652static void OnImGuiRenderEnd()
653{
654 ImGui::End();
655}
656
657static void SetUpIcon()
658{
659#ifdef TERR3D_WIN32
660 HWND hwnd = glfwGetWin32Window(mainApp->GetWindow()->GetNativeWindow());
661 HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
662
663 if (hIcon)
664 {
665 //Change both icons to the same icon handle.
666 SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
667 SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
668 //This will ensure that the application icon gets changed too.
669 SendMessage(GetWindow(hwnd, GW_OWNER), WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
670 SendMessage(GetWindow(hwnd, GW_OWNER), WM_SETICON, ICON_BIG, (LPARAM)hIcon);
671 }
672
673#endif
674}
675
676
677class MyApp : public Application
678{
679public:
680 virtual void OnPreload() override
681 {
682 SetTitle("TerraForge3D - Jaysmito Mukherjee");
683 MkDir(GetExecutableDir() + PATH_SEPARATOR "Data" PATH_SEPARATOR "logs");
684 SetLogsDir(GetExecutableDir() + PATH_SEPARATOR "Data" PATH_SEPARATOR "logs");
685 SetWindowConfigPath(GetExecutableDir() + PATH_SEPARATOR "Data" PATH_SEPARATOR "configs" PATH_SEPARATOR "windowconfigs.terr3d");
686 MkDir(GetExecutableDir() + PATH_SEPARATOR "Data" PATH_SEPARATOR "cache" PATH_SEPARATOR "autosave\"");
687 MkDir(GetExecutableDir() + PATH_SEPARATOR "Data" PATH_SEPARATOR "temp\"");
688 }
689
690 virtual void OnUpdate(float deltatime) override
691 {
692 if (!appState->states.ruinning)
693 {
694 return;
695 }
696
697 if (!appState->states.exploreMode)
698 {
699 // CTRL Shortcuts
700 if ((glfwGetKey(GetWindow()->GetNativeWindow(), GLFW_KEY_LEFT_CONTROL) || glfwGetKey(GetWindow()->GetNativeWindow(), GLFW_KEY_RIGHT_CONTROL)))
701 {
702 // Open Shortcut
703 if (glfwGetKey(GetWindow()->GetNativeWindow(), GLFW_KEY_O))
704 {
705 OpenSaveFile();
706 }
707
708 // Exit Shortcut
709 if (glfwGetKey(GetWindow()->GetNativeWindow(), GLFW_KEY_Q))
710 {
711 exit(0);
712 }
713
714 // Save Shortcut
715 if (glfwGetKey(GetWindow()->GetNativeWindow(), GLFW_KEY_S))
716 {
717 if (appState->globals.currentOpenFilePath.size() > 3)
718 {
719 Log("Saved to " + appState->globals.currentOpenFilePath);
720 SaveFile(appState->globals.currentOpenFilePath);
721 }
722
723 else
724 {
725 SaveFile();
726 }
727 }
728
729 // Close Shortcut
730 if (glfwGetKey(GetWindow()->GetNativeWindow(), GLFW_KEY_W))
731 {
732 if (appState->globals.currentOpenFilePath.size() > 3)
733 {
734 Log("CLosed file " + appState->globals.currentOpenFilePath);
735 appState->globals.currentOpenFilePath = "";
736 }
737
738 else
739 {
740 Log("Shutting Down");
741 exit(0);
742 }
743 }
744
745 // CTRL + SHIFT Shortcuts
746 if ((glfwGetKey(GetWindow()->GetNativeWindow(), GLFW_KEY_LEFT_SHIFT) || glfwGetKey(GetWindow()->GetNativeWindow(), GLFW_KEY_RIGHT_SHIFT))) // Save Shortcut
747 {
748 // Save As Shortcuts
749 if (glfwGetKey(GetWindow()->GetNativeWindow(), GLFW_KEY_S))
750 {
751 appState->globals.currentOpenFilePath = "";
752 SaveFile();
753 }
754
755 // Explorer Mode Shortcut
756 if (glfwGetKey(GetWindow()->GetNativeWindow(), GLFW_KEY_X))
757 {
758 Log("Toggle Explorer Mode");
759 appState->states.exploreMode = true;
760 }
761 }
762 }
763
764 appState->stats.deltatime = deltatime;
765
766 {
767 appState->frameBuffers.reflection->Begin();
768 glViewport(0, 0, appState->frameBuffers.reflection->GetWidth(), appState->frameBuffers.reflection->GetHeight());
769 GetWindow()->Clear();
770 DoTheRederThing(deltatime);
771 glBindFramebuffer(GL_FRAMEBUFFER, appState->frameBuffers.main->GetRendererID());
772 glViewport(0, 0, appState->frameBuffers.main->GetWidth(), appState->frameBuffers.main->GetHeight());
773 GetWindow()->Clear();
774 DoTheRederThing(deltatime, true);
775
776 if (appState->states.postProcess)
777 {
778 appState->frameBuffers.postProcess->Begin();
779 GetWindow()->Clear();
780 PostProcess(deltatime);
781 }
782 }
783
784 glBindFramebuffer(GL_FRAMEBUFFER, 0);
785 RenderImGui();
786 }
787
788 else
789 {
790 static bool expH = false;
791
792 if (!expH)
793 {
794 GetWindow()->SetFullScreen(true);
795 glfwSetInputMode(GetWindow()->GetNativeWindow(), GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
796 ExPSaveCamera(appState->cameras.main.position, appState->cameras.main.rotation);
797 }
798
799 expH = appState->states.exploreMode;
800 appState->stats.deltatime = deltatime;
801 appState->frameBuffers.reflection->Begin();
802 glViewport(0, 0, appState->frameBuffers.reflection->GetWidth(), appState->frameBuffers.reflection->GetHeight());
803 GetWindow()->Clear();
804 DoTheRederThing(deltatime);
805 appState->frameBuffers.reflection->End();
806 glBindFramebuffer(GL_FRAMEBUFFER, 0);
807 int w, h;
808 glfwGetWindowSize(GetWindow()->GetNativeWindow(), &w, &h);
809 glViewport(0, 0, w, h);
810 GetWindow()->Clear();
811 UpdateExplorerControls(appState->cameras.main.position, appState->cameras.main.rotation, appState->states.iExploreMode, &appState->globals.offset[0], &appState->globals.offset[1]);
812 DoTheRederThing(deltatime, true);
813
814 if (appState->states.postProcess)
815 {
816 appState->frameBuffers.postProcess->Begin();
817 PostProcess(deltatime);
818 }
819
820 if ((glfwGetKey(GetWindow()->GetNativeWindow(), GLFW_KEY_ESCAPE)))
821 {
822 appState->states.exploreMode = false;
823 expH = false;
824 glfwSetInputMode(GetWindow()->GetNativeWindow(), GLFW_CURSOR, GLFW_CURSOR_NORMAL);
825 GetWindow()->SetFullScreen(false);
826 ExPRestoreCamera(appState->cameras.main.position, appState->cameras.main.rotation);
827 }
828 }
829
830 if (appState->states.autoUpdate)
831 {
832 RegenerateMesh();
833 }
834
835 appState->modules.manager->UpdateModules();
836 }
837
838 virtual void OnOneSecondTick() override
839 {
840 if (!appState->states.ruinning)
841 {
842 return;
843 }
844
845 appState->globals.secondCounter++;
846
847 if (appState->globals.secondCounter % 5 == 0)
848 {
849 if (appState->states.autoSave)
850 {
851 SaveFile(appState->constants.cacheDir + PATH_SEPARATOR "autosave" PATH_SEPARATOR "autosave.terr3d");
852
853 if (appState->globals.currentOpenFilePath.size() > 3)
854 {
855 SaveFile(appState->globals.currentOpenFilePath);
856 }
857 }
858 }
859
860 GetWindow()->SetVSync(appState->states.vSync);
861 appState->stats.frameRate = 1 / appState->stats.deltatime;
862 }
863
864 virtual void OnImGuiRender() override
865 {
866 OnBeforeImGuiRender();
867 appState->mainMenu->ShowMainMenu();
868 ShowGeneralControls();
869
870 if (appState->windows.cameraControls)
871 {
872 ImGui::Begin("Camera Controls", &appState->windows.cameraControls);
873 appState->cameras.main.ShowSettings();
874 ImGui::Checkbox("Auto Calculate Aspect Ratio", &appState->states.autoAspectCalcRatio);
875 ImGui::End();
876 }
877
878 if (appState->states.autoAspectCalcRatio && (appState->globals.viewportSize[1] != 0 && appState->globals.viewportSize[0] != 0))
879 {
880 appState->cameras.main.aspect = appState->globals.viewportSize[0] / appState->globals.viewportSize[1];
881 }
882
883 appState->lightManager->ShowSettings(true, &appState->windows.lightControls);
884 appState->meshGenerator->ShowSettings();
885 ShowTerrainControls();
886 ShowMainScene();
887
888 // Optional Windows
889
890 if (appState->windows.statsWindow)
891 {
892 ShowStats();
893 }
894
895 appState->seaManager->ShowSettings(&appState->windows.seaEditor);
896
897 if (appState->windows.modulesManager)
898 {
899 ShowModuleManager();
900 }
901
902 if (appState->windows.styleEditor)
903 {
904 ShowStyleEditor(&appState->windows.styleEditor);
905 }
906
907 if (appState->windows.foliageManager)
908 {
909 appState->foliageManager->ShowSettings(&appState->windows.foliageManager);
910 }
911
912 if(appState->windows.textureStore)
913 {
914 appState->textureStore->ShowSettings(&appState->windows.textureStore);
915 }
916
917 if(appState->windows.shadingManager)
918 {
919 appState->shadingManager->ShowSettings(&appState->windows.shadingManager);
920 }
921
922 if (appState->windows.filtersManager)
923 {
924 appState->filtersManager->ShowSettings(&appState->windows.filtersManager);
925 }
926
927 if (appState->windows.osLisc)
928 {
929 appState->osLiscences->ShowSettings(&appState->windows.osLisc);
930 }
931
932 if (appState->windows.supportersTribute)
933 {
934 appState->supportersTribute->ShowSettings(&appState->windows.supportersTribute);
935 }
936
937 if (appState->windows.skySettings)
938 {
939 appState->skyManager->ShowSettings(&appState->windows.skySettings);
940 }
941
942 if(appState->windows.textureBaker)
943 {
944 appState->textureBaker->ShowSettings(&appState->windows.textureBaker);
945 }
946
947 OnImGuiRenderEnd();
948 }
949
950 virtual void OnStart(std::string loadFile) override
951 {
952 // Set random generator seed from current time
953 srand((unsigned int)time(NULL));
954 // Setup custom icon for the Main Window
955 SetUpIcon();
956 appState = new ApplicationState();
957 appState->mainApp = mainApp;
958 appState->constants.executableDir = GetExecutableDir();
959 appState->constants.dataDir = appState->constants.executableDir + PATH_SEPARATOR "Data";
960 appState->constants.cacheDir = appState->constants.dataDir + PATH_SEPARATOR "cache";
961 appState->constants.texturesDir = appState->constants.dataDir + PATH_SEPARATOR "textures";
962 appState->constants.projectsDir = appState->constants.cacheDir + PATH_SEPARATOR "project_data";
963 appState->constants.tempDir = appState->constants.dataDir + PATH_SEPARATOR "temp";
964 appState->constants.shadersDir = appState->constants.dataDir + PATH_SEPARATOR "shaders";
965 appState->constants.kernelsDir = appState->constants.dataDir + PATH_SEPARATOR "kernels";
966 appState->constants.fontsDir = appState->constants.dataDir + PATH_SEPARATOR "fonts";
967 appState->constants.liscensesDir = appState->constants.dataDir + PATH_SEPARATOR "licenses";
968 appState->constants.skyboxDir = appState->constants.dataDir + PATH_SEPARATOR "skybox";
969 appState->constants.modulesDir = appState->constants.dataDir + PATH_SEPARATOR "modules";
970 appState->constants.configsDir = appState->constants.dataDir + PATH_SEPARATOR "configs";
971 appState->constants.logsDir = appState->constants.dataDir + PATH_SEPARATOR "logs";
972 appState->constants.modelsDir = appState->constants.dataDir + PATH_SEPARATOR "models";
973 appState->supportersTribute = new SupportersTribute();
974 SetupExplorerControls();
975 ImGui::GetStyle().WindowMenuButtonPosition = ImGuiDir_None;
976 LoadDefaultStyle();
977 GetWindow()->SetShouldCloseCallback(OnAppClose);
978 glfwSetFramebufferSizeCallback(GetWindow()->GetNativeWindow(), [](GLFWwindow* window, int w, int h)
979 {
980 glfwSwapBuffers(window);
981 });
982 glfwSetScrollCallback(GetWindow()->GetNativeWindow(), [](GLFWwindow *, double x, double y)
983 {
984 ImGuiIO &io = ImGui::GetIO();
985 io.MouseWheel = (float)y;
986 });
987 glfwSetDropCallback(GetWindow()->GetNativeWindow(), [](GLFWwindow *, int count, const char ** paths)
988 {
989 for (int i = 0; i < count; i++)
990 {
991 std::string path = paths[i];
992 if (path.find(".terr3d") != std::string::npos)
993 {
994 appState->serailizer->LoadFile(path);
995 }
996 else if(path.find(".terr3dpack") != std::string::npos)
997 {
998 appState->serailizer->LoadPackedProject(path);
999 }
1000 }
1001 });
1002 GetWindow()->SetClearColor({ 0.1f, 0.1f, 0.1f });
1003 appState->globals.kernelsIncludeDir = "\""+ appState->constants.kernelsDir + "\"";
1004 appState->modules.manager = new ModuleManager(appState);
1005 appState->meshGenerator = new MeshGeneratorManager(appState);
1006 appState->mainMenu = new MainMenu(appState);
1007 appState->seaManager = new SeaManager(appState);
1008 appState->lightManager = new LightManager();
1009 appState->skyManager = new SkyManager(appState);
1010 appState->foliageManager = new FoliageManager(appState);
1011 appState->projectManager = new ProjectManager(appState);
1012 appState->serailizer = new Serializer(appState);
1013 appState->osLiscences = new OSLiscences(appState);
1014 appState->textureStore = new TextureStore(appState);
1015 appState->shadingManager = new ShadingManager(appState);
1016 appState->textureBaker = new TextureBaker(appState);
1017 ResetShader();
1018 appState->meshGenerator->GenerateSync();
1019 appState->models.coreTerrain->SetupMeshOnGPU();
1020 appState->models.screenQuad->SetupMeshOnGPU();
1021 appState->models.screenQuad->mesh->GenerateScreenQuad();
1022 appState->models.screenQuad->mesh->RecalculateNormals();
1023 appState->models.screenQuad->UploadToGPU();
1024 glEnable(GL_DEPTH_TEST);
1025 appState->globals.scale = 1;
1026
1027 if (loadFile.size() > 0)
1028 {
1029 Log("Loading File from " + loadFile);
1030 OpenSaveFile(loadFile);
1031 }
1032
1033 appState->projectManager->SetId(GenerateId(32));
1034 appState->filtersManager = new FiltersManager(appState);
1035 float t = 1.0f;
1036 // Load Fonts
1037 LoadUIFont("Open-Sans-Regular", 18, appState->constants.fontsDir + PATH_SEPARATOR "OpenSans-Regular.ttf");
1038 LoadUIFont("OpenSans-Bold", 25, appState->constants.fontsDir + PATH_SEPARATOR "OpenSans-Bold.ttf");
1039 LoadUIFont("OpenSans-Semi-Bold", 22, appState->constants.fontsDir + PATH_SEPARATOR "OpenSans-Bold.ttf");
1040 // The framebuffer used for reflections in the sea
1041 appState->frameBuffers.reflection = new FrameBuffer();
1042 // The main frame buffer
1043 appState->frameBuffers.main = new FrameBuffer(1280, 720);
1044 // The Framebuffer used for post processing
1045 appState->frameBuffers.postProcess = new FrameBuffer(1280, 720);
1046 bool tpp = false;
1047 appState->shaders.postProcess = new Shader(ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "post_processing" PATH_SEPARATOR "vert.glsl", &tpp),
1048 ReadShaderSourceFile(appState->constants.shadersDir + PATH_SEPARATOR "post_processing" PATH_SEPARATOR "frag.glsl", &tpp));
1049 appState->states.autoUpdate = true;
1050
1051 if(IsNetWorkConnected())
1052 {
1053 if(FileExists(appState->constants.configsDir + PATH_SEPARATOR "server.terr3d"))
1054 {
1055 bool ttmp = false;
1056 std::string uid = ReadShaderSourceFile(appState->constants.configsDir + PATH_SEPARATOR "server.terr3d", &ttmp);
1057 Log("Connection to Backend : " + FetchURL("https://terraforge3d.maxalpha.repl.co", "/startup/" + uid));
1058 }
1059
1060 else
1061 {
1062 DownloadFile("https://terraforge3d.maxalpha.repl.co", "/register", appState->constants.configsDir + PATH_SEPARATOR "server.terr3d");
1063 bool ttmp = false;
1064 std::string uid = ReadShaderSourceFile(appState->constants.configsDir + PATH_SEPARATOR "server.terr3d", &ttmp);
1065 Log("Connection to Backend : " + FetchURL("https://terraforge3d.maxalpha.repl.co", "/startup/" + uid));
1066 }
1067 }
1068
1069 appState->windows.shadingManager = true; // TEMPORARY FOR DEBUG ONLY
1070 Log("Started Up App!");
1071 }
1072
1073 void OnEnd()
1074 {
1075 while (appState->states.remeshing);
1076
1077 using namespace std::chrono_literals;
1078 std::this_thread::sleep_for(500ms);
1079 delete appState->shaders.terrain;
1080 delete appState->shaders.foliage;
1081 delete appState->shaders.wireframe;
1082 delete appState->shaders.postProcess;
1083 delete appState->supportersTribute;
1084 delete appState->mainMenu;
1085 delete appState->skyManager;
1086 delete appState->frameBuffers.main;
1087 delete appState->frameBuffers.postProcess;
1088 delete appState->frameBuffers.reflection;
1089 delete appState->filtersManager;
1090 delete appState->osLiscences;
1091 delete appState->textureBaker;
1092 delete appState->projectManager;
1093 delete appState->foliageManager;
1094 delete appState->shadingManager;
1095// delete appState->seaManager;
1096 delete appState->lightManager;
1097 delete appState->serailizer;
1098 delete appState;
1099 }
1100};
1101
1102Application *CreateApplication()
1103{
1104 mainApp = new MyApp();
1105 return mainApp;
1106}
Definition: Main.cpp:678
Definition: Shader.h:7