commit 3a0593c3ff7a91114e82d25cc664a16e0be4b4fb Author: Nanako <469449812@qq.com> Date: Tue Oct 15 10:11:53 2024 +0800 init diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4678e49 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.10) +project(aorii) + +include(cmake/retrieve_files.cmake) + +find_package(Eigen3 REQUIRED) +find_package(spdlog REQUIRED) + +# 如果是Debug模式, 添加宏定义 +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + add_definitions(-DDEBUG=1) +endif() + +add_subdirectory(src/renderer) +add_subdirectory(src/widget) diff --git a/cmake/retrieve_files.cmake b/cmake/retrieve_files.cmake new file mode 100644 index 0000000..756d614 --- /dev/null +++ b/cmake/retrieve_files.cmake @@ -0,0 +1,61 @@ + +function(retrieve_files_custom path extension out_files) + message(STATUS "Retrieving files in ${path}") + set(EXTENSIONS "") + foreach(ext ${extension}) + list(APPEND EXTENSIONS "${path}/*.${ext}") + endforeach () + + # 递归查找文件夹下的 .h .hpp. ini 文件保存到 HEAD_FILES + file(GLOB_RECURSE FIND_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} CONFIGURE_DEPENDS ${EXTENSIONS}) + # 将 HEDADER_FILES 和 SRC_FILES 保存到 ALL_FILES 变量 + set(ALL_FILES ${FIND_FILES}) + + set(RESULT "") + + # 对 ALL_FILES 变量里面的所有文件分类(保留资源管理器的目录结构) + foreach(fileItem ${ALL_FILES}) + # Get the directory of the source file + get_filename_component(PARENT_DIR "${fileItem}" DIRECTORY) + + # 用于检查平台的条件 + if(PARENT_DIR STREQUAL "windows") + if(WIN32) + set(RESULT "${RESULT};${fileItem}") + else() + continue() + endif() + elseif(PARENT_DIR STREQUAL "linux") + if(UNIX AND NOT APPLE) + set(RESULT "${RESULT};${fileItem}") + else() + continue() + endif() + elseif(PARENT_DIR STREQUAL "mac") + if(APPLE) + set(RESULT "${RESULT};${fileItem}") + else() + continue() + endif() + else() + # 如果文件夹名称不是平台,则始终包含 + set(RESULT "${RESULT};${fileItem}") + endif() + + # Remove common directory prefix to make the group + string(REPLACE "${path}" "" GROUP "${PARENT_DIR}") + # Make sure we are using windows slashes + string(REPLACE "/" "\\" GROUP "${GROUP}") + # Group into "Source Files" and "Header Files" + set(GROUP "${GROUP}") + source_group("${GROUP}" FILES "${fileItem}") + endforeach() + + set(${out_files} ${RESULT} PARENT_SCOPE) +endfunction() + +function(retrieve_files path out_files) + set(temp_files "") + retrieve_files_custom(${path} "h;hpp;ini;cpp;c;ixx" temp_files) + set(${out_files} ${${out_files}} ${temp_files} PARENT_SCOPE) +endfunction() diff --git a/src/renderer/CMakeLists.txt b/src/renderer/CMakeLists.txt new file mode 100644 index 0000000..36c9a57 --- /dev/null +++ b/src/renderer/CMakeLists.txt @@ -0,0 +1,39 @@ +project(renderer) + +set(GL_BACKEND FALSE CACHE BOOL "OpenGL backend to use") +set(DX_BACKEND FALSE CACHE BOOL "DirectX backend to use") +set(VK_BACKEND FALSE CACHE BOOL "Vulkan backend to use") + +if (NOT GL_BACKEND AND NOT DX_BACKEND AND NOT VK_BACKEND) + message(FATAL_ERROR "No backend selected") +endif() + +set(RENDERER_SOURCES + renderer.cpp + renderer.h + renderer_buffer.cpp + renderer_buffer.h + renderer_texture.cpp + renderer_texture.h +) + +if (GL_BACKEND) + retrieve_files(backend/gl RENDERER_SOURCES) + add_definitions(-DGL_BACKEND=1) +endif() +if (DX_BACKEND) + retrieve_files(backend/dx RENDERER_SOURCES) + add_definitions(-DDX_BACKEND=1) +endif () +if (VK_BACKEND) + retrieve_files(backend/vk RENDERER_SOURCES) + add_definitions(-DVK_BACKEND=1) +endif () + +add_library(${PROJECT_NAME} STATIC ${RENDERER_SOURCES}) +target_link_libraries(${PROJECT_NAME} Eigen3::Eigen spdlog::spdlog) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +if (DX_BACKEND) + target_link_libraries(${PROJECT_NAME} d3d11 d3dcompiler dxgi) +endif () diff --git a/src/renderer/backend/dx/dx_backend.cpp b/src/renderer/backend/dx/dx_backend.cpp new file mode 100644 index 0000000..90559f9 --- /dev/null +++ b/src/renderer/backend/dx/dx_backend.cpp @@ -0,0 +1,51 @@ +#include "dx_backend.h" + +#include "dx_texture.h" +#include "spdlog/spdlog.h" + +std::shared_ptr dx_backend::create_texture(const Eigen::Vector2i& size) { + D3D11_TEXTURE2D_DESC desc = {}; + desc.Width = size.x(); + desc.Height = size.y(); + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + + ID3D11Texture2D* texture = nullptr; + if (FAILED(device->CreateTexture2D(&desc, nullptr, &texture))) { + return nullptr; + } + + return std::make_shared(texture); +} + +void dx_backend::destroy_texture(renderer_texture* texture) { +#ifdef DEBUG + spdlog::info("Destroying texture"); +#endif +} + +bool dx_backend::init() { + if (!create_device()) + return false; + if (!create_context()) + return false; + return true; +} + +bool dx_backend::create_device() { + D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1 }; + const auto result = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, featureLevels, 2, D3D11_SDK_VERSION, &device, nullptr, nullptr); + return SUCCEEDED(result); +} + +bool dx_backend::create_context() { + device->GetImmediateContext(&context); + return true; +} diff --git a/src/renderer/backend/dx/dx_backend.h b/src/renderer/backend/dx/dx_backend.h new file mode 100644 index 0000000..8c6887f --- /dev/null +++ b/src/renderer/backend/dx/dx_backend.h @@ -0,0 +1,22 @@ +#pragma once +#include "renderer.h" +#include + +class dx_backend : public renderer { + inline static dx_backend* instance = nullptr; +public: + static dx_backend* get_instance() { + return static_cast(aorii::s_renderer); + } + bool init() override; + + std::shared_ptr create_texture(const Eigen::Vector2i& size) override; + void destroy_texture(renderer_texture* texture) override; +private: + bool create_device(); + bool create_context(); + + ID3D11Device* device = nullptr; + ID3D11DeviceContext* context = nullptr; +}; + diff --git a/src/renderer/backend/dx/dx_texture.cpp b/src/renderer/backend/dx/dx_texture.cpp new file mode 100644 index 0000000..dd3173f --- /dev/null +++ b/src/renderer/backend/dx/dx_texture.cpp @@ -0,0 +1,44 @@ +#include "dx_texture.h" + +#include "dx_backend.h" + +dx_texture::dx_texture(ID3D11Texture2D* texture) { + m_texture = texture; +} + +dx_texture::~dx_texture() { + // 如果是Debug模式, 检查m_data是否被释放 +#if defined(DEBUG) + assert(!m_data); +#endif + free(m_data); +} + +void* dx_texture::lock() { + D3D11_TEXTURE2D_DESC desc; + m_texture->GetDesc(&desc); + m_data = new char[desc.Width * desc.Height * 4]; + return m_data; +} + +void dx_texture::unlock() { + D3D11_TEXTURE2D_DESC desc; + m_texture->GetDesc(&desc); + D3D11_MAPPED_SUBRESOURCE mappedResource; + auto context = dx_backend::get_instance(); + context->Map(m_texture.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + memcpy(mappedResource.pData, m_data, desc.Width * desc.Height * 4); + context->Unmap(m_texture.get(), 0); + delete[] m_data; + m_data = nullptr; +} + +bool dx_texture::resize(const Eigen::Vector2i& size) { + return true; +} + +Eigen::Vector2i dx_texture::size() { + D3D11_TEXTURE2D_DESC desc; + m_texture->GetDesc(&desc); + return { desc.Width, desc.Height }; +} diff --git a/src/renderer/backend/dx/dx_texture.h b/src/renderer/backend/dx/dx_texture.h new file mode 100644 index 0000000..ec26d23 --- /dev/null +++ b/src/renderer/backend/dx/dx_texture.h @@ -0,0 +1,19 @@ +#pragma once +#include "renderer_texture.h" +#include +#include + +// DX11纹理 +class dx_texture : public renderer_texture { +public: + explicit dx_texture(ID3D11Texture2D* texture); + ~dx_texture() override; + void* lock() override; + void unlock() override; + + bool resize(const Eigen::Vector2i& size) override; + Eigen::Vector2i size() override; +private: + void* m_data = nullptr; + ID3D11Texture2D* m_texture; +}; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp new file mode 100644 index 0000000..6f2c98e --- /dev/null +++ b/src/renderer/renderer.cpp @@ -0,0 +1,29 @@ +#include "renderer.h" + +#ifdef DX_BACKEND +#include "backend/dx/dx_backend.h" +#endif + +bool aorii::create_renderer(renderer_api api) { + if (s_renderer) + return true; + switch (api) { +#ifdef DX_BACKEND + case renderer_api::dx11: + s_renderer = new dx_backend(); + break; +#endif +#ifdef GL_BACKEND + case renderer_api::opengl: + break; +#endif +#ifdef VK_BACKEND + case renderer_api::vulkan: + break; +#endif + default: + assert(false); + break; + } + return s_renderer->init(); +} diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h new file mode 100644 index 0000000..ef6e304 --- /dev/null +++ b/src/renderer/renderer.h @@ -0,0 +1,26 @@ +#pragma once +#include +#include + +class renderer_texture; + +enum class renderer_api { + dx11, + opengl, + vulkan, +}; + +class renderer { +public: + virtual ~renderer() = default; + + virtual std::shared_ptr create_texture(const Eigen::Vector2i& size) = 0; + virtual void destroy_texture(renderer_texture* texture) = 0; + + virtual bool init() = 0; +}; + +namespace aorii { + inline static renderer* s_renderer = nullptr; + bool create_renderer(renderer_api api); +} diff --git a/src/renderer/renderer_buffer.cpp b/src/renderer/renderer_buffer.cpp new file mode 100644 index 0000000..c70f4d9 --- /dev/null +++ b/src/renderer/renderer_buffer.cpp @@ -0,0 +1 @@ +#include "renderer_buffer.h" diff --git a/src/renderer/renderer_buffer.h b/src/renderer/renderer_buffer.h new file mode 100644 index 0000000..4d7ccc0 --- /dev/null +++ b/src/renderer/renderer_buffer.h @@ -0,0 +1,5 @@ +#pragma once + +class renderer_buffer { + +}; diff --git a/src/renderer/renderer_texture.cpp b/src/renderer/renderer_texture.cpp new file mode 100644 index 0000000..a80fe0a --- /dev/null +++ b/src/renderer/renderer_texture.cpp @@ -0,0 +1 @@ +#include "renderer_texture.h" diff --git a/src/renderer/renderer_texture.h b/src/renderer/renderer_texture.h new file mode 100644 index 0000000..eb37a69 --- /dev/null +++ b/src/renderer/renderer_texture.h @@ -0,0 +1,14 @@ +#pragma once +#include + +class renderer_texture { +public: + virtual ~renderer_texture() = default; + + + virtual void* lock() = 0; + virtual void unlock() = 0; + + virtual bool resize(const Eigen::Vector2i& size) = 0; + virtual Eigen::Vector2i size() = 0; +}; diff --git a/src/widget/CMakeLists.txt b/src/widget/CMakeLists.txt new file mode 100644 index 0000000..e69de29