DX11后端框架
This commit is contained in:
parent
3a0593c3ff
commit
8c26893b66
@ -2,14 +2,25 @@ cmake_minimum_required(VERSION 3.10)
|
|||||||
project(aorii)
|
project(aorii)
|
||||||
|
|
||||||
include(cmake/retrieve_files.cmake)
|
include(cmake/retrieve_files.cmake)
|
||||||
|
include(cmake/detect_os.cmake)
|
||||||
|
include(cmake/configure_glfw_native.cmake)
|
||||||
|
|
||||||
find_package(Eigen3 REQUIRED)
|
find_package(Eigen3 REQUIRED)
|
||||||
find_package(spdlog REQUIRED)
|
find_package(spdlog REQUIRED)
|
||||||
|
find_package(glfw3 REQUIRED)
|
||||||
|
|
||||||
# 如果是Debug模式, 添加宏定义
|
# 如果是Debug模式, 添加宏定义
|
||||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
add_definitions(-DDEBUG=1)
|
add_definitions(-DDEBUG=1)
|
||||||
endif()
|
else ()
|
||||||
|
add_definitions(-DDEBUG=0)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_subdirectory(src/core)
|
||||||
add_subdirectory(src/renderer)
|
add_subdirectory(src/renderer)
|
||||||
add_subdirectory(src/widget)
|
add_subdirectory(src/widget)
|
||||||
|
|
||||||
|
set(BUILD_EXAMPLE FALSE CACHE BOOL "Build example")
|
||||||
|
if (BUILD_EXAMPLE)
|
||||||
|
add_subdirectory(example)
|
||||||
|
endif ()
|
||||||
|
39
cmake/configure_glfw_native.cmake
Normal file
39
cmake/configure_glfw_native.cmake
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
function(configure_glfw_native target)
|
||||||
|
# 检测操作系统
|
||||||
|
if(WIN32)
|
||||||
|
target_compile_definitions(${target} PRIVATE GLFW_EXPOSE_NATIVE_WIN32)
|
||||||
|
message(STATUS "Exposing GLFW native Win32 API")
|
||||||
|
elseif(APPLE)
|
||||||
|
target_compile_definitions(${target} PRIVATE GLFW_EXPOSE_NATIVE_COCOA)
|
||||||
|
message(STATUS "Exposing GLFW native Cocoa API")
|
||||||
|
elseif(UNIX)
|
||||||
|
# 对于 Unix-like 系统,我们需要进一步检测
|
||||||
|
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
# 检测 Wayland
|
||||||
|
find_package(Wayland)
|
||||||
|
if(Wayland_FOUND)
|
||||||
|
target_compile_definitions(${target} PRIVATE GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||||
|
message(STATUS "Exposing GLFW native Wayland API")
|
||||||
|
else()
|
||||||
|
# 如果没有 Wayland,默认使用 X11
|
||||||
|
target_compile_definitions(${target} PRIVATE GLFW_EXPOSE_NATIVE_X11)
|
||||||
|
message(STATUS "Exposing GLFW native X11 API")
|
||||||
|
endif()
|
||||||
|
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|OpenBSD|NetBSD")
|
||||||
|
# BSD 系统通常使用 X11
|
||||||
|
target_compile_definitions(${target} PRIVATE GLFW_EXPOSE_NATIVE_X11)
|
||||||
|
message(STATUS "Exposing GLFW native X11 API for BSD")
|
||||||
|
else()
|
||||||
|
message(WARNING "Unknown Unix-like system, GLFW native API might not be properly exposed")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(WARNING "Unknown operating system, GLFW native API might not be properly exposed")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 对于 EGL 支持,你可能需要额外的检测
|
||||||
|
# 这里我们简单地为所有非 Windows 和非 macOS 系统启用它
|
||||||
|
if(NOT WIN32 AND NOT APPLE)
|
||||||
|
target_compile_definitions(${target} PRIVATE GLFW_EXPOSE_NATIVE_EGL)
|
||||||
|
message(STATUS "Exposing GLFW native EGL API")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
58
cmake/detect_os.cmake
Normal file
58
cmake/detect_os.cmake
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# DetectOS.cmake
|
||||||
|
|
||||||
|
function(add_os_definitions target)
|
||||||
|
# 初始化所有平台宏为 0
|
||||||
|
set(PLATFORMS WINDOWS MACOS LINUX FREEBSD)
|
||||||
|
|
||||||
|
# 检测操作系统并设置相应的宏为 1
|
||||||
|
if(WIN32)
|
||||||
|
target_compile_definitions(${target} PRIVATE WINDOWS=1)
|
||||||
|
message(STATUS "Detected Windows operating system")
|
||||||
|
list(REMOVE_ITEM PLATFORMS WINDOWS)
|
||||||
|
elseif(APPLE)
|
||||||
|
target_compile_definitions(${target} PRIVATE MACOS=1)
|
||||||
|
message(STATUS "Detected macOS operating system")
|
||||||
|
list(REMOVE_ITEM PLATFORMS MACOS)
|
||||||
|
elseif(UNIX)
|
||||||
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||||
|
target_compile_definitions(${target} PRIVATE LINUX=1)
|
||||||
|
message(STATUS "Detected Linux operating system")
|
||||||
|
list(REMOVE_ITEM PLATFORMS LINUX)
|
||||||
|
elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||||
|
target_compile_definitions(${target} PRIVATE FREEBSD=1)
|
||||||
|
message(STATUS "Detected FreeBSD operating system")
|
||||||
|
list(REMOVE_ITEM PLATFORMS FREEBSD)
|
||||||
|
else()
|
||||||
|
message(WARNING "Detected unknown Unix-like operating system")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(WARNING "Unknown operating system")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
foreach(PLATFORM ${PLATFORMS})
|
||||||
|
target_compile_definitions(${target} PRIVATE ${PLATFORM}=0)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# 检测并设置架构宏
|
||||||
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
target_compile_definitions(${target} PRIVATE ARCH_64BIT=1 ARCH_32BIT=0)
|
||||||
|
message(STATUS "Detected 64-bit architecture")
|
||||||
|
else()
|
||||||
|
target_compile_definitions(${target} PRIVATE ARCH_64BIT=0 ARCH_32BIT=1)
|
||||||
|
message(STATUS "Detected 32-bit architecture")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 设置通用的 UNIX 宏
|
||||||
|
if(UNIX)
|
||||||
|
target_compile_definitions(${target} PRIVATE UNIX=1)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(${target} PRIVATE UNIX=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 设置通用的 POSIX 宏
|
||||||
|
if(UNIX OR APPLE)
|
||||||
|
target_compile_definitions(${target} PRIVATE POSIX=1)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(${target} PRIVATE POSIX=0)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
8
example/CMakeLists.txt
Normal file
8
example/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
project(aorii_example)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
set(SRC_FILES "")
|
||||||
|
retrieve_files(src SRC_FILES)
|
||||||
|
add_executable(${PROJECT_NAME} ${SRC_FILES})
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE renderer)
|
21
example/src/main.cpp
Normal file
21
example/src/main.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include "core/renderer.h"
|
||||||
|
#include "core/renderer_window.h"
|
||||||
|
#include "core/window_manager.h"
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
aorii::create_renderer(renderer_api::dx11);
|
||||||
|
aorii::create_window_manager();
|
||||||
|
|
||||||
|
auto window = aorii::create_window({128, 128}, "hello world");
|
||||||
|
auto glfw_window = window->get_glfw_window();
|
||||||
|
while (!glfwWindowShouldClose(glfw_window)) {
|
||||||
|
glfwMakeContextCurrent(glfw_window);
|
||||||
|
glfwPollEvents();
|
||||||
|
aorii::s_renderer->render(0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
aorii::destroy_window_manager();
|
||||||
|
aorii::destroy_renderer();
|
||||||
|
}
|
7
src/core/CMakeLists.txt
Normal file
7
src/core/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
project(aorii_core)
|
||||||
|
|
||||||
|
|
||||||
|
set(SRC_FILES "")
|
||||||
|
retrieve_files(${CMAKE_CURRENT_SOURCE_DIR} SRC_FILES)
|
||||||
|
add_library(${PROJECT_NAME} STATIC ${SRC_FILES})
|
||||||
|
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
28
src/core/misc/scope_exit.h
Normal file
28
src/core/misc/scope_exit.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
template<typename FuncType>
|
||||||
|
class scope_exit_guard {
|
||||||
|
public:
|
||||||
|
scope_exit_guard(FuncType&& in_func) : func((FuncType&&)in_func) {
|
||||||
|
}
|
||||||
|
~scope_exit_guard() {
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
FuncType func;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct scope_exit_syntax_support {
|
||||||
|
template <typename FuncType>
|
||||||
|
scope_exit_guard<FuncType> operator+(FuncType&& InFunc)
|
||||||
|
{
|
||||||
|
return scope_exit_guard<FuncType>((FuncType&&)InFunc);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PRIVATE_CONCATENATE_DETAIL(x, y) x##y
|
||||||
|
#define PRIVATE_CONCATENATE(x, y) PRIVATE_CONCATENATE_DETAIL(x, y)
|
||||||
|
|
||||||
|
#define ON_SCOPE_EXIT const auto PRIVATE_CONCATENATE(scope_exit, __LINE__) = scope_exit_syntax_support() + [&]()
|
||||||
|
|
3
src/core/misc/test.cpp
Normal file
3
src/core/misc/test.cpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
//
|
||||||
|
// Created by 46944 on 24-10-15.
|
||||||
|
//
|
@ -3,37 +3,54 @@ project(renderer)
|
|||||||
set(GL_BACKEND FALSE CACHE BOOL "OpenGL backend to use")
|
set(GL_BACKEND FALSE CACHE BOOL "OpenGL backend to use")
|
||||||
set(DX_BACKEND FALSE CACHE BOOL "DirectX backend to use")
|
set(DX_BACKEND FALSE CACHE BOOL "DirectX backend to use")
|
||||||
set(VK_BACKEND FALSE CACHE BOOL "Vulkan backend to use")
|
set(VK_BACKEND FALSE CACHE BOOL "Vulkan backend to use")
|
||||||
|
set(METAL_BACKEND FALSE CACHE BOOL "Metal backend to use")
|
||||||
|
|
||||||
if (NOT GL_BACKEND AND NOT DX_BACKEND AND NOT VK_BACKEND)
|
if (NOT GL_BACKEND AND NOT DX_BACKEND AND NOT VK_BACKEND AND NOT METAL_BACKEND)
|
||||||
message(FATAL_ERROR "No backend selected")
|
message(FATAL_ERROR "No backend selected")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(RENDERER_SOURCES
|
set(RENDERER_SOURCES "")
|
||||||
renderer.cpp
|
retrieve_files(core RENDERER_SOURCES)
|
||||||
renderer.h
|
|
||||||
renderer_buffer.cpp
|
|
||||||
renderer_buffer.h
|
|
||||||
renderer_texture.cpp
|
|
||||||
renderer_texture.h
|
|
||||||
)
|
|
||||||
|
|
||||||
if (GL_BACKEND)
|
if (GL_BACKEND)
|
||||||
retrieve_files(backend/gl RENDERER_SOURCES)
|
retrieve_files(backend/gl RENDERER_SOURCES)
|
||||||
add_definitions(-DGL_BACKEND=1)
|
|
||||||
endif()
|
endif()
|
||||||
if (DX_BACKEND)
|
if (DX_BACKEND)
|
||||||
retrieve_files(backend/dx RENDERER_SOURCES)
|
retrieve_files(backend/dx RENDERER_SOURCES)
|
||||||
add_definitions(-DDX_BACKEND=1)
|
|
||||||
endif ()
|
endif ()
|
||||||
if (VK_BACKEND)
|
if (VK_BACKEND)
|
||||||
retrieve_files(backend/vk RENDERER_SOURCES)
|
retrieve_files(backend/vk RENDERER_SOURCES)
|
||||||
add_definitions(-DVK_BACKEND=1)
|
endif ()
|
||||||
|
if (METAL_BACKEND)
|
||||||
|
retrieve_files(backend/metal RENDERER_SOURCES)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} STATIC ${RENDERER_SOURCES})
|
add_library(${PROJECT_NAME} STATIC ${RENDERER_SOURCES})
|
||||||
target_link_libraries(${PROJECT_NAME} Eigen3::Eigen spdlog::spdlog)
|
target_link_libraries(${PROJECT_NAME} PUBLIC Eigen3::Eigen spdlog::spdlog glfw aorii_core)
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
add_os_definitions(${PROJECT_NAME})
|
||||||
|
configure_glfw_native(${PROJECT_NAME})
|
||||||
|
|
||||||
|
set(ALL_BACKENDS GL_BACKEND DX_BACKEND VK_BACKEND METAL_BACKEND)
|
||||||
|
if (GL_BACKEND)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PUBLIC GL_BACKEND=1)
|
||||||
|
list(REMOVE_ITEM ALL_BACKENDS GL_BACKEND)
|
||||||
|
endif()
|
||||||
|
if (DX_BACKEND)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PUBLIC DX_BACKEND=1)
|
||||||
|
list(REMOVE_ITEM ALL_BACKENDS DX_BACKEND)
|
||||||
|
endif ()
|
||||||
|
if (VK_BACKEND)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PUBLIC VK_BACKEND=1)
|
||||||
|
list(REMOVE_ITEM ALL_BACKENDS VK_BACKEND)
|
||||||
|
endif ()
|
||||||
|
if (METAL_BACKEND)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PUBLIC METAL_BACKEND=1)
|
||||||
|
list(REMOVE_ITEM ALL_BACKENDS METAL_BACKEND)
|
||||||
|
endif ()
|
||||||
|
foreach(BACKEND ${ALL_BACKENDS})
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PUBLIC ${BACKEND}=0)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
if (DX_BACKEND)
|
if (DX_BACKEND)
|
||||||
target_link_libraries(${PROJECT_NAME} d3d11 d3dcompiler dxgi)
|
target_link_libraries(${PROJECT_NAME} PRIVATE d3d11 d3dcompiler dxgi)
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
#include "dx_backend.h"
|
|
||||||
|
|
||||||
#include "dx_texture.h"
|
|
||||||
#include "spdlog/spdlog.h"
|
|
||||||
|
|
||||||
std::shared_ptr<renderer_texture> 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<dx_texture>(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;
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "renderer.h"
|
|
||||||
#include <d3d11.h>
|
|
||||||
|
|
||||||
class dx_backend : public renderer {
|
|
||||||
inline static dx_backend* instance = nullptr;
|
|
||||||
public:
|
|
||||||
static dx_backend* get_instance() {
|
|
||||||
return static_cast<dx_backend*>(aorii::s_renderer);
|
|
||||||
}
|
|
||||||
bool init() override;
|
|
||||||
|
|
||||||
std::shared_ptr<renderer_texture> 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;
|
|
||||||
};
|
|
||||||
|
|
70
src/renderer/backend/dx/dx_renderer.cpp
Normal file
70
src/renderer/backend/dx/dx_renderer.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include "dx_renderer.h"
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "dx_texture.h"
|
||||||
|
#include "dx_window.h"
|
||||||
|
#include "core/window_manager.h"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
|
bool dx_renderer::init() {
|
||||||
|
if (!glfwInit()) return false;
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
|
|
||||||
|
if (!create_device()) return false;
|
||||||
|
if (!create_context()) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dx_renderer::destroy() { glfwTerminate(); }
|
||||||
|
|
||||||
|
bool dx_renderer::render(float delta_time) {
|
||||||
|
const auto& all_window = aorii::get_all_window();
|
||||||
|
for (const auto& window : all_window) {
|
||||||
|
window->begin_frame();
|
||||||
|
window->end_frame();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dx_renderer::destroy_texture(renderer_texture* texture) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
spdlog::info("Destroying texture");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer_texture* dx_renderer::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 new dx_texture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer_window* dx_renderer::create_window() {
|
||||||
|
return new dx_window();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dx_renderer::create_device() {
|
||||||
|
constexpr 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_renderer::create_context() {
|
||||||
|
device->GetImmediateContext(&context);
|
||||||
|
return true;
|
||||||
|
}
|
28
src/renderer/backend/dx/dx_renderer.h
Normal file
28
src/renderer/backend/dx/dx_renderer.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <d3d11.h>
|
||||||
|
|
||||||
|
#include "core/renderer.h"
|
||||||
|
|
||||||
|
class dx_window;
|
||||||
|
|
||||||
|
class dx_renderer : public renderer {
|
||||||
|
public:
|
||||||
|
bool init() override;
|
||||||
|
void destroy() override;
|
||||||
|
bool render(float delta_time) override;
|
||||||
|
|
||||||
|
renderer_texture* create_texture(const Eigen::Vector2i& size) override;
|
||||||
|
void destroy_texture(renderer_texture* texture) override;
|
||||||
|
|
||||||
|
ID3D11Device* get_d3d_device() const { return device; }
|
||||||
|
ID3D11DeviceContext* get_d3d_context() const { return context; }
|
||||||
|
private:
|
||||||
|
renderer_window* create_window() override;
|
||||||
|
|
||||||
|
bool create_device();
|
||||||
|
bool create_context();
|
||||||
|
|
||||||
|
ID3D11Device* device = nullptr;
|
||||||
|
ID3D11DeviceContext* context = nullptr;
|
||||||
|
};
|
||||||
|
|
@ -1,10 +1,8 @@
|
|||||||
#include "dx_texture.h"
|
#include "dx_texture.h"
|
||||||
|
|
||||||
#include "dx_backend.h"
|
#include "dx_renderer.h"
|
||||||
|
|
||||||
dx_texture::dx_texture(ID3D11Texture2D* texture) {
|
dx_texture::dx_texture(ID3D11Texture2D* texture) { m_texture = texture; }
|
||||||
m_texture = texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
dx_texture::~dx_texture() {
|
dx_texture::~dx_texture() {
|
||||||
// 如果是Debug模式, 检查m_data是否被释放
|
// 如果是Debug模式, 检查m_data是否被释放
|
||||||
@ -22,20 +20,18 @@ void* dx_texture::lock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dx_texture::unlock() {
|
void dx_texture::unlock() {
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
// D3D11_TEXTURE2D_DESC desc;
|
||||||
m_texture->GetDesc(&desc);
|
// m_texture->GetDesc(&desc);
|
||||||
D3D11_MAPPED_SUBRESOURCE mappedResource;
|
// D3D11_MAPPED_SUBRESOURCE mappedResource;
|
||||||
auto context = dx_backend::get_instance();
|
// auto context = dx_backend::get_instance();
|
||||||
context->Map(m_texture.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
// context->Map(m_texture.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
||||||
memcpy(mappedResource.pData, m_data, desc.Width * desc.Height * 4);
|
// memcpy(mappedResource.pData, m_data, desc.Width * desc.Height * 4);
|
||||||
context->Unmap(m_texture.get(), 0);
|
// context->Unmap(m_texture.get(), 0);
|
||||||
delete[] m_data;
|
// delete[] m_data;
|
||||||
m_data = nullptr;
|
// m_data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dx_texture::resize(const Eigen::Vector2i& size) {
|
bool dx_texture::resize(const Eigen::Vector2i& size) { return true; }
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Eigen::Vector2i dx_texture::size() {
|
Eigen::Vector2i dx_texture::size() {
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "renderer_texture.h"
|
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "core/renderer_texture.h"
|
||||||
|
|
||||||
// DX11纹理
|
// DX11纹理
|
||||||
class dx_texture : public renderer_texture {
|
class dx_texture : public renderer_texture {
|
||||||
public:
|
public:
|
||||||
|
126
src/renderer/backend/dx/dx_window.cpp
Normal file
126
src/renderer/backend/dx/dx_window.cpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#include "dx_window.h"
|
||||||
|
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include "dx_renderer.h"
|
||||||
|
#include "misc/scope_exit.h"
|
||||||
|
|
||||||
|
using namespace aorii;
|
||||||
|
|
||||||
|
bool dx_window::create_surface(GLFWwindow* in_window) {
|
||||||
|
const auto d3d_device = aorii::get_renderer<dx_renderer>()->get_d3d_device();
|
||||||
|
|
||||||
|
IDXGIDevice* dxgi_device = nullptr;
|
||||||
|
auto hr = d3d_device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgi_device));
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
spdlog::critical("Failed to get IDXGIDevice. Error: {0}", hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ON_SCOPE_EXIT{
|
||||||
|
if (dxgi_device) dxgi_device->Release();
|
||||||
|
};
|
||||||
|
|
||||||
|
IDXGIAdapter* dxgi_adapter = nullptr;
|
||||||
|
hr = dxgi_device->GetAdapter(&dxgi_adapter);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
spdlog::critical("Failed to get IDXGIAdapter. Error: {0}", hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ON_SCOPE_EXIT{
|
||||||
|
if (dxgi_adapter) dxgi_adapter->Release();
|
||||||
|
};
|
||||||
|
|
||||||
|
IDXGIFactory2* dxgi_factory = nullptr;
|
||||||
|
hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgi_factory));
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
spdlog::critical("Failed to get IDXGIFactory. Error: {0}", hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ON_SCOPE_EXIT{
|
||||||
|
if (dxgi_factory) dxgi_factory->Release();
|
||||||
|
};
|
||||||
|
|
||||||
|
DXGI_SWAP_CHAIN_DESC1 sd = {};
|
||||||
|
sd.Width = 0; // 使用窗口宽度
|
||||||
|
sd.Height = 0; // 使用窗口高度
|
||||||
|
sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
sd.SampleDesc.Count = 1;
|
||||||
|
sd.SampleDesc.Quality = 0;
|
||||||
|
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
sd.BufferCount = 2;
|
||||||
|
sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||||
|
sd.Flags = 0;
|
||||||
|
|
||||||
|
const auto hwnd = static_cast<HWND>(get_window_handle());
|
||||||
|
hr = dxgi_factory->CreateSwapChainForHwnd(d3d_device, hwnd, &sd, nullptr, nullptr, &swap_chain);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
spdlog::critical("Failed to create swap chain. Error: {0}", hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
build_render_target_view();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dx_window::begin_frame() {
|
||||||
|
const auto render = aorii::get_renderer<dx_renderer>();
|
||||||
|
const auto d3d_context = render->get_d3d_context();
|
||||||
|
|
||||||
|
d3d_context->ClearRenderTargetView(render_target_view, clear_color);
|
||||||
|
|
||||||
|
swap_chain->Present(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dx_window::end_frame() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void dx_window::on_resize(const Eigen::Vector2i& in_size) {
|
||||||
|
if (in_size.isZero())
|
||||||
|
return;
|
||||||
|
if (render_target_view) {
|
||||||
|
render_target_view->Release();
|
||||||
|
render_target_view = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto hr = swap_chain->ResizeBuffers(0, in_size.x(), in_size.y(), DXGI_FORMAT_UNKNOWN, 0);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
spdlog::critical("Failed to resize window. Error: {0}", hr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
build_render_target_view();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dx_window::build_render_target_view() {
|
||||||
|
const auto d3d_device = aorii::get_renderer<dx_renderer>()->get_d3d_device();
|
||||||
|
const auto d3d_context = aorii::get_renderer<dx_renderer>()->get_d3d_context();
|
||||||
|
|
||||||
|
ID3D11Texture2D* back_buffer = nullptr;
|
||||||
|
auto hr = swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&back_buffer);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
spdlog::critical("Failed to get back buffer. Error: {0}", hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ON_SCOPE_EXIT{
|
||||||
|
if (back_buffer) back_buffer->Release();
|
||||||
|
};
|
||||||
|
|
||||||
|
hr = d3d_device->CreateRenderTargetView(back_buffer, nullptr, &render_target_view);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
spdlog::critical("Failed to create render target. Error: {0}", hr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto framebuffer_size = get_framebuffer_size();
|
||||||
|
|
||||||
|
D3D11_VIEWPORT viewport = {};
|
||||||
|
viewport.Width = framebuffer_size.x();
|
||||||
|
viewport.Height = framebuffer_size.y();
|
||||||
|
viewport.MinDepth = 0.0f;
|
||||||
|
viewport.MaxDepth = 1.0f;
|
||||||
|
viewport.TopLeftX = 0.0f;
|
||||||
|
viewport.TopLeftY = 0.0f;
|
||||||
|
d3d_context->RSSetViewports(1, &viewport);
|
||||||
|
d3d_context->OMSetRenderTargets(1, &render_target_view, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
19
src/renderer/backend/dx/dx_window.h
Normal file
19
src/renderer/backend/dx/dx_window.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <dxgi1_2.h>
|
||||||
|
|
||||||
|
#include "core/renderer_window.h"
|
||||||
|
|
||||||
|
class dx_window : public renderer_window {
|
||||||
|
public:
|
||||||
|
void begin_frame() override;
|
||||||
|
void end_frame() override;
|
||||||
|
protected:
|
||||||
|
bool create_surface(GLFWwindow* in_window) override;
|
||||||
|
void on_resize(const Eigen::Vector2i& in_size) override;
|
||||||
|
|
||||||
|
bool build_render_target_view();
|
||||||
|
private:
|
||||||
|
IDXGISwapChain1* swap_chain = nullptr;
|
||||||
|
ID3D11RenderTargetView* render_target_view = nullptr;
|
||||||
|
};
|
47
src/renderer/core/renderer.cpp
Normal file
47
src/renderer/core/renderer.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include "renderer.h"
|
||||||
|
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include "renderer_window.h"
|
||||||
|
|
||||||
|
#if DX_BACKEND
|
||||||
|
#include "backend/dx/dx_renderer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool aorii::create_renderer(renderer_api api) {
|
||||||
|
if (s_renderer) return true;
|
||||||
|
switch (api) {
|
||||||
|
#if DX_BACKEND
|
||||||
|
case renderer_api::dx11: s_renderer = new dx_renderer();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if GL_BACKEND
|
||||||
|
case renderer_api::opengl:
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if VK_BACKEND
|
||||||
|
case renderer_api::vulkan:
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default: spdlog::critical("Failed to create renderer!");
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s_renderer->init()) {
|
||||||
|
delete s_renderer;
|
||||||
|
s_renderer = nullptr;
|
||||||
|
}
|
||||||
|
return s_renderer != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void aorii::destroy_renderer() {
|
||||||
|
if (!s_renderer) return;
|
||||||
|
|
||||||
|
s_renderer->destroy();
|
||||||
|
delete s_renderer;
|
||||||
|
s_renderer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderer::destroy_window(renderer_window* window) {
|
||||||
|
delete window;
|
||||||
|
}
|
40
src/renderer/core/renderer.h
Normal file
40
src/renderer/core/renderer.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include <Eigen/Eigen>
|
||||||
|
|
||||||
|
class renderer_window;
|
||||||
|
class renderer_texture;
|
||||||
|
|
||||||
|
enum class renderer_api {
|
||||||
|
dx11,
|
||||||
|
opengl,
|
||||||
|
vulkan,
|
||||||
|
metal,
|
||||||
|
};
|
||||||
|
|
||||||
|
class renderer {
|
||||||
|
friend class window_manager;
|
||||||
|
public:
|
||||||
|
virtual ~renderer() = default;
|
||||||
|
|
||||||
|
virtual bool init() = 0;
|
||||||
|
virtual void destroy() = 0;
|
||||||
|
virtual bool render(float delta_time) = 0;
|
||||||
|
|
||||||
|
virtual renderer_texture* create_texture(const Eigen::Vector2i& size) = 0;
|
||||||
|
virtual void destroy_texture(renderer_texture* texture) = 0;
|
||||||
|
private:
|
||||||
|
virtual renderer_window* create_window() = 0;
|
||||||
|
virtual void destroy_window(renderer_window* window);
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace aorii {
|
||||||
|
inline renderer* s_renderer = nullptr;
|
||||||
|
template<typename T>
|
||||||
|
static T* get_renderer() {
|
||||||
|
return static_cast<T*>(s_renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool create_renderer(renderer_api api);
|
||||||
|
void destroy_renderer();
|
||||||
|
}
|
26
src/renderer/core/renderer_window.cpp
Normal file
26
src/renderer/core/renderer_window.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "renderer_window.h"
|
||||||
|
#include "GLFW/glfw3native.h"
|
||||||
|
|
||||||
|
renderer_window::~renderer_window() { if (window) glfwDestroyWindow(window); }
|
||||||
|
|
||||||
|
bool renderer_window::init(const Eigen::Vector2i& in_size, const std::string& in_title) {
|
||||||
|
window = glfwCreateWindow(in_size.x(), in_size.y(), in_title.c_str(), nullptr, nullptr);
|
||||||
|
if (!window) return false;
|
||||||
|
return create_surface(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* renderer_window::get_window_handle() const {
|
||||||
|
#if WINDOWS
|
||||||
|
return glfwGetWin32Window(window);
|
||||||
|
#elif MACOS
|
||||||
|
return glfwGetCocoaWindow(window);
|
||||||
|
#elif LINUX
|
||||||
|
#if GLFW_EXPOSE_NATIVE_WAYLAND
|
||||||
|
return glfwGetWaylandWindow(window);
|
||||||
|
#else
|
||||||
|
return (void*)glfwGetX11Window(window);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
41
src/renderer/core/renderer_window.h
Normal file
41
src/renderer/core/renderer_window.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Eigen/Eigen"
|
||||||
|
#include "GLFW/glfw3.h"
|
||||||
|
|
||||||
|
class renderer_window {
|
||||||
|
friend class window_manager;
|
||||||
|
public:
|
||||||
|
const float clear_color[4] = {0.4, 0.3, 0.6, 1};
|
||||||
|
|
||||||
|
virtual ~renderer_window();
|
||||||
|
|
||||||
|
virtual bool init(const Eigen::Vector2i& in_size, const std::string& in_title);
|
||||||
|
|
||||||
|
virtual void begin_frame() = 0;
|
||||||
|
virtual void end_frame() = 0;
|
||||||
|
|
||||||
|
void resize(const Eigen::Vector2i& in_size) {
|
||||||
|
if (in_size == get_window_size()) return;
|
||||||
|
on_resize(in_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Eigen::Vector2i get_window_size() const {
|
||||||
|
int w, h;
|
||||||
|
glfwGetWindowSize(window, &w, &h);
|
||||||
|
return Eigen::Vector2i(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
Eigen::Vector2i get_framebuffer_size() const {
|
||||||
|
int w, h;
|
||||||
|
glfwGetFramebufferSize(window, &w, &h);
|
||||||
|
return Eigen::Vector2i(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* get_window_handle() const;
|
||||||
|
GLFWwindow* get_glfw_window() const { return window; }
|
||||||
|
protected:
|
||||||
|
virtual bool create_surface(GLFWwindow* in_window) = 0;
|
||||||
|
virtual void on_resize(const Eigen::Vector2i& in_size) = 0;
|
||||||
|
private:
|
||||||
|
GLFWwindow* window = nullptr;
|
||||||
|
};
|
44
src/renderer/core/window_manager.cpp
Normal file
44
src/renderer/core/window_manager.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "window_manager.h"
|
||||||
|
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
|
#include "renderer.h"
|
||||||
|
#include "renderer_window.h"
|
||||||
|
|
||||||
|
void on_window_size_change(GLFWwindow* changed_window, int width, int height) {
|
||||||
|
aorii::s_window_manager->on_glfw_window_size_callback(changed_window, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
window_manager::~window_manager() {
|
||||||
|
for (const auto window : windows) {
|
||||||
|
aorii::s_renderer->destroy_window(window);
|
||||||
|
}
|
||||||
|
windows.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer_window* window_manager::create_window(const Eigen::Vector2i& in_size, const std::string& in_title) {
|
||||||
|
const auto window = aorii::s_renderer->create_window();
|
||||||
|
if (!window->init(in_size, in_title)) {
|
||||||
|
delete window;
|
||||||
|
spdlog::error("Failed to create window");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const auto glfw_window = window->get_glfw_window();
|
||||||
|
glfwSetFramebufferSizeCallback(glfw_window, on_window_size_change);
|
||||||
|
windows.push_back(window);
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void window_manager::on_glfw_window_size_callback(GLFWwindow* in_window, int width, int height) {
|
||||||
|
auto find = find_window(in_window);
|
||||||
|
if (!find) return;
|
||||||
|
find->on_resize({ width, height });
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer_window* window_manager::find_window(GLFWwindow* in_window) {
|
||||||
|
auto it = std::find_if(windows.begin(), windows.end(), [in_window](renderer_window* w) {
|
||||||
|
return w->get_glfw_window() == in_window;
|
||||||
|
});
|
||||||
|
if (it != windows.end()) { return *it; }
|
||||||
|
return nullptr;
|
||||||
|
}
|
30
src/renderer/core/window_manager.h
Normal file
30
src/renderer/core/window_manager.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Eigen/Eigen"
|
||||||
|
#include "GLFW/glfw3.h"
|
||||||
|
|
||||||
|
class renderer_window;
|
||||||
|
|
||||||
|
class window_manager {
|
||||||
|
public:
|
||||||
|
~window_manager();
|
||||||
|
renderer_window* create_window(const Eigen::Vector2i& in_size, const std::string& in_title);
|
||||||
|
|
||||||
|
const auto& get_windows() const { return windows; }
|
||||||
|
|
||||||
|
void on_glfw_window_size_callback(GLFWwindow* in_window, int width, int height);
|
||||||
|
private:
|
||||||
|
renderer_window* find_window(GLFWwindow* in_window);
|
||||||
|
std::vector<renderer_window*> windows;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace aorii {
|
||||||
|
inline window_manager* s_window_manager;
|
||||||
|
inline void create_window_manager() { s_window_manager = new window_manager(); }
|
||||||
|
inline void destroy_window_manager() { delete s_window_manager; }
|
||||||
|
|
||||||
|
inline renderer_window* create_window(const Eigen::Vector2i& in_size, const std::string& in_title) {
|
||||||
|
return s_window_manager->create_window(in_size, in_title);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const auto& get_all_window() { return s_window_manager->get_windows(); }
|
||||||
|
}
|
@ -1,29 +0,0 @@
|
|||||||
#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();
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <memory>
|
|
||||||
#include <Eigen/Eigen>
|
|
||||||
|
|
||||||
class renderer_texture;
|
|
||||||
|
|
||||||
enum class renderer_api {
|
|
||||||
dx11,
|
|
||||||
opengl,
|
|
||||||
vulkan,
|
|
||||||
};
|
|
||||||
|
|
||||||
class renderer {
|
|
||||||
public:
|
|
||||||
virtual ~renderer() = default;
|
|
||||||
|
|
||||||
virtual std::shared_ptr<renderer_texture> 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);
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user