aboutsummaryrefslogtreecommitdiff
path: root/app/source/Cplt/Entrypoint/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app/source/Cplt/Entrypoint/main.cpp')
-rw-r--r--app/source/Cplt/Entrypoint/main.cpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/app/source/Cplt/Entrypoint/main.cpp b/app/source/Cplt/Entrypoint/main.cpp
new file mode 100644
index 0000000..8f67d32
--- /dev/null
+++ b/app/source/Cplt/Entrypoint/main.cpp
@@ -0,0 +1,163 @@
+#include <Cplt/Entrypoint/Backend.hpp>
+#include <Cplt/Model/GlobalStates.hpp>
+#include <Cplt/UI/UI.hpp>
+#include <Cplt/Utils/I18n.hpp>
+#include <Cplt/Utils/ScopeGuard.hpp>
+#include <Cplt/Utils/Sigslot.hpp>
+
+#include <IconsFontAwesome.h>
+#include <imgui.h>
+#include <argparse/argparse.hpp>
+#include <filesystem>
+#include <iostream>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <string_view>
+
+namespace fs = std::filesystem;
+using namespace std::literals::string_literals;
+using namespace std::literals::string_view_literals;
+
+static std::unique_ptr<RenderingBackend> CreateDefaultBackend()
+{
+#if defined(_WIN32)
+# if BUILD_CORE_WITH_DX12_BACKEND
+ if (auto backend = RenderingBackend::CreateDx12Backend()) {
+ return backend;
+ }
+# endif
+# if BUILD_CORE_WITH_DX11_BACKEND
+ if (auto backend = RenderingBackend::CreateDx11Backend()) {
+ return backend;
+ }
+# endif
+# if BUILD_CORE_WITH_VULKAN_BACKEND
+ if (auto backend = RenderingBackend::CreateVulkanBackend()) {
+ return backend;
+ }
+# endif
+# if BUILD_CORE_WITH_OPENGL3_BACKEND
+ if (auto backend = RenderingBackend::CreateOpenGL3Backend()) {
+ return backend;
+ }
+# endif
+# if BUILD_CORE_WITH_OPENGL2_BACKEND
+ if (auto backend = RenderingBackend::CreateOpenGL2Backend()) {
+ return backend;
+ }
+# endif
+#elif defined(__APPLE__)
+ // We currently only support using metal on macos
+ return RenderingBackend::CreateMetalBackend();
+#elif defined(__linux__)
+# if BUILD_CORE_WITH_VULKAN_BACKEND
+ if (auto backend = RenderingBackend::CreateVulkanBackend()) {
+ return backend;
+ }
+# endif
+# if BUILD_CORE_WITH_OPENGL3_BACKEND
+ if (auto backend = RenderingBackend::CreateOpenGL3Backend()) {
+ return backend;
+ }
+# endif
+# if BUILD_CORE_WITH_OPENGL2_BACKEND
+ if (auto backend = RenderingBackend::CreateOpenGL2Backend()) {
+ return backend;
+ }
+# endif
+#endif
+
+ return nullptr;
+}
+
+static std::unique_ptr<RenderingBackend> CreateBackend(std::string_view option)
+{
+ if (option == "default") {
+ return CreateDefaultBackend();
+ } else if (option == "opengl2") {
+ return RenderingBackend::CreateOpenGL2Backend();
+ } else if (option == "opengl3") {
+ return RenderingBackend::CreateOpenGL3Backend();
+ } else if (option == "vulkan") {
+ return RenderingBackend::CreateVulkanBackend();
+ } else if (option == "dx11") {
+ return RenderingBackend::CreateDx11Backend();
+ } else if (option == "dx12") {
+ return RenderingBackend::CreateDx12Backend();
+ } else if (option == "metal") {
+ return RenderingBackend::CreateMetalBackend();
+ } else {
+ std::string message;
+ message += "Unknown backend '";
+ message += option;
+ message += "'.\n";
+ throw std::runtime_error(message);
+ }
+}
+
+#ifdef DOCTEST_CONFIG_DISABLE
+int main(int argc, char* argv[])
+{
+ argparse::ArgumentParser parser;
+ parser.add_argument("--global-data-directory")
+ .help("Directory in which global data (such as recently used projects) are saved to. Use 'default' to use the default directory on each platform.")
+ .default_value("default"s);
+ parser.add_argument("--rendering-backend")
+ .help("Which rendering backend to use. If equals 'default', the preferred API for each platform will be used")
+ .default_value("default"s);
+
+ try {
+ parser.parse_args(argc, argv);
+ } catch (const std::runtime_error& error) {
+ std::cout << error.what() << '\n';
+ std::cout << parser;
+ return -1;
+ }
+
+ auto backendOption = parser.get<std::string>("--rendering-backend");
+ auto backend = CreateBackend(backendOption);
+
+ auto& io = ImGui::GetIO();
+
+ // Disable saving window positions
+ io.IniFilename = nullptr;
+ // Disable log (dump widget tree) file, we don't trigger it but just to be safe
+ io.LogFilename = nullptr;
+
+ // Light mode because all major OS's default theme is white
+ // TODO follow system theme
+ ImGui::StyleColorsLight();
+
+ // Configure default fonts
+ {
+ // Includes latin alphabet, although for some reason smaller than if rendered using 18 point NotoSans regular
+ io.Fonts->AddFontFromFileTTF("fonts/NotoSansSC-Regular.otf", 18, nullptr, io.Fonts->GetGlyphRangesChineseFull());
+
+ ImWchar iconRanges[] = { ICON_MIN_FA, ICON_MAX_FA };
+ ImFontConfig config;
+ config.MergeMode = true;
+ io.Fonts->AddFontFromFileTTF("fonts/FontAwesome5-Solid.otf", 14, &config, iconRanges);
+ }
+
+ auto dataDirOption = parser.get<std::string>("--global-data-directory");
+ if (dataDirOption == "default") {
+ GlobalStates::Init();
+ } else {
+ fs::path path(dataDirOption);
+ GlobalStates::Init(std::move(path));
+ }
+ DEFER
+ {
+ GlobalStates::Shutdown();
+ };
+
+ // Main loop
+ backend->RunUntilWindowClose(&UI::MainWindow);
+
+ return 0;
+}
+#else
+# define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+# include <doctest/doctest.h>
+#endif