From bdcc81822adddf2c6ad7f10d9e090d913475c1e0 Mon Sep 17 00:00:00 2001 From: rtk0c Date: Sun, 28 Mar 2021 13:24:52 -0700 Subject: Initial code structure --- .gitignore | 2 + 3rdparty/imgui/CMakeLists.txt | 85 ++++++++++++++++++++++++++++++++++- 3rdparty/imnodes/CMakeLists.txt | 12 ++++- CMakeLists.txt | 4 ++ conanfile.txt | 1 + core/CMakeLists.txt | 60 +++++++++++++++++++++---- core/fonts/NotoSansSC-LICENSE.txt | 91 ++++++++++++++++++++++++++++++++++++++ core/fonts/NotoSansSC-Regular.otf | Bin 0 -> 8481960 bytes core/src/Entrypoint/Common.cpp | 11 +++++ core/src/Entrypoint/Common.hpp | 20 +++++++++ core/src/Entrypoint/DirectX11.cpp | 13 ++++++ core/src/Entrypoint/DirectX11.hpp | 11 +++++ core/src/Entrypoint/DirectX12.cpp | 13 ++++++ core/src/Entrypoint/DirectX12.hpp | 11 +++++ core/src/Entrypoint/Metal.hpp | 11 +++++ core/src/Entrypoint/Metal.mm | 13 ++++++ core/src/Entrypoint/OpenGL2.cpp | 70 +++++++++++++++++++++++++++++ core/src/Entrypoint/OpenGL2.hpp | 15 +++++++ core/src/Entrypoint/OpenGL3.cpp | 85 +++++++++++++++++++++++++++++++++++ core/src/Entrypoint/OpenGL3.hpp | 15 +++++++ core/src/Entrypoint/Vulkan.cpp | 13 ++++++ core/src/Entrypoint/Vulkan.hpp | 11 +++++ core/src/Entrypoint/main.cpp | 91 ++++++++++++++++++++++++++++++++++++++ core/src/UI/Export.cpp | 1 + core/src/UI/Export.hpp | 1 + 25 files changed, 647 insertions(+), 13 deletions(-) create mode 100644 core/fonts/NotoSansSC-LICENSE.txt create mode 100644 core/fonts/NotoSansSC-Regular.otf create mode 100644 core/src/Entrypoint/Common.cpp create mode 100644 core/src/Entrypoint/Common.hpp create mode 100644 core/src/Entrypoint/DirectX11.cpp create mode 100644 core/src/Entrypoint/DirectX11.hpp create mode 100644 core/src/Entrypoint/DirectX12.cpp create mode 100644 core/src/Entrypoint/DirectX12.hpp create mode 100644 core/src/Entrypoint/Metal.hpp create mode 100644 core/src/Entrypoint/Metal.mm create mode 100644 core/src/Entrypoint/OpenGL2.cpp create mode 100644 core/src/Entrypoint/OpenGL2.hpp create mode 100644 core/src/Entrypoint/OpenGL3.cpp create mode 100644 core/src/Entrypoint/OpenGL3.hpp create mode 100644 core/src/Entrypoint/Vulkan.cpp create mode 100644 core/src/Entrypoint/Vulkan.hpp create mode 100644 core/src/Entrypoint/main.cpp create mode 100644 core/src/UI/Export.cpp create mode 100644 core/src/UI/Export.hpp diff --git a/.gitignore b/.gitignore index 95ff04c..223be0c 100644 --- a/.gitignore +++ b/.gitignore @@ -78,4 +78,6 @@ CMakeLists.txt.user* *.exe .vscode/c_cpp_properties.json +.vscode/settings.json build*/ +imgui.ini diff --git a/3rdparty/imgui/CMakeLists.txt b/3rdparty/imgui/CMakeLists.txt index 191f1ea..3382d72 100644 --- a/3rdparty/imgui/CMakeLists.txt +++ b/3rdparty/imgui/CMakeLists.txt @@ -1,2 +1,83 @@ -file(GLOB_RECURSE IMGUI_SOURCES ${CMAKE_CURRENT_LIST_DIR}/*.cpp) -add_library(imgui IMGUI_SOURCES) +set(IMGUI_SOURCES + imgui.h + imgui.cpp + imconfig.h + imgui_internal.h + imgui_demo.cpp + imgui_draw.cpp + imgui_tables.cpp + imgui_widgets.cpp + imstb_rectpack.h + imstb_textedit.h + imstb_truetype.h + + # Since we only use GLFW to manage windows, application can't be built without GLFW + backend/imgui_impl_glfw.h + backend/imgui_impl_glfw.cpp +) + +option(IMGUI_INCLUDE_OPENGL2_BACKEND ON) +if(IMGUI_INCLUDE_OPENGL2_BACKEND) + message("ImGui: - building with OpenGL2 backend") + list(APPEND IMGUI_SOURCES + backend/imgui_impl_opengl2.h + backend/imgui_impl_opengl2.cpp + ) +endif() + +option(IMGUI_INCLUDE_OPENGL3_BACKEND ON) +if(IMGUI_INCLUDE_OPENGL3_BACKEND) + message("ImGui: - building with OpenGL3 backend") + list(APPEND IMGUI_SOURCES + backend/imgui_impl_opengl3.h + backend/imgui_impl_opengl3.cpp + ) +endif() + +option(IMGUI_INCLUDE_VULKAN_BACKEND ON) +if(IMGUI_INCLUDE_VULKAN_BACKEND) + message("ImGui: - building with Vulkan backend") + list(APPEND IMGUI_SOURCES + backend/imgui_impl_vulkan.h + backend/imgui_impl_vulkan.cpp + ) +endif() + +if(WIN32) + option(IMGUI_INCLUDE_DX11_BACKEND ON) + if(IMGUI_INCLUDE_DX11_BACKEND) + message("ImGui: - building with DirectX11 backend") + list(APPEND IMGUI_SOURCES + backend/imgui_impl_dx11.h + backend/imgui_impl_dx11.cpp + ) + endif() + + option(IMGUI_INCLUDE_DX12_BACKEND ON) + if(IMGUI_INCLUDE_DX12_BACKEND) + message("ImGui: - building with DirectX12 backend") + list(APPEND IMGUI_SOURCES + backend/imgui_impl_dx12.h + backend/imgui_impl_dx12.cpp + ) + endif() +elseif(APPLE) + option(IMGUI_INCLUDE_METAL_BACKEND ON) + if(IMGUI_INCLUDE_METAL_BACKEND) + message("ImGui: - building with Metal backend") + list(APPEND IMGUI_SOURCES + backend/imgui_impl_metal.h + backend/imgui_impl_metal.mm + ) + endif() +endif() + +add_library(imgui ${IMGUI_SOURCES}) +target_compile_definitions(imgui +PRIVATE + IMGUI_IMPL_OPENGL_LOADER_GLAD=1 +) +target_include_directories(imgui +PRIVATE + ${CMAKE_SOURCE_DIR}/3rdparty/imgui +) diff --git a/3rdparty/imnodes/CMakeLists.txt b/3rdparty/imnodes/CMakeLists.txt index 16b007a..bb1290c 100644 --- a/3rdparty/imnodes/CMakeLists.txt +++ b/3rdparty/imnodes/CMakeLists.txt @@ -1,2 +1,10 @@ -file(GLOB_RECURSE IMNODES_SOURCES ${CMAKE_CURRENT_LIST_DIR}/*.cpp) -add_library(imnodes IMNODES_SOURCES) +set(IMNODES_SOURCES + imnodes.h + imnodes.cpp +) + +add_library(imnodes ${IMNODES_SOURCES}) +target_include_directories(imnodes PRIVATE + ${CMAKE_SOURCE_DIR}/3rdparty/imnodes + ${CMAKE_SOURCE_DIR}/3rdparty/imgui +) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b6f7ba..aeb7b0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required(VERSION 3.5) project(Cplt LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) option(FORCE_COLORED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." ON) if(FORCE_COLORED_OUTPUT) @@ -10,6 +12,8 @@ if(FORCE_COLORED_OUTPUT) endif() endif() +set(LINUX ${CMAKE_SYSTEM_NAME} MATCHES "Linux") + include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() diff --git a/conanfile.txt b/conanfile.txt index 2bf6348..4ddf420 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -1,5 +1,6 @@ [requires] argparse/2.1 +sqlite3/3.35.2 glfw/3.3.2 glad/0.1.34 doctest/2.4.4 diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index f2077a3..0eb4900 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -1,6 +1,6 @@ -project(CpltCore LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) +option(BUILD_CORE_WITH_UNITY_BUILD OFF) +option(BUILD_CORE_MAIN "Whether to compile the main executable or not." ON) +option(BUILD_CORE_TESTS "Whether to compile the tests executable or not." OFF) function(add_source_group GROUP_NAME GROUP_SOURCES) set(${GROUP_NAME} ${GROUP_SOURCES}) @@ -11,9 +11,26 @@ function(add_source_group GROUP_NAME GROUP_SOURCES) endfunction() set(ENTRYPOINT_MODULE_SOURCES + src/Entrypoint/main.cpp + src/Entrypoint/Common.hpp + src/Entrypoint/Common.cpp + src/Entrypoint/OpenGL2.hpp + src/Entrypoint/OpenGL2.cpp + src/Entrypoint/OpenGL3.hpp + src/Entrypoint/OpenGL3.cpp + src/Entrypoint/Vulkan.hpp + src/Entrypoint/Vulkan.cpp + src/Entrypoint/DirectX11.hpp + src/Entrypoint/DirectX11.cpp + src/Entrypoint/DirectX12.hpp + src/Entrypoint/DirectX12.cpp + src/Entrypoint/Metal.hpp + src/Entrypoint/Metal.mm ) add_source_group(UI_MODULE_SOURCES + src/UI/Export.hpp + src/UI/Export.cpp ) add_source_group(UTILS_MODULE_SOURCES @@ -33,6 +50,7 @@ set(UTILS_DIALOG_MODULE_SOURCES src/Utils/Dialog/Dialog.cpp ) if(APPLE) + find_library(COCOA_LIBRARY Cocoa) list(APPEND UTILS_DIALOG_MODULE_SOURCES src/Utils/Dialog/Dialog_macos.mm ) @@ -41,6 +59,8 @@ elseif(WIN32) src/Utils/Dialog/Dialog_win32.cpp ) elseif(LINUX) + find_package(PkgConfig REQUIRED) + pkg_check_modules(GTK3 REQUIRED gtk+-3.0) list(APPEND UTILS_DIALOG_MODULE_SOURCES src/Utils/Dialog/Dialog_linux.cpp ) @@ -60,14 +80,32 @@ function(add_executable_variant TARGET_NAME) ${CMAKE_SOURCE_DIR}/3rdparty/imgui ${CMAKE_SOURCE_DIR}/3rdparty/imnodes ) - target_link_libraries(${TARGET_NAME} PRIVATE ${CONAN_LIBS}) + target_link_libraries(${TARGET_NAME} + PRIVATE + ${CONAN_LIBS} + imgui + imnodes + ) target_compile_definitions(${TARGET_NAME} PRIVATE PLATFORM_WIN32=$ PLATFORM_MACOS=$ PLATFORM_LINUX=$ + IMGUI_INCLUDE_OPENGL2_BACKEND=$ + IMGUI_INCLUDE_OPENGL3_BACKEND=$ + IMGUI_INCLUDE_VULKAN_BACKEND=$ + IMGUI_INCLUDE_DX11_BACKEND=$ + IMGUI_INCLUDE_DX12_BACKEND=$ + IMGUI_INCLUDE_METAL_BACKEND=$ ) + if(APPLE) + target_link_libraries(${TARGET_NAME} PUBLIC ${COCOA_LIBRARY}) + elseif(LINUX) + target_link_libraries(${TARGET_NAME} PUBLIC ${GTK3_LIBRARIES}) + target_include_directories(${TARGET_NAME} PRIVATE ${GTK3_INCLUDE_DIRS}) + endif() + # No console window when targetting windows if(WIN32) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") @@ -81,11 +119,11 @@ function(add_executable_variant TARGET_NAME) endif() endif() - if(${CMAKE_UNITY_BUILD}) + if(BUILD_CORE_WITH_UNITY_BUILD) message("CpltCore: - using unity build") set_target_properties(${TARGET_NAME} PROPERTIES - # UNITY_BUILD property is automatically set when CMAKE_UNITY_BUILD is set + UNITY_BUILD ON UNITY_BUILD_MODE GROUP ) else() @@ -93,7 +131,11 @@ function(add_executable_variant TARGET_NAME) endif() endfunction() -add_executable_variant(CpltCore_main) -target_compile_definitions(CpltCore_main PRIVATE DOCTEST_CONFIG_DISABLE=1) +if(BUILD_CORE_MAIN) + add_executable_variant(CpltCore_main) + target_compile_definitions(CpltCore_main PRIVATE DOCTEST_CONFIG_DISABLE=1) +endif() -add_executable_variant(CpltCore_test) +if(BUILD_CORE_TESTS) + add_executable_variant(CpltCore_test) +endif() diff --git a/core/fonts/NotoSansSC-LICENSE.txt b/core/fonts/NotoSansSC-LICENSE.txt new file mode 100644 index 0000000..075d1ae --- /dev/null +++ b/core/fonts/NotoSansSC-LICENSE.txt @@ -0,0 +1,91 @@ +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/core/fonts/NotoSansSC-Regular.otf b/core/fonts/NotoSansSC-Regular.otf new file mode 100644 index 0000000..fdb0506 Binary files /dev/null and b/core/fonts/NotoSansSC-Regular.otf differ diff --git a/core/src/Entrypoint/Common.cpp b/core/src/Entrypoint/Common.cpp new file mode 100644 index 0000000..62baf9d --- /dev/null +++ b/core/src/Entrypoint/Common.cpp @@ -0,0 +1,11 @@ +#include "Common.hpp" + +#include + +GLFWwindow* RenderingBackend::GetWindow() const { + return mWindow; +} + +void RenderingBackend::GlfwErrorCallback(int error, const char* message) { + std::cerr << "GLFW Error " << error << ": " << message << "\n"; +} diff --git a/core/src/Entrypoint/Common.hpp b/core/src/Entrypoint/Common.hpp new file mode 100644 index 0000000..2a4dcbf --- /dev/null +++ b/core/src/Entrypoint/Common.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include + +#include + +class RenderingBackend { +protected: + GLFWwindow* mWindow; + +public: + virtual ~RenderingBackend() = default; + virtual void BeginFrame() = 0; + virtual void EndFrame() = 0; + + GLFWwindow* GetWindow() const; + + /// Common GLFW error handle callback for each rendering backend to use. + static void GlfwErrorCallback(int error, const char* message); +}; diff --git a/core/src/Entrypoint/DirectX11.cpp b/core/src/Entrypoint/DirectX11.cpp new file mode 100644 index 0000000..617447c --- /dev/null +++ b/core/src/Entrypoint/DirectX11.cpp @@ -0,0 +1,13 @@ +#include "DirectX11.hpp" + +DirectX11Backend::DirectX11Backend() { + // TODO +} + +void DirectX11Backend::BeginFrame() { + // TODO +} + +void DirectX11Backend::EndFrame() { + // TODO +} diff --git a/core/src/Entrypoint/DirectX11.hpp b/core/src/Entrypoint/DirectX11.hpp new file mode 100644 index 0000000..134a20f --- /dev/null +++ b/core/src/Entrypoint/DirectX11.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "Entrypoint/Common.hpp" + +class DirectX11Backend : public RenderingBackend { +public: + DirectX11Backend(); + virtual ~DirectX11Backend() = default; + virtual void BeginFrame() override; + virtual void EndFrame() override; +}; diff --git a/core/src/Entrypoint/DirectX12.cpp b/core/src/Entrypoint/DirectX12.cpp new file mode 100644 index 0000000..1769d24 --- /dev/null +++ b/core/src/Entrypoint/DirectX12.cpp @@ -0,0 +1,13 @@ +#include "DirectX12.hpp" + +DirectX12Backend::DirectX12Backend() { + // TODO +} + +void DirectX12Backend::BeginFrame() { + // TODO +} + +void DirectX12Backend::EndFrame() { + // TODO +} diff --git a/core/src/Entrypoint/DirectX12.hpp b/core/src/Entrypoint/DirectX12.hpp new file mode 100644 index 0000000..8b9a4f0 --- /dev/null +++ b/core/src/Entrypoint/DirectX12.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "Entrypoint/Common.hpp" + +class DirectX12Backend : public RenderingBackend { +public: + DirectX12Backend(); + virtual ~DirectX12Backend() = default; + virtual void BeginFrame() override; + virtual void EndFrame() override; +}; diff --git a/core/src/Entrypoint/Metal.hpp b/core/src/Entrypoint/Metal.hpp new file mode 100644 index 0000000..cd96d0f --- /dev/null +++ b/core/src/Entrypoint/Metal.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "Entrypoint/Common.hpp" + +class MetalBackend : public RenderingBackend { +public: + MetalBackend(); + virtual ~MetalBackend() = default; + virtual void BeginFrame() override; + virtual void EndFrame() override; +}; diff --git a/core/src/Entrypoint/Metal.mm b/core/src/Entrypoint/Metal.mm new file mode 100644 index 0000000..3f69634 --- /dev/null +++ b/core/src/Entrypoint/Metal.mm @@ -0,0 +1,13 @@ +#include "Metal.hpp" + +MetalBackend::MetalBackend() { + // TODO +} + +void MetalBackend::BeginFrame() { + // TODO +} + +void MetalBackend::EndFrame() { + // TODO +} diff --git a/core/src/Entrypoint/OpenGL2.cpp b/core/src/Entrypoint/OpenGL2.cpp new file mode 100644 index 0000000..de13a02 --- /dev/null +++ b/core/src/Entrypoint/OpenGL2.cpp @@ -0,0 +1,70 @@ +#include "OpenGL2.hpp" + +#include + +#include +#include +#include +#include +#include + +OpenGL2Backend::OpenGL2Backend() { +#if IMGUI_INCLUDE_OPENGL2_BACKEND + glfwSetErrorCallback(GlfwErrorCallback); + if (!glfwInit()) { + throw std::runtime_error("Failed to initialize GLFW."); + } + + mWindow = glfwCreateWindow(1280, 720, "Cplt", nullptr, nullptr); + if (mWindow == nullptr) { + throw std::runtime_error("Failed to create GLFW window."); + } + glfwMakeContextCurrent(mWindow); + glfwSwapInterval(1); // Enable vsync + + if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) == 0) { + throw std::runtime_error("Failed to initialize OpenGL."); + } + + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + + ImGui_ImplGlfw_InitForOpenGL(mWindow, true); + ImGui_ImplOpenGL2_Init(); +#else + throw std::runtime_error("Backend opengl2 is not available in this build.\n"); +#endif +} + +OpenGL2Backend::~OpenGL2Backend() { + ImGui_ImplOpenGL2_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + glfwDestroyWindow(mWindow); + glfwTerminate(); +} + +void OpenGL2Backend::BeginFrame() { + glfwPollEvents(); + + ImGui_ImplOpenGL2_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); +} + +void OpenGL2Backend::EndFrame() { + int displayWidth, displayHeight; + glfwGetFramebufferSize(mWindow, &displayWidth, &displayHeight); + glViewport(0, 0, displayWidth, displayHeight); + + const ImVec4 kClearColor = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + glClearColor(kClearColor.x * kClearColor.w, kClearColor.y * kClearColor.w, kClearColor.z * kClearColor.w, kClearColor.w); + glClear(GL_COLOR_BUFFER_BIT); + + ImGui::Render(); + ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); + + glfwMakeContextCurrent(mWindow); + glfwSwapBuffers(mWindow); +} diff --git a/core/src/Entrypoint/OpenGL2.hpp b/core/src/Entrypoint/OpenGL2.hpp new file mode 100644 index 0000000..86fbad7 --- /dev/null +++ b/core/src/Entrypoint/OpenGL2.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "Entrypoint/Common.hpp" + +#include + +#include + +class OpenGL2Backend : public RenderingBackend { +public: + OpenGL2Backend(); + virtual ~OpenGL2Backend(); + virtual void BeginFrame() override; + virtual void EndFrame() override; +}; diff --git a/core/src/Entrypoint/OpenGL3.cpp b/core/src/Entrypoint/OpenGL3.cpp new file mode 100644 index 0000000..c1f66d5 --- /dev/null +++ b/core/src/Entrypoint/OpenGL3.cpp @@ -0,0 +1,85 @@ +#include "OpenGL3.hpp" + +#include + +#include +#include +#include +#include +#include + +OpenGL3Backend::OpenGL3Backend() { +#if IMGUI_INCLUDE_OPENGL3_BACKEND + glfwSetErrorCallback(GlfwErrorCallback); + if (!glfwInit()) { + throw std::runtime_error("Failed to initialize GLFW."); + } + +# if PLATFORM_APPLE + // GL 3.2 + GLSL 150 + const char* glslVersion = "#version 150"; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac +# else + // GL 3.0 + GLSL 130 + const char* glslVersion = "#version 130"; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only + //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only +# endif + + mWindow = glfwCreateWindow(1280, 720, "Cplt", nullptr, nullptr); + if (mWindow == nullptr) { + throw std::runtime_error("Failed to create GLFW window."); + } + glfwMakeContextCurrent(mWindow); + glfwSwapInterval(1); // Enable vsync + + if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) == 0) { + throw std::runtime_error("Failed to initialize OpenGL."); + } + + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + + ImGui_ImplGlfw_InitForOpenGL(mWindow, true); + ImGui_ImplOpenGL3_Init(glslVersion); +#else + throw std::runtime_error("Backend opengl3 is not available in this build.\n"); +#endif +} + +OpenGL3Backend::~OpenGL3Backend() { + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + glfwDestroyWindow(mWindow); + glfwTerminate(); +} + +void OpenGL3Backend::BeginFrame() { + glfwPollEvents(); + + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); +} + +void OpenGL3Backend::EndFrame() { + int displayWidth, displayHeight; + glfwGetFramebufferSize(mWindow, &displayWidth, &displayHeight); + glViewport(0, 0, displayWidth, displayHeight); + + const ImVec4 kClearColor = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + glClearColor(kClearColor.x * kClearColor.w, kClearColor.y * kClearColor.w, kClearColor.z * kClearColor.w, kClearColor.w); + glClear(GL_COLOR_BUFFER_BIT); + + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + glfwSwapBuffers(mWindow); +} diff --git a/core/src/Entrypoint/OpenGL3.hpp b/core/src/Entrypoint/OpenGL3.hpp new file mode 100644 index 0000000..29086a2 --- /dev/null +++ b/core/src/Entrypoint/OpenGL3.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "Entrypoint/Common.hpp" + +#include + +#include + +class OpenGL3Backend : public RenderingBackend { +public: + OpenGL3Backend(); + virtual ~OpenGL3Backend() ; + virtual void BeginFrame() override; + virtual void EndFrame() override; +}; diff --git a/core/src/Entrypoint/Vulkan.cpp b/core/src/Entrypoint/Vulkan.cpp new file mode 100644 index 0000000..5af1772 --- /dev/null +++ b/core/src/Entrypoint/Vulkan.cpp @@ -0,0 +1,13 @@ +#include "Vulkan.hpp" + +VulkanBackend::VulkanBackend() { + // TODO +} + +void VulkanBackend::BeginFrame() { + // TODO +} + +void VulkanBackend::EndFrame() { + // TODO +} diff --git a/core/src/Entrypoint/Vulkan.hpp b/core/src/Entrypoint/Vulkan.hpp new file mode 100644 index 0000000..6404806 --- /dev/null +++ b/core/src/Entrypoint/Vulkan.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "Entrypoint/Common.hpp" + +class VulkanBackend : public RenderingBackend { +public: + VulkanBackend(); + virtual ~VulkanBackend() = default; + virtual void BeginFrame() override; + virtual void EndFrame() override; +}; diff --git a/core/src/Entrypoint/main.cpp b/core/src/Entrypoint/main.cpp new file mode 100644 index 0000000..3adf757 --- /dev/null +++ b/core/src/Entrypoint/main.cpp @@ -0,0 +1,91 @@ +#include "Entrypoint/Common.hpp" +#include "Entrypoint/DirectX11.hpp" +#include "Entrypoint/DirectX12.hpp" +#include "Entrypoint/Metal.hpp" +#include "Entrypoint/OpenGL2.hpp" +#include "Entrypoint/OpenGL3.hpp" +#include "Entrypoint/Vulkan.hpp" + +#include + +#include +#include +#include +#include +#include +#include + +using namespace std::literals::string_literals; + +int main(int argc, char* argv[]) { + argparse::ArgumentParser parser; + 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; + } + + std::unique_ptr backend; + auto backendOption = parser.get("--rendering-backend"); + if (backendOption == "default") { + // TODO better api selection mechanism, use lower tier if higher tier is unavilable instead of bailing +#if PLATFORM_WIN32 +# if IMGUI_INCLUDE_DX12_BACKEND + backend = std::make_unique(); +# elif IMGUI_INCLUDE_DX11_BACKEND + backend = std::make_unique(); +# elif IMGUI_INCLUDE_VULKAN_BACKEND + backend = std::make_unique(); +# elif IMGUI_INCLUDE_OPENGL3_BACKEND + backend = std::make_unique(); +# elif IMGUI_INCLUDE_OPENGL2_BACKEND + backend = std::make_unique(); +# endif +#elif PLATFORM_MACOS + backend = std::make_unique(); +#elif PLATFORM_LINUX +# if IMGUI_INCLUDE_VULKAN_BACKEND + backend = std::make_unique(); +// # elif IMGUI_INCLUDE_OPENGL3_BACKEND +// backend = std::make_unique(); +# elif IMGUI_INCLUDE_OPENGL2_BACKEND + backend = std::make_unique(); +# endif +#endif + } else if (backendOption == "opengl2") { + backend = std::make_unique(); + } else if (backendOption == "opengl3") { + backend = std::make_unique(); + } else if (backendOption == "vulkan") { + backend = std::make_unique(); + } else if (backendOption == "dx11") { + backend = std::make_unique(); + } else if (backendOption == "dx12") { + backend = std::make_unique(); + } else if (backendOption == "metal") { + backend = std::make_unique(); + } else { + std::cout << "Unknown backend '" << backendOption << "'.\n"; + return -1; + } + + auto& io = ImGui::GetIO(); + io.Fonts->AddFontFromFileTTF("fonts/NotoSansSC-Regular.otf", 18, nullptr, io.Fonts->GetGlyphRangesChineseSimplifiedCommon()); + + auto window = backend->GetWindow(); + bool showDemo = true; + while (!glfwWindowShouldClose(window)) { + backend->BeginFrame(); + if (showDemo) + ImGui::ShowDemoWindow(&showDemo); + backend->EndFrame(); + } + + return 0; +} diff --git a/core/src/UI/Export.cpp b/core/src/UI/Export.cpp new file mode 100644 index 0000000..d6b26dc --- /dev/null +++ b/core/src/UI/Export.cpp @@ -0,0 +1 @@ +#include "Export.hpp" diff --git a/core/src/UI/Export.hpp b/core/src/UI/Export.hpp new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/core/src/UI/Export.hpp @@ -0,0 +1 @@ +#pragma once -- cgit v1.2.3-70-g09d2