diff options
author | rtk0c <[email protected]> | 2021-03-28 13:24:52 -0700 |
---|---|---|
committer | rtk0c <[email protected]> | 2021-03-28 13:24:52 -0700 |
commit | bdcc81822adddf2c6ad7f10d9e090d913475c1e0 (patch) | |
tree | 91997b21958992f4e9e48839166ea4feaa0712b1 | |
parent | 442d2d75d71bbc057e667edc301a79fa1cc813be (diff) |
Initial code structure
25 files changed, 647 insertions, 13 deletions
@@ -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=$<BOOL:${WIN32}> PLATFORM_MACOS=$<BOOL:${APPLE}> PLATFORM_LINUX=$<BOOL:${LINUX}> + IMGUI_INCLUDE_OPENGL2_BACKEND=$<BOOL:${IMGUI_INCLUDE_OPENGL2_BACKEND}> + IMGUI_INCLUDE_OPENGL3_BACKEND=$<BOOL:${IMGUI_INCLUDE_OPENGL3_BACKEND}> + IMGUI_INCLUDE_VULKAN_BACKEND=$<BOOL:${IMGUI_INCLUDE_VULKAN_BACKEND}> + IMGUI_INCLUDE_DX11_BACKEND=$<BOOL:${IMGUI_INCLUDE_DX11_BACKEND}> + IMGUI_INCLUDE_DX12_BACKEND=$<BOOL:${IMGUI_INCLUDE_DX12_BACKEND}> + IMGUI_INCLUDE_METAL_BACKEND=$<BOOL:${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 Binary files differnew file mode 100644 index 0000000..fdb0506 --- /dev/null +++ b/core/fonts/NotoSansSC-Regular.otf 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 <iostream> + +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 <glad/glad.h> + +#include <GLFW/glfw3.h> + +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 <glad/glad.h> + +#include <GLFW/glfw3.h> +#include <backend/imgui_impl_glfw.h> +#include <backend/imgui_impl_opengl2.h> +#include <imgui.h> +#include <stdexcept> + +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 <glad/glad.h> + +#include <GLFW/glfw3.h> + +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 <glad/glad.h> + +#include <GLFW/glfw3.h> +#include <backend/imgui_impl_glfw.h> +#include <backend/imgui_impl_opengl3.h> +#include <imgui.h> +#include <stdexcept> + +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 <glad/glad.h> + +#include <GLFW/glfw3.h> + +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 <glad/glad.h> + +#include <GLFW/glfw3.h> +#include <imgui.h> +#include <argparse/argparse.hpp> +#include <iostream> +#include <memory> +#include <string> + +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<RenderingBackend> backend; + auto backendOption = parser.get<std::string>("--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<DirectX12Backend>(); +# elif IMGUI_INCLUDE_DX11_BACKEND + backend = std::make_unique<DirectX11Backend>(); +# elif IMGUI_INCLUDE_VULKAN_BACKEND + backend = std::make_unique<VulkanBackend>(); +# elif IMGUI_INCLUDE_OPENGL3_BACKEND + backend = std::make_unique<OpenGL3Backend>(); +# elif IMGUI_INCLUDE_OPENGL2_BACKEND + backend = std::make_unique<OpenGL2Backend>(); +# endif +#elif PLATFORM_MACOS + backend = std::make_unique<MetalBackend>(); +#elif PLATFORM_LINUX +# if IMGUI_INCLUDE_VULKAN_BACKEND + backend = std::make_unique<VulkanBackend>(); +// # elif IMGUI_INCLUDE_OPENGL3_BACKEND +// backend = std::make_unique<OpenGL3Backend>(); +# elif IMGUI_INCLUDE_OPENGL2_BACKEND + backend = std::make_unique<OpenGL2Backend>(); +# endif +#endif + } else if (backendOption == "opengl2") { + backend = std::make_unique<OpenGL2Backend>(); + } else if (backendOption == "opengl3") { + backend = std::make_unique<OpenGL3Backend>(); + } else if (backendOption == "vulkan") { + backend = std::make_unique<VulkanBackend>(); + } else if (backendOption == "dx11") { + backend = std::make_unique<DirectX11Backend>(); + } else if (backendOption == "dx12") { + backend = std::make_unique<DirectX12Backend>(); + } else if (backendOption == "metal") { + backend = std::make_unique<MetalBackend>(); + } 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 |