diff --git a/CMakeLists.txt b/CMakeLists.txt index bb83cd3..9112e29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,25 +4,8 @@ cmake_minimum_required(VERSION 3.21) project(mirage) -# 指定需要的 C++ 标准 -set(CMAKE_CXX_STANDARD 23) -# 强制要求此标准,如果编译器不支持则配置时报错 -set(CMAKE_CXX_STANDARD_REQUIRED ON) -# 可选:禁用编译器特定的扩展,使用纯粹的标准 -set(CMAKE_CXX_EXTENSIONS OFF) - -if (MSVC) - # 设置utf-8编码 - add_compile_options(/utf-8) - # 强制 MSVC 正确设置 __cplusplus 宏 - add_compile_options(/Zc:__cplusplus) -endif () -if (WIN32) - # 定义Windows版本宏 -# add_definitions(-DWIN32_LEAN_AND_MEAN) - add_definitions(-DUNICODE -D_UNICODE) -endif () - +include(cmake/project_cpp_standard.cmake) +set_cpp_standard(23) set(MIRAGE_USE_HDR OFF CACHE BOOL "Enable HDR format") set(MIRAGE_HDR_FORMAT "SG_PIXELFORMAT_RGBA16F" CACHE STRING "Enable HDR format") diff --git a/cmake/project_cpp_standard.cmake b/cmake/project_cpp_standard.cmake new file mode 100644 index 0000000..53bf74e --- /dev/null +++ b/cmake/project_cpp_standard.cmake @@ -0,0 +1,52 @@ + +function(set_cpp_standard standard) + # 参数验证 + set(VALID_STANDARDS 11 14 17 20 23) + if(NOT ${standard} IN_LIST VALID_STANDARDS) + message(WARNING "非标准 C++ 版本: ${standard},支持的版本有: ${VALID_STANDARDS}") + endif() + + # 指定需要的 C++ 标准,设置到父作用域 + set(CMAKE_CXX_STANDARD ${standard} PARENT_SCOPE) + # 强制要求此标准,如果编译器不支持则配置时报错 + set(CMAKE_CXX_STANDARD_REQUIRED ON PARENT_SCOPE) + # 可选:禁用编译器特定的扩展,使用纯粹的标准 + set(CMAKE_CXX_EXTENSIONS OFF PARENT_SCOPE) + + if(MSVC) + # 设置utf-8编码 + add_compile_options(/utf-8) + # 强制 MSVC 正确设置 __cplusplus 宏 + add_compile_options(/Zc:__cplusplus) + # 可选:增加 MSVC 警告级别 + add_compile_options(/W4) + endif() + + if(WIN32) + # 定义Windows版本宏 + add_definitions(-DUNICODE -D_UNICODE) + # 可选:添加 WIN32_LEAN_AND_MEAN 以减少 Windows 头文件包含 + # add_definitions(-DWIN32_LEAN_AND_MEAN) + endif() + + # GCC/Clang 特定选项 + if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra) + # 根据 C++ 标准添加特定选项 + if(${standard} GREATER 14) # 更兼容的写法,避免使用 GREATER_EQUAL + add_compile_options(-Wshadow -Wnon-virtual-dtor) + endif() + endif() + + # 如果是MinGW, 并且使用了C++17或更高版本, 则添加libstdc++exp库 + if(MINGW) + message(STATUS "检测到MinGW编译器") + # 更兼容的版本比较 + if(${standard} GREATER 14) # C++17及以上 + message(STATUS "为C++${standard}添加libstdc++exp库支持") + link_libraries(-lstdc++exp) + endif() + endif() + + message(STATUS "已设置C++${standard}标准") +endfunction() diff --git a/example/src/main.cpp b/example/src/main.cpp index 5d77a07..e687b5b 100644 --- a/example/src/main.cpp +++ b/example/src/main.cpp @@ -41,11 +41,11 @@ int main(int argc, char* argv[]) { for (const char* test_str : test_cases) { std::optional color = linear_color::from_string(test_str); - std::cout << "Parsing '" << test_str << "': "; + std::println(std::cout, "Parsing '{}': ", test_str); if (color) { - std::cout << "Success -> r:" << color->r << " g:" << color->g << " b:" << color->b << " a:" << color->a << std::endl; + std::println(std::cout, "Success -> r:{}, g:{}, b:{}, a:{}", color->r, color->g, color->b, color->a); } else { - std::cout << "Failed" << std::endl; + std::println(std::cerr, "Failed to parse color string: {}", test_str); } } @@ -70,29 +70,33 @@ int main(int argc, char* argv[]) { const auto& text_block2 = std::make_shared(); text_block2->set_text(U"Hello, World!"); - const auto button = mnew(mbutton) - mslot(mbutton) - .margin({10}) - .visibility(visibility_t::visible) - [ - text_block - ]; + auto button = std::make_shared(); + button->push_slot( + mslot(mbutton) + .margin({10}) + .visibility(visibility_t::visible) + [ + text_block + ] + ); - const auto button2 = mnew(mbutton) - mslot(mbutton) - .visibility(visibility_t::visible) - [ - text_block2 - ]; + // const auto button2 = mnew(mbutton) + // mslot(mbutton) + // .visibility(visibility_t::visible) + // [ + // text_block2 + // ]; const auto& window = mwindow::create({ 800, 600 }, L"Hello, World!"); window->set_content( - mnew(mborder) - mslot(mborder) - .h_alignment(horizontal_alignment_t::center) - .v_alignment(vertical_alignment_t::center) + mborder() [ - button + mslot(mborder) + .h_alignment(horizontal_alignment_t::center) + .v_alignment(vertical_alignment_t::center) + [ + button + ] ] ); diff --git a/src/mirage_image/pixel.h b/src/mirage_image/pixel.h index fe705ae..3ef6393 100644 --- a/src/mirage_image/pixel.h +++ b/src/mirage_image/pixel.h @@ -967,7 +967,7 @@ namespace color_space { z /= zn; // XYZ到Lab的变换 - auto f = [](T t) { + auto f = [](T t) static { const T delta = 6.0f / 29.0f; return (t > std::pow(delta, 3)) ? std::pow(t, 1.0f / 3.0f) : (t / (3 * std::pow(delta, 2)) + 4.0f / 29.0f); }; @@ -998,7 +998,7 @@ namespace color_space { const T zn = 1.08883f; // Lab到XYZ的变换 - auto f_inv = [](T t) { + auto f_inv = [](T t) static { const T delta = 6.0f / 29.0f; return (t > delta) ? std::pow(t, 3) : 3 * std::pow(delta, 2) * (t - 4.0f / 29.0f); }; diff --git a/src/mirage_render/src/render/render_context.h b/src/mirage_render/src/render/render_context.h index 738db16..c10a7e8 100644 --- a/src/mirage_render/src/render/render_context.h +++ b/src/mirage_render/src/render/render_context.h @@ -68,7 +68,7 @@ struct mirage_window_state { * * 当窗口大小改变时重建交换链。虚方法,由派生类实现。 */ - virtual void rebuild_swapchain(const Eigen::Vector2i& size) {} + virtual void rebuild_swapchain(const Eigen::Vector2i& size) { (void)size; } }; /** diff --git a/src/mirage_render/src/render/windows/windows_render_context.cpp b/src/mirage_render/src/render/windows/windows_render_context.cpp index 0e12142..d1fe4cb 100644 --- a/src/mirage_render/src/render/windows/windows_render_context.cpp +++ b/src/mirage_render/src/render/windows/windows_render_context.cpp @@ -2,6 +2,8 @@ #include #include +#include + #include "misc/angle_literals.h" #include @@ -59,8 +61,7 @@ bool windows_mirage_render_context::init() { // 检查是否成功创建设备 if (FAILED(hr)) { - std::cerr << "mirage: " << "Failed to create D3D11 device with any driver type. HRESULT: 0x" - << std::hex << hr << std::dec << std::endl; + std::println(std::cerr, "mirage: 所有的 D3D11 设备类型都创建失败. HRESULT: 0x{:#06x}", hr); cleanup(); return false; } @@ -69,7 +70,7 @@ bool windows_mirage_render_context::init() { IDXGIDevice* dxgi_device = nullptr; hr = device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast(&dxgi_device)); if (FAILED(hr)) { - std::cerr << "mirage: Failed to get DXGI device. HRESULT: 0x" << std::hex << hr << std::dec << std::endl; + std::println(std::cerr, "mirage: 获取 DXGI 设备失败. HRESULT: 0x{:#06x}", hr); cleanup(); return false; } @@ -80,7 +81,7 @@ bool windows_mirage_render_context::init() { dxgi_device->Release(); if (FAILED(hr)) { - std::cerr << "mirage: Failed to get DXGI adapter. HRESULT: 0x" << std::hex << hr << std::dec << std::endl; + std::println(std::cerr, "mirage: 无法获取 DXGI 适配器. HRESULT: 0x{:#06x}", hr); cleanup(); return false; } @@ -89,46 +90,46 @@ bool windows_mirage_render_context::init() { DXGI_ADAPTER_DESC adapter_desc; hr = dxgi_adapter->GetDesc(&adapter_desc); if (FAILED(hr)) { - std::wcerr << L"mirage: Failed to get DXGI Adapter description" << std::endl; + std::println(std::cerr, "mirage: 无法获取 DXGI 适配器描述信息. HRESULT: 0x{:#06x}", hr); } // **尝试获取最新的DXGI工厂版本 - 从最新的Factory6开始尝试** // Windows 10 Fall Creators Update (1709)或更高版本支持 hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory6), reinterpret_cast(&dxgi_factory)); if (SUCCEEDED(hr)) { - std::cout << "mirage: Using IDXGIFactory6" << std::endl; + std::println(std::cout, "mirage: 使用 DXGI Factory6"); } else { // 尝试Factory5 - Windows 10 Anniversary Update (1607)或更高版本 hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory5), reinterpret_cast(&dxgi_factory)); if (SUCCEEDED(hr)) { - std::cout << "mirage: Using IDXGIFactory5" << std::endl; + std::println(std::cout, "mirage: 使用 DXGI Factory5"); } else { // 尝试Factory4 - Windows 10初始版本 hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory4), reinterpret_cast(&dxgi_factory)); if (SUCCEEDED(hr)) { - std::cout << "mirage: Using IDXGIFactory4" << std::endl; + std::println(std::cout, "mirage: 使用 DXGI Factory4"); } else { // 尝试Factory3 - Windows 8.1 hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory3), reinterpret_cast(&dxgi_factory)); if (SUCCEEDED(hr)) { - std::cout << "mirage: Using IDXGIFactory3" << std::endl; + std::println(std::cout, "mirage: 使用 DXGI Factory3"); } else { // 尝试Factory2 - Windows 8,支持FLIP模式交换链 hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast(&dxgi_factory)); if (SUCCEEDED(hr)) { - std::cout << "mirage: Using IDXGIFactory2" << std::endl; + std::println(std::cout, "mirage: 使用 DXGI Factory2"); } else { // 回退到基本Factory1 - Windows 7 hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast(&dxgi_factory)); if (SUCCEEDED(hr)) { - std::cout << "mirage: Using IDXGIFactory1" << std::endl; + std::println(std::cout, "mirage: 使用 DXGI Factory1"); } else { // 最后尝试原始Factory hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast(&dxgi_factory)); if (SUCCEEDED(hr)) { - std::cout << "mirage: Using IDXGIFactory" << std::endl; + std::println(std::cout, "mirage: 使用 DXGI Factory"); } else { - std::cerr << "mirage: Failed to get any DXGI Factory" << std::endl; + std::println(std::cerr, "mirage: 无法获取 DXGI Factory. HRESULT: 0x{:#06x}", hr); dxgi_adapter->Release(); cleanup(); return false; @@ -149,7 +150,7 @@ bool windows_mirage_render_context::init() { DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allow_tearing, sizeof(allow_tearing)))) { - std::cout << "mirage: Tearing support: " << (allow_tearing ? "Yes" : "No") << std::endl; + std::println(std::cout, "mirage: 防撕裂支持: {}", (bool)allow_tearing); } factory5->Release(); } @@ -157,9 +158,15 @@ bool windows_mirage_render_context::init() { dxgi_adapter->Release(); + // 输出初始化成功信息 - std::cout << "mirage: D3D11 device created successfully" << std::endl; - std::wcout << L"mirage: Using adapter: " << adapter_desc.Description << std::endl; + std::println(std::cout, "mirage: 成功创建 D3D11 设备"); + { + std::u16string adapter_desc_str((const char16_t*)adapter_desc.Description); + auto str = utf8::utf16to8(adapter_desc_str); + std::println(std::cout, "mirage: 适配器名称: {}", str); + } + std::println(std::cout, "mirage: 适配器 VRAM: {} MB", adapter_desc.DedicatedVideoMemory / 1024 / 1024); // 输出驱动类型信息 auto driver_type_str = "Unknown"; @@ -172,7 +179,7 @@ bool windows_mirage_render_context::init() { break; default: ; } - std::cout << "mirage: Using driver type: " << driver_type_str << std::endl; + std::println(std::cout, "mirage: 使用驱动类型: {}", driver_type_str); // 输出特性级别信息 auto feature_level_str = "Unknown"; @@ -187,11 +194,11 @@ bool windows_mirage_render_context::init() { break; default: ; } - std::cout << "mirage: Using feature level: " << feature_level_str << std::endl; + std::println(std::cout, "mirage: 使用特性级别: {}", feature_level_str); return true; } catch (const std::exception& e) { - std::cerr << "mirage: Exception during D3D11 initialization: " << e.what() << std::endl; + std::println(std::cerr, "mirage: D3D11初始化失败: {}", e.what()); cleanup(); return false; } diff --git a/src/mirage_render/src/render/windows/windows_render_state.cpp b/src/mirage_render/src/render/windows/windows_render_state.cpp index 3539378..b16b923 100644 --- a/src/mirage_render/src/render/windows/windows_render_state.cpp +++ b/src/mirage_render/src/render/windows/windows_render_state.cpp @@ -202,7 +202,7 @@ void windows_render_state::rebuild_swapchain(const Eigen::Vector2i& size) { IDXGISwapChain4* swapChain4 = nullptr; if (SUCCEEDED(dx_swap_chain->QueryInterface(__uuidof(IDXGISwapChain4), (void**)&swapChain4))) { #if DEBUG - std::cout << "使用IDXGISwapChain4重建交换链" << std::endl; + std::println(std::cout, "mirage: 使用IDXGISwapChain4重建交换链"); #endif // 保留当前交换链标志 @@ -225,7 +225,7 @@ void windows_render_state::rebuild_swapchain(const Eigen::Vector2i& size) { else { IDXGISwapChain1* swapChain1 = nullptr; if (SUCCEEDED(dx_swap_chain->QueryInterface(__uuidof(IDXGISwapChain1), (void**)&swapChain1))) { - std::cout << "使用IDXGISwapChain1重建交换链" << std::endl; + std::println(std::cout, "mirage: 使用IDXGISwapChain1重建交换链"); // 保留当前交换链标志 DXGI_SWAP_CHAIN_DESC1 desc = {}; @@ -248,7 +248,7 @@ void windows_render_state::rebuild_swapchain(const Eigen::Vector2i& size) { } // 回退到基础IDXGISwapChain else { - std::cout << "使用基础IDXGISwapChain重建交换链" << std::endl; + std::println(std::cout, "mirage: 使用基础IDXGISwapChain重建交换链"); // 获取基础交换链描述 DXGI_SWAP_CHAIN_DESC desc = {}; @@ -323,6 +323,6 @@ void windows_render_state::rebuild_swapchain(const Eigen::Vector2i& size) { context->Release(); #if DEBUG - std::cout << "交换链重建成功,新尺寸: " << size.x() << "x" << size.y() << std::endl; + std::println(std::cout, "mirage: 交换链重建成功,新尺寸: {} x {}", size.x(), size.y()); #endif } diff --git a/src/mirage_widget/src/widget/compound_widget/mbutton.cpp b/src/mirage_widget/src/widget/compound_widget/mbutton.cpp index 758cf80..6bea193 100644 --- a/src/mirage_widget/src/widget/compound_widget/mbutton.cpp +++ b/src/mirage_widget/src/widget/compound_widget/mbutton.cpp @@ -29,34 +29,34 @@ void mbutton::on_paint(mirage_paint_context& in_context) { void mbutton::on_click(const Eigen::Vector2f& in_position, mouse_button in_button) { mborder::on_click(in_position, in_button); - std::cout << this << ": Button clicked!" << in_position.x() << ", " << in_position.y() << std::endl; + std::println(std::cout, "点击 Button: {}, {}", in_position.x(), in_position.y()); color_ = {0.2, 0.2, 0.2, 1}; invalidate(invalidate_reason::paint); } void mbutton::on_double_click(const Eigen::Vector2f& in_position, mouse_button in_button) { mborder::on_double_click(in_position, in_button); - std::cout << this << ": Button double clicked!" << in_position.x() << ", " << in_position.y() << std::endl; + std::println(std::cout, "双击 Button: {}, {}", in_position.x(), in_position.y()); invalidate(invalidate_reason::paint); } void mbutton::on_mouse_enter() { mborder::on_mouse_enter(); - std::cout << this << ": Mouse entered!" << std::endl; + std::println(std::cout, "鼠标进入 Button"); color_ = {0.2, 0.2, 0.2, 1}; invalidate(invalidate_reason::paint); } void mbutton::on_mouse_leave() { mborder::on_mouse_leave(); - std::cout << this << ": Mouse left!" << std::endl; + std::println(std::cout, "鼠标离开 Button"); color_ = {0.1, 0.1, 0.1, 1}; invalidate(invalidate_reason::paint); } hit_test_handle mbutton::on_mouse_button_down(const Eigen::Vector2f& in_position, mouse_button in_button) { mborder::on_mouse_button_down(in_position, in_button); - std::cout << this << ": Mouse pressed!" << in_position.x() << ", " << in_position.y() << std::endl; + std::println(std::cout, "鼠标按下 Button: {}, {}", in_position.x(), in_position.y()); color_ = {0.1, 0.1, 0.1, 1}; invalidate(invalidate_reason::paint); return hit_test_handle::handled(); @@ -64,7 +64,7 @@ hit_test_handle mbutton::on_mouse_button_down(const Eigen::Vector2f& in_position hit_test_handle mbutton::on_mouse_button_up(const Eigen::Vector2f& in_position, mouse_button in_button) { mborder::on_mouse_button_up(in_position, in_button); - std::cout << this << ": Mouse released!" << in_position.x() << ", " << in_position.y() << std::endl; + std::println(std::cout, "鼠标释放 Button: {}, {}", in_position.x(), in_position.y()); color_ = {0.2, 0.2, 0.2, 1}; invalidate(invalidate_reason::paint); return hit_test_handle::handled(); diff --git a/src/mirage_widget/src/widget/mcompound_widget.h b/src/mirage_widget/src/widget/mcompound_widget.h index 4ed4df2..b2fd289 100644 --- a/src/mirage_widget/src/widget/mcompound_widget.h +++ b/src/mirage_widget/src/widget/mcompound_widget.h @@ -93,6 +93,10 @@ public: } return slot_; } + auto operator[](const SlotType& in_slot) { + push_slot(in_slot); + return shared_from_this(); + } //-------------- 尺寸计算 -------------- diff --git a/src/mirage_widget/src/widget/mpanel_widget.h b/src/mirage_widget/src/widget/mpanel_widget.h index 0e701c8..79ec0c5 100644 --- a/src/mirage_widget/src/widget/mpanel_widget.h +++ b/src/mirage_widget/src/widget/mpanel_widget.h @@ -123,6 +123,11 @@ public: const auto& get_slots() const { return slots_; } + + auto operator[](auto... in_slot) { + for (const auto& slot: { in_slot... }) { add_slot(slot); } + return shared_from_this(); + } private: std::vector slots_; }; diff --git a/src/mirage_widget/src/widget/widget_new.h b/src/mirage_widget/src/widget/widget_new.h index b8cd399..d15e682 100644 --- a/src/mirage_widget/src/widget/widget_new.h +++ b/src/mirage_widget/src/widget/widget_new.h @@ -55,5 +55,5 @@ struct mwidget_decl { std::shared_ptr widget_; }; -#define mslot(type) +type::slot_type() +#define mslot(type) type::slot_type() #define mnew(type, ...) mwidget_decl(__VA_ARGS__) <<= mwidget_slot_guard()