消除警告

This commit is contained in:
2025-04-21 23:29:13 +08:00
parent 21a12b257f
commit 057967a5c9
18 changed files with 776 additions and 852 deletions

View File

@@ -23,7 +23,7 @@ add_definitions(-DMIRAGE_HDR_FORMAT=${MIRAGE_HDR_FORMAT} -DMIRAGE_PIXEL_FORMAT=$
# CMAKE_CURRENT_SOURCE_DIR 在根 CMakeLists.txt 中即为项目源代码的根目录
# 使用 PARENT_SCOPE 使该变量在调用此函数的 CMakeLists.txt 文件中也可用
set(MIRAGE_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
message(STATUS "mirage 项目根源目录 MIRAGE_ROOT_DIR 设置为: ${MIRAGE_ROOT_DIR}")
message(STATUS "mirage 项目根源目录 (MIRAGE_ROOT_DIR) 设置为: ${MIRAGE_ROOT_DIR}")
include(cmake/retrieve_files.cmake)
include(cmake/detect_os.cmake)

View File

@@ -12,22 +12,76 @@ file(REMOVE ${SHADER_PATH_FILE})
file(WRITE ${SHADER_PATH_FILE} "")
# 添加着色器目录的函数
# 参数:
# path: 要添加的包含 .slang 着色器文件的目录路径
# 功能:
# 1. 将路径转换为适合目标系统的格式 (特别是处理 Cygwin)。
# 2. 将路径追加到 SHADER_PATH_FILE 指定的文件中。
# 3. 查找指定路径下的所有 .slang 文件。
# 4. 将找到的 .slang 文件添加为 CMake 配置的依赖项,
# 以便在这些文件更改时触发重新配置。
# 注意:
# - 需要在使用此函数前定义 CMAKE_BINARY_DIR 和 SHADER_PATH_FILE 变量。
# 例如: set(SHADER_PATH_FILE ${CMAKE_BINARY_DIR}/shader_paths.txt)
# - 假定 SHADER_PATH_FILE 的使用者期望接收适合其环境的路径格式
# (此处在 Cygwin 下转换为 Windows 格式)。
function(add_mirage_shader_directory path)
# 将路径写入shader_paths.txt
file(APPEND ${SHADER_PATH_FILE} "${path}\n")
# 检查 SHADER_PATH_FILE 变量是否已定义
if(NOT DEFINED SHADER_PATH_FILE)
message(FATAL_ERROR "**错误**: SHADER_PATH_FILE 变量未定义。请在使用 add_mirage_shader_directory 前设置此变量。")
endif()
# 观察目录文件是否修改, 触发compile_shaders目标重新编译
file(GLOB_RECURSE SHADER_FILES "${path}/*.slang")
# 获取绝对路径以确保一致性
get_filename_component(abs_path ${path} ABSOLUTE)
# 设置依赖关系当shader文件变化时重新编译
# 保存用于文件操作和写入文件的路径变量
set(path_to_write ${abs_path})
# 如果是cygwin环境, 需要转换路径为Windows格式
if (CYGWIN)
message(STATUS "检测到 Cygwin 环境,尝试使用 cygpath 转换路径: ${abs_path}")
# **关键点**: 使用 cygpath -w 将 Cygwin 路径转换为 Windows 路径
execute_process(
COMMAND cygpath -w ${abs_path}
OUTPUT_VARIABLE path_windows
OUTPUT_STRIP_TRAILING_WHITESPACE # 去除可能的尾随空格
RESULT_VARIABLE cygpath_result
ERROR_QUIET # 如果 cygpath 不存在或失败,则不显示错误,但检查 result
)
if(cygpath_result EQUAL 0 AND path_windows) # 检查 cygpath 是否成功执行并有输出
# 更新用于写入文件的路径
set(path_to_write ${path_windows})
message(STATUS "路径已成功转换为 Windows 格式: ${path_to_write}")
else()
# 如果 cygpath 失败或未找到,发出警告,并回退到原始路径
message(WARNING "无法使用 cygpath 转换路径 ${abs_path}。将使用原始路径。请确保 cygpath 在系统 PATH 中。")
# path_to_write 保持为 abs_path
endif()
endif()
# 将可能已转换的路径写入shader_paths.txt
# **关键点**: 追加路径到 ${SHADER_PATH_FILE}
file(APPEND ${SHADER_PATH_FILE} "${path_to_write}\n")
# 查找目录下的所有 .slang 文件,包括子目录
# **关键点**: 递归查找 ${abs_path} 目录下的 *.slang 文件
file(GLOB_RECURSE SHADER_FILES LIST_DIRECTORIES false "${abs_path}/*.slang")
# 设置依赖关系当shader文件变化时重新运行CMake配置
# **关键点**: 将着色器文件添加为 CMake 配置依赖项
foreach(SHADER_FILE ${SHADER_FILES})
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${SHADER_FILE})
get_filename_component(ABS_SHADER_FILE ${SHADER_FILE} ABSOLUTE)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${ABS_SHADER_FILE})
endforeach()
# **关键点**: 输出状态消息,告知用户已添加目录
message(STATUS "添加着色器源文件目录: ${path_to_write}")
endfunction()
set(SHADER_COMPILE_ARGS "")
set(SHADER_SHDC "")
if (WIN32)
if (WIN32 OR CYGWIN)
list(APPEND SHADER_COMPILE_ARGS "--hlsl")
set(SHADER_SHDC ${MIRAGE_ROOT_DIR}/tools/win_mirage_shdc.exe)
elseif (APPLE)
@@ -38,6 +92,8 @@ else()
set(SHADER_SHDC ${MIRAGE_ROOT_DIR}/tools/linux_mirage_shdc)
endif()
message(STATUS "使用着色器编译器: ${SHADER_SHDC}")
# 如果是Debug模式, 添加--debug选项
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND SHADER_COMPILE_ARGS "--debug")
@@ -53,7 +109,7 @@ add_custom_target(compile_shaders ALL
VERBATIM
)
# 定义一个,将编译着色器作为其他目标的依赖
# 定义一个函数,将编译着色器作为其他目标的依赖
function(add_shader_dependencies target)
add_dependencies(${target} compile_shaders)
endfunction()

View File

@@ -1,73 +1,131 @@
# DetectOS.cmake
# 定义一个函数,为指定的目标添加操作系统和架构相关的预处理器定义
function(add_os_definitions target)
# 初始化所有平台宏为 0
set(PLATFORMS MIRAGE_PLATFORM_WINDOWS MIRAGE_PLATFORM_MACOS MIRAGE_PLATFORM_LINUX MIRAGE_PLATFORM_FREEBSD MIRAGE_PLATFORM_IOS MIRAGE_PLATFORM_ANDROID)
# 检查 target 参数是否提供
if(NOT target)
message(FATAL_ERROR "函数 add_os_definitions 需要一个 target 参数。")
return()
endif()
# 检测操作系统并设置相应的宏为 1
if(WIN32)
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_WINDOWS=1)
message(STATUS "检测到 Windows 操作系统")
list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_WINDOWS)
elseif(APPLE AND NOT IOS)
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_MACOS=1)
message(STATUS "检测到 macOS 操作系统")
list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_MACOS)
elseif(UNIX)
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_LINUX=1)
message(STATUS "检测到 Linux 操作系统")
list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_LINUX)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_FREEBSD=1)
message(STATUS "检测到 FreeBSD 操作系统")
list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_FREEBSD)
else()
message(WARNING "检测到未知的 类Unix 操作系统")
endif()
# --- 阶段 1: 确定宏的值 ---
# 初始化所有平台、架构和特性宏的值为 0
set(mirage_def_windows 0)
set(mirage_def_macos 0)
set(mirage_def_linux 0)
set(mirage_def_freebsd 0)
set(mirage_def_ios 0)
set(mirage_def_android 0)
set(mirage_def_cygwin 0)
set(mirage_def_unix 0)
set(mirage_def_posix 0)
set(mirage_def_mobile 0)
set(mirage_def_arch_64bit 0)
set(mirage_def_arch_32bit 0)
# -- 操作系统检测与赋值 --
# 注意检测顺序:优先检测更具体的平台
if(CYGWIN)
# Cygwin 环境比较特殊,它在 Windows 上模拟 Unix
set(mirage_def_windows 1) # 基础是 Windows
set(mirage_def_cygwin 1) # 明确是 Cygwin
set(mirage_def_unix 1) # 提供 Unix API
set(mirage_def_posix 1) # 提供 POSIX API
message(STATUS "检测到 **Cygwin** 环境 (运行于 Windows)")
elseif(WIN32)
# 非 Cygwin 的 Windows 环境 (MSVC, MinGW, etc.)
set(mirage_def_windows 1)
message(STATUS "检测到 **Windows** 操作系统 (非 Cygwin)")
elseif(ANDROID)
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_ANDROID=1)
message(STATUS "检测到 Android 操作系统")
list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_ANDROID)
# Android 平台 (通常需要特定工具链设置 ANDROID 变量)
set(mirage_def_android 1)
set(mirage_def_unix 1) # Android NDK 基于 Unix
set(mirage_def_posix 1) # NDK 提供 POSIX API
set(mirage_def_mobile 1) # 移动平台
message(STATUS "检测到 **Android** 操作系统")
elseif(IOS)
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_IOS=1)
message(STATUS "检测到 iOS 操作系统")
list(REMOVE_ITEM PLATFORMS MIRAGE_PLATFORM_IOS)
# iOS 平台 (通常需要特定工具链设置 IOS 变量)
# 需要在 APPLE 之前判断,因为 iOS 下 APPLE 也为 TRUE
set(mirage_def_ios 1)
set(mirage_def_unix 1) # iOS (Darwin) 基于 Unix
set(mirage_def_posix 1) # 提供 POSIX API
set(mirage_def_mobile 1) # 移动平台
message(STATUS "检测到 **iOS** 操作系统")
elseif(APPLE)
# 此时排除了 iOS确定是 macOS
set(mirage_def_macos 1)
set(mirage_def_unix 1) # macOS (Darwin) 基于 Unix
set(mirage_def_posix 1) # 提供 POSIX API
message(STATUS "检测到 **macOS** 操作系统")
elseif(UNIX)
# 此时排除了 Apple, Android, Cygwin 的其他 Unix-like 系统
set(mirage_def_unix 1)
set(mirage_def_posix 1)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(mirage_def_linux 1)
message(STATUS "检测到 **Linux** 操作系统")
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
set(mirage_def_freebsd 1)
message(STATUS "检测到 **FreeBSD** 操作系统")
else()
message(WARNING "检测到未知的 类Unix 操作系统: ${CMAKE_SYSTEM_NAME}")
endif()
else()
message(WARNING "检测到未知的操作系统")
message(WARNING "检测到未知的操作系统: ${CMAKE_SYSTEM_NAME}")
endif()
foreach(PLATFORM ${PLATFORMS})
target_compile_definitions(${target} PUBLIC ${PLATFORM}=0)
endforeach()
# 检测并设置架构宏
# -- 架构检测与赋值 --
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_ARCH_64BIT=1 MIRAGE_PLATFORM_ARCH_32BIT=0)
message(STATUS "检测到 64-bit 架构")
set(mirage_def_arch_64bit 1)
set(mirage_def_arch_32bit 0) # 明确设置为 0
message(STATUS "检测到 **64-bit** 架构")
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(mirage_def_arch_64bit 0) # 明确设置为 0
set(mirage_def_arch_32bit 1)
message(STATUS "检测到 **32-bit** 架构")
else()
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_ARCH_64BIT=0 MIRAGE_PLATFORM_ARCH_32BIT=1)
message(STATUS "检测到 32-bit 架构")
# 对于未知或未定义的指针大小,两者都保持 0
message(WARNING "无法明确检测到 32-bit 或 64-bit 架构 (CMAKE_SIZEOF_VOID_P = ${CMAKE_SIZEOF_VOID_P})。将两者都设置为 0。")
endif()
# 设置通用的 UNIX 宏
if(UNIX)
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_UNIX=1)
else()
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_UNIX=0)
# --- 阶段 2: 组装定义列表 ---
set(definitions_list "") # 初始化空列表
# 添加平台定义
list(APPEND definitions_list "MIRAGE_PLATFORM_WINDOWS=${mirage_def_windows}")
list(APPEND definitions_list "MIRAGE_PLATFORM_MACOS=${mirage_def_macos}")
list(APPEND definitions_list "MIRAGE_PLATFORM_LINUX=${mirage_def_linux}")
list(APPEND definitions_list "MIRAGE_PLATFORM_FREEBSD=${mirage_def_freebsd}")
list(APPEND definitions_list "MIRAGE_PLATFORM_IOS=${mirage_def_ios}")
list(APPEND definitions_list "MIRAGE_PLATFORM_ANDROID=${mirage_def_android}")
list(APPEND definitions_list "MIRAGE_PLATFORM_CYGWIN=${mirage_def_cygwin}")
# 添加架构定义
list(APPEND definitions_list "MIRAGE_PLATFORM_ARCH_64BIT=${mirage_def_arch_64bit}")
list(APPEND definitions_list "MIRAGE_PLATFORM_ARCH_32BIT=${mirage_def_arch_32bit}")
# 添加特性定义
list(APPEND definitions_list "MIRAGE_PLATFORM_UNIX=${mirage_def_unix}")
list(APPEND definitions_list "MIRAGE_PLATFORM_POSIX=${mirage_def_posix}")
list(APPEND definitions_list "MIRAGE_PLATFORM_IS_MOBILE=${mirage_def_mobile}")
# --- 阶段 3: 应用所有定义 ---
# **关键:使用一次调用将所有定义添加到目标**
if(definitions_list) # 确保列表非空
target_compile_definitions(${target} PUBLIC ${definitions_list})
endif()
# 设置通用的 POSIX 宏
if(UNIX OR APPLE)
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_POSIX=1)
else()
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_POSIX=0)
endif()
# 函数作用域结束时mirage_def_* 变量会自动销毁,无需显式 unset
# 设置IS_MOBILE宏
if(ANDROID OR IOS)
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_IS_MOBILE=1)
else()
target_compile_definitions(${target} PUBLIC MIRAGE_PLATFORM_IS_MOBILE=0)
endif()
endfunction()
# --- 使用示例 ---
# project(MyProject)
# add_executable(my_app main.c)
#
# # 调用函数为 my_app 添加平台定义
# add_os_definitions(my_app)
#
# # 你也可以为库调用
# # add_library(my_lib STATIC my_lib.c)
# # add_os_definitions(my_lib)

View File

@@ -1,56 +1,85 @@
# 函数:设置 C++ 标准及相关编译选项
# 参数 standard: 需要设置的 C++ 标准版本 (例如 11, 14, 17, 20, 23)
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}")
# --- 参数验证 ---
set(VALID_STANDARDS 11 14 17 20 23) # 定义支持的 C++ 标准列表
list(FIND VALID_STANDARDS ${standard} _standard_index) # 查找 standard 是否在列表中
if(_standard_index EQUAL -1) # 如果未找到
message(WARNING "**非标准 C++ 版本**: ${standard}。支持的版本有: ${VALID_STANDARDS}")
# 可选:可以设置为一个默认值或停止配置
# message(FATAL_ERROR "不支持的 C++ 标准: ${standard}")
# set(standard 17) # 或者设置为默认值,例如 C++17
# message(WARNING "已将 C++ 标准设置为默认值: ${standard}")
endif()
# 指定需要的 C++ 标准,设置到父作用域
# --- 设置 C++ 标准 ---
# 指定需要的 C++ 标准,设置到父作用域,使其对调用者定义的 target 生效
set(CMAKE_CXX_STANDARD ${standard} PARENT_SCOPE)
# 强制要求此标准,如果编译器不支持则配置时报错
# **强制要求此标准**,如果编译器不支持则配置时报错
set(CMAKE_CXX_STANDARD_REQUIRED ON PARENT_SCOPE)
# 可选:禁用编译器特定的扩展,使用纯粹的标准
# **禁用编译器特定的扩展**,使用纯粹的标准 C++
set(CMAKE_CXX_EXTENSIONS OFF PARENT_SCOPE)
# --- 平台特定设置 ---
if(WIN32)
# 定义Windows版本
# Windows 定义 UNICODE
add_definitions(-DUNICODE -D_UNICODE)
# 可选:添加 WIN32_LEAN_AND_MEAN 以减少 Windows 头文件包含
# 可选:添加 WIN32_LEAN_AND_MEAN 以减少 Windows 头文件包含,加快编译速度
# add_definitions(-DWIN32_LEAN_AND_MEAN)
message(STATUS "为 Windows 添加 UNICODE 定义")
endif()
# --- 编译器特定设置 ---
if(MSVC)
# 设置utf-8编码
# **设置源代码和执行字符集为 UTF-8**
add_compile_options(/utf-8)
# 强制 MSVC 正确设置 __cplusplus 宏
# **强制 MSVC 正确设置 __cplusplus 宏**,以便代码能准确判断 C++ 标准
add_compile_options(/Zc:__cplusplus)
# 可选:增加 MSVC 警告级别
# **设置警告级别为 W4** (较高警告级别)
add_compile_options(/W4)
# **禁用未使用的形参警告 (C4100)**
# **禁用特定警告C4100 未使用的形参** (有时用于接口兼容性)
add_compile_options(/wd4100)
# 禁用特定警告C4996 使用了被标记为否决的函数或变量 (例如一些旧的 CRT 函数)
add_compile_options(/wd4996)
message(STATUS "为 MSVC 添加特定编译选项: /utf-8 /Zc:__cplusplus /W4 /wd4100 /wd4996")
endif()
# GCC/Clang 特定选项
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# **启用常用警告**
add_compile_options(-Wall -Wextra)
# 禁用未使用参数的警告
# **禁用未使用参数的警告** (与 MSVC 的 /wd4100 对应)
add_compile_options(-Wno-unused-parameter)
# 根据 C++ 标准添加特定选项
if(${standard} GREATER 14) # 更兼容的写法,避免使用 GREATER_EQUAL
# **设置输入和执行字符集为 UTF-8** (对应 MSVC 的 /utf-8)
# 这有助于处理源代码中的 UTF-8 字符,并影响运行时字符编码,但控制台本身的显示需要环境配合
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -finput-charset=UTF-8 -fexec-charset=UTF-8")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -finput-charset=UTF-8 -fexec-charset=UTF-8")
# 根据 C++ 标准添加特定警告 (C++17 及以上)
if(${standard} GREATER 14)
# **启用阴影变量警告和非虚析构函数警告**
add_compile_options(-Wshadow -Wnon-virtual-dtor)
message(STATUS "为 GCC/Clang (C++${CMAKE_CXX_STANDARD}) 添加额外警告: -Wshadow -Wnon-virtual-dtor")
endif()
message(STATUS "为 GCC/Clang 添加特定编译选项: -Wall -Wextra -Wno-unused-parameter -finput-charset=UTF-8 -fexec-charset=UTF-8")
# 注意: 控制台/终端的 UTF-8 输出显示通常还需要操作系统环境的配合 (例如 Linux/macOS 终端本身设置Windows下 chcp 65001)
endif()
# 如果是MinGW, 并且使用了C++17或更高版本, 则添加libstdc++exp库
# MinGW 特定设置 (通常在 Windows 上使用 GCC 工具链)
if(MINGW)
message(STATUS "检测到MinGW编译器")
# 更兼容的版本比较
if(${standard} GREATER 14) # C++17及以上
message(STATUS "为C++${standard}添加libstdc++exp库支持")
link_libraries(-lstdc++exp)
message(STATUS "检测到 MinGW 编译器")
# 如果使用了 C++17 或更高版本, 可能需要链接 libstdc++exp 以支持 <filesystem> 等特性
if(${standard} GREATER 14)
message(STATUS "**为 MinGW C++${CMAKE_CXX_STANDARD} 添加 libstdc++fs 库依赖** (用于 <filesystem>)")
# 注意:较新版本的 MinGW 可能不再需要显式链接,或者需要链接的是 -lstdc++fs
# link_libraries() 会影响后续所有 target更推荐使用 target_link_libraries()
# 这里暂时保留 link_libraries(),但建议后续根据具体 target 调整
# 尝试链接 stdc++fs这在较新的 MinGW 中更常见用于 <filesystem>
link_libraries(-lstdc++fs)
# 如果链接 -lstdc++fs 失败,可以尝试回退到 -lstdc++exp
# link_libraries(-lstdc++exp)
endif()
endif()
message(STATUS "已设置C++${standard}标准")
message(STATUS "**C++ 标准已设置为: c++${standard}**")
endfunction()

View File

@@ -314,4 +314,3 @@ function(add_resource_file)
endif()
endfunction()

View File

@@ -1,6 +1,4 @@
#pragma once
#include <mutex>
#include "misc/mirage_type.h"
#include "render/render_context.h"

View File

@@ -14,7 +14,7 @@
*
* 示例用法: auto angle = 45.5_deg;
*/
consteval auto operator"" _deg(const long double in_degree) {
consteval auto operator""_deg(const long double in_degree) {
return in_degree * 3.1415926 / 180.0;
}
@@ -25,6 +25,6 @@ consteval auto operator"" _deg(const long double in_degree) {
*
* 示例用法: auto angle = 90_deg;
*/
consteval auto operator"" _deg(const unsigned long long in_degree) {
return in_degree * 3.1415926 / 180.0;
consteval auto operator""_deg(const unsigned long long in_degree) {
return static_cast<double>(in_degree) * 3.1415926 / 180.0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -64,7 +64,7 @@ mapped_file_unix& mapped_file_unix::operator=(mapped_file_unix&& other) noexcept
bool mapped_file_unix::map_file(const std::filesystem::path& filename) {
cleanup();
std::string utf8_filename(filename.begin(), filename.end());
const std::string& utf8_filename = filename.string();
fd = open(utf8_filename.c_str(), O_RDONLY);
if (fd == -1) {
// 无法打开文件

View File

@@ -71,7 +71,7 @@ mapped_file_win& mapped_file_win::operator=(mapped_file_win&& other) noexcept {
bool mapped_file_win::map_file(const std::filesystem::path& filename) {
cleanup();
file_handle_ = CreateFileW(
file_handle_ = CreateFile(
filename.c_str(),
GENERIC_READ,
FILE_SHARE_READ,

View File

@@ -113,7 +113,7 @@ enum class flow_direction_preference_t {
/**
* @brief 全局默认流动方向设置
*/
inline static auto g_flow_direction = flow_direction_t::left_to_right;
// inline static auto g_flow_direction = flow_direction_t::left_to_right;
//-------------- 几何和渲染结构体 --------------
@@ -304,16 +304,16 @@ struct mirage_vertex_param_t {
/**
* @brief 两容器构造函数 - 从两个容器构造前两个元素到x,y后两个元素到z,w
* @param a 第一个容器提供x和y分量
* @param b 第二个容器提供z和w分量
* @param in_a 第一个容器提供x和y分量
* @param in_b 第二个容器提供z和w分量
*/
template<typename A, typename B,
typename = decltype(std::declval<A>()[0]),
typename = decltype(std::declval<B>()[0])>
mirage_vertex_param_t(const A& a, const B& b) : x(static_cast<float>(a[0])),
y(static_cast<float>(a[1])),
z(static_cast<float>(b[0])),
w(static_cast<float>(b[1])) {
mirage_vertex_param_t(const A& in_a, const B& in_b) : x(static_cast<float>(in_a[0])),
y(static_cast<float>(in_a[1])),
z(static_cast<float>(in_b[0])),
w(static_cast<float>(in_b[1])) {
}
//-------------- 辅助类型特征检测 --------------

View File

@@ -49,11 +49,11 @@ struct char_key_t {
template<>
struct std::hash<char_key_t> {
size_t operator()(const char_key_t& in_key) const {
std::hash<uint32_t> hash_fn;
size_t hash = hash_fn(in_key.glyph_index);
hash ^= (uint64_t)in_key.font_face.get();
hash ^= std::hash<float>{}(in_key.font_size);
return hash;
constexpr std::hash<uint32_t> hash_fn;
size_t hash_key = hash_fn(in_key.glyph_index);
hash_key ^= reinterpret_cast<uint64_t>(in_key.font_face.get());
hash_key ^= std::hash<float>{}(in_key.font_size);
return hash_key;
}
};

View File

@@ -11,11 +11,7 @@ bool mouse_tracking_ = FALSE;
std::vector<platform_window*> windows;
platform_window* get_window_from_hwnd(const HWND hwnd) {
for (const auto& window: windows) {
if (window->get_window_handle() == hwnd) {
return window;
}
}
for (const auto& window: windows) { if (window->get_window_handle() == hwnd) { return window; } }
return nullptr;
}
@@ -23,13 +19,14 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
bool processed = false;
// 窗口关闭事件
if (uMsg == WM_CLOSE) {
std::erase_if(windows, [hwnd](platform_window* window) {
if (window->get_window_handle() == hwnd) {
window->close();
return true;
}
return false;
});
std::erase_if(windows,
[hwnd](platform_window* window) {
if (window->get_window_handle() == hwnd) {
window->close();
return true;
}
return false;
});
processed = true;
}
@@ -41,7 +38,9 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
// 窗口移动事件
if (uMsg == WM_MOVE) {
if (const auto window = get_window_from_hwnd(hwnd)) { window->on_move(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); }
if (const auto window = get_window_from_hwnd(hwnd)) {
window->on_move(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
}
processed = true;
}
@@ -56,16 +55,16 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
// 鼠标移动事件
if (uMsg == WM_MOUSEMOVE) {
if (const auto window = get_window_from_hwnd(hwnd)) {
const int x = GET_X_LPARAM(lParam);
const int y = GET_Y_LPARAM(lParam);
const int x = GET_X_LPARAM(lParam);
const int y = GET_Y_LPARAM(lParam);
const Eigen::Vector2f pos(static_cast<float>(x), static_cast<float>(y));
window->handle_mouse_move(pos);
}
if (!mouse_tracking_) {
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hwnd;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hwnd;
tme.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&tme);
mouse_tracking_ = TRUE;
@@ -75,14 +74,14 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
// 鼠标按键事件
const auto lmr_button = uMsg >= WM_LBUTTONDOWN && uMsg <= WM_MBUTTONDBLCLK;
const auto x_button = uMsg >= WM_XBUTTONDOWN && uMsg <= WM_XBUTTONDBLCLK;
const auto x_button = uMsg >= WM_XBUTTONDOWN && uMsg <= WM_XBUTTONDBLCLK;
if (lmr_button || x_button) {
if (const auto window = get_window_from_hwnd(hwnd)) {
const int x = GET_X_LPARAM(lParam);
const int y = GET_Y_LPARAM(lParam);
const int x = GET_X_LPARAM(lParam);
const int y = GET_Y_LPARAM(lParam);
const Eigen::Vector2f pos(static_cast<float>(x), static_cast<float>(y));
const auto action = platform_event_to_mouse_action(uMsg, wParam);
const auto button = platform_event_to_mouse_button(uMsg, wParam);
const auto action = platform_event_to_mouse_action(uMsg, wParam);
const auto button = platform_event_to_mouse_button(uMsg, wParam);
if (action == mouse_action::press)
window->handle_mouse_button_down(pos, button);
else if (action == mouse_action::release)
@@ -96,9 +95,9 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
// 鼠标滚轮事件
if (uMsg == WM_MOUSEWHEEL || uMsg == WM_MOUSEHWHEEL) {
if (const auto window = get_window_from_hwnd(hwnd)) {
const int x = GET_X_LPARAM(lParam);
const int y = GET_Y_LPARAM(lParam);
POINT screen_point = { x, y };
const int x = GET_X_LPARAM(lParam);
const int y = GET_Y_LPARAM(lParam);
POINT screen_point = { x, y };
ScreenToClient(hwnd, &screen_point);
// 现在 screen_point.x 和 screen_point.y 包含相对于窗口客户区的坐标
@@ -113,9 +112,7 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (uMsg == WM_MOUSELEAVE) {
mouse_tracking_ = FALSE;
if (const auto window = get_window_from_hwnd(hwnd)) {
window->handle_mouse_leave();
}
if (const auto window = get_window_from_hwnd(hwnd)) { window->handle_mouse_leave(); }
processed = true;
}
@@ -136,13 +133,19 @@ platform_window::platform_window(int32_t in_width, int32_t in_height, const wcha
RECT rect = { 0, 0, in_width, in_height };
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
window_handle_ = (void*)CreateWindowW(
L"mirage_window_class", in_title,
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
rect.right - rect.left, rect.bottom - rect.top,
NULL, NULL, GetModuleHandleW(NULL), NULL
);
window_handle_ = static_cast<void*>(CreateWindowW(
L"mirage_window_class",
in_title,
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
rect.right - rect.left,
rect.bottom - rect.top,
nullptr,
nullptr,
GetModuleHandleW(nullptr),
nullptr
));
if (!window_handle_) {
std::cerr << "Failed to create window" << std::endl;
@@ -190,9 +193,9 @@ Eigen::Vector2i platform_window::get_window_size() const {
if (GetWindowRect(WINDOW_HANDLE, &rect)) {
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
return Eigen::Vector2i(width, height);
return { width, height };
}
return Eigen::Vector2i(0, 0);
return { 0, 0 };
}
Eigen::Vector2i platform_window::get_window_frame_size() const {
@@ -201,14 +204,12 @@ Eigen::Vector2i platform_window::get_window_frame_size() const {
if (GetClientRect(WINDOW_HANDLE, &rect)) {
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
return Eigen::Vector2i(width, height);
return { width, height };
}
return Eigen::Vector2i(0, 0);
return { 0, 0 };
}
float platform_window::get_window_dpi_scale() const {
return 1.f;
}
float platform_window::get_window_dpi_scale() const { return 1.f; }
Eigen::Vector2i platform_window::get_window_position() const {
RECT rect;
@@ -219,55 +220,62 @@ Eigen::Vector2i platform_window::get_window_position() const {
void* platform_window::get_window_handle() const { return window_handle_; }
platform_window& platform_window::set_title(const wchar_t* title) {
SetWindowText(WINDOW_HANDLE, title);
SetWindowTextW(WINDOW_HANDLE, title);
return *this;
}
platform_window& platform_window::set_has_minimize_button(bool has_minimize_button) {
auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE);
if (has_minimize_button) { style |= WS_MINIMIZEBOX; } else { style &= ~WS_MINIMIZEBOX; }
if (has_minimize_button) { style |= WS_MINIMIZEBOX; }
else { style &= ~WS_MINIMIZEBOX; }
SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style);
return *this;
}
platform_window& platform_window::set_has_maximize_button(bool has_maximize_button) {
auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE);
if (has_maximize_button) { style |= WS_MAXIMIZEBOX; } else { style &= ~WS_MAXIMIZEBOX; }
if (has_maximize_button) { style |= WS_MAXIMIZEBOX; }
else { style &= ~WS_MAXIMIZEBOX; }
SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style);
return *this;
}
platform_window& platform_window::set_has_close_button(bool has_close_button) {
auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE);
if (has_close_button) { style |= WS_SYSMENU; } else { style &= ~WS_SYSMENU; }
if (has_close_button) { style |= WS_SYSMENU; }
else { style &= ~WS_SYSMENU; }
SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style);
return *this;
}
platform_window& platform_window::set_has_border(bool has_border) {
auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE);
if (has_border) { style |= WS_BORDER; } else { style &= ~WS_BORDER; }
if (has_border) { style |= WS_BORDER; }
else { style &= ~WS_BORDER; }
SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style);
return *this;
}
platform_window& platform_window::set_has_caption(bool has_caption) {
auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE);
if (has_caption) { style |= WS_CAPTION; } else { style &= ~WS_CAPTION; }
if (has_caption) { style |= WS_CAPTION; }
else { style &= ~WS_CAPTION; }
SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style);
return *this;
}
platform_window& platform_window::set_has_resizable_border(bool has_resizable_border) {
auto style = GetWindowLong(WINDOW_HANDLE, GWL_STYLE);
if (has_resizable_border) { style |= WS_THICKFRAME; } else { style &= ~WS_THICKFRAME; }
if (has_resizable_border) { style |= WS_THICKFRAME; }
else { style &= ~WS_THICKFRAME; }
SetWindowLong(WINDOW_HANDLE, GWL_STYLE, style);
return *this;
}
platform_window& platform_window::set_topmost(bool is_topmost) {
auto style = GetWindowLong(WINDOW_HANDLE, GWL_EXSTYLE);
if (is_topmost) { style |= WS_EX_TOPMOST; } else { style &= ~WS_EX_TOPMOST; }
if (is_topmost) { style |= WS_EX_TOPMOST; }
else { style &= ~WS_EX_TOPMOST; }
SetWindowLong(WINDOW_HANDLE, GWL_EXSTYLE, style);
return *this;
}

View File

@@ -11,197 +11,201 @@
#include "windows_render_state.h"
bool windows_mirage_render_context::init() {
try {
// 定义支持的特性级别(从高到低排序)
D3D_FEATURE_LEVEL feature_levels[] = {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
try {
// 定义支持的特性级别(从高到低排序)
D3D_FEATURE_LEVEL feature_levels[] = {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
// 设置设备创建标志
// UINT device_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_SINGLETHREADED; // BGRA支持和单线程模式
UINT device_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; // BGRA支持和单线程模式
// 设置设备创建标志
// UINT device_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_SINGLETHREADED; // BGRA支持和单线程模式
UINT device_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; // BGRA支持和单线程模式
#if DEBUG
device_flags |= D3D11_CREATE_DEVICE_DEBUG; // 在Debug模式下启用调试层
device_flags |= D3D11_CREATE_DEVICE_DEBUG; // 在Debug模式下启用调试层
#endif
// 定义要尝试的驱动类型数组
constexpr D3D_DRIVER_TYPE driver_types[] = {
D3D_DRIVER_TYPE_HARDWARE, // 首选硬件加速
D3D_DRIVER_TYPE_WARP, // 其次是WARP软件渲染器
D3D_DRIVER_TYPE_REFERENCE // 最后是参考软件渲染器
};
// 定义要尝试的驱动类型数组
constexpr D3D_DRIVER_TYPE driver_types[] = {
D3D_DRIVER_TYPE_HARDWARE, // 首选硬件加速
D3D_DRIVER_TYPE_WARP, // 其次是WARP软件渲染器
D3D_DRIVER_TYPE_REFERENCE // 最后是参考软件渲染器
};
// 尝试按优先级创建设备
HRESULT hr = E_FAIL;
D3D_DRIVER_TYPE used_driver_type = D3D_DRIVER_TYPE_UNKNOWN;
SetProcessDPIAware();
// 尝试按优先级创建设备
HRESULT hr = E_FAIL;
D3D_DRIVER_TYPE used_driver_type = D3D_DRIVER_TYPE_UNKNOWN;
SetProcessDPIAware();
for (const auto& driver_type : driver_types) {
hr = D3D11CreateDevice(
nullptr, // 使用默认适配器
driver_type, // 驱动类型
nullptr, // 软件栅格化模块句柄(仅用于软件设备)
device_flags, // 设备创建标志
feature_levels, // 特性级别数组
ARRAYSIZE(feature_levels), // 特性级别数量
D3D11_SDK_VERSION, // SDK版本
&device, // 输出设备
&feature_level, // 输出获取的特性级别
&device_context // 输出设备上下文
);
for (const auto& driver_type: driver_types) {
hr = D3D11CreateDevice(
nullptr,
// 使用默认适配器
driver_type,
// 驱动类型
nullptr,
// 软件栅格化模块句柄(仅用于软件设备)
device_flags,
// 设备创建标志
feature_levels,
// 特性级别数组
std::size(feature_levels),
// 特性级别数量
D3D11_SDK_VERSION,
// SDK版本
&device,
// 输出设备
&feature_level,
// 输出获取的特性级别
&device_context // 输出设备上下文
);
if (SUCCEEDED(hr)) {
used_driver_type = driver_type;
break;
}
}
if (SUCCEEDED(hr)) {
used_driver_type = driver_type;
break;
}
}
// 检查是否成功创建设备
if (FAILED(hr)) {
std::println(std::cerr, "mirage: 所有的 D3D11 设备类型都创建失败. HRESULT: 0x{:#06x}", hr);
cleanup();
return false;
}
// 检查是否成功创建设备
if (FAILED(hr)) {
std::println(std::cerr, "mirage: 所有的 D3D11 设备类型都创建失败. HRESULT: 0x{:#06x}", hr);
cleanup();
return false;
}
// **获取DXGI设备以访问适配器**
IDXGIDevice* dxgi_device = nullptr;
hr = device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgi_device));
if (FAILED(hr)) {
std::println(std::cerr, "mirage: 获取 DXGI 设备失败. HRESULT: 0x{:#06x}", hr);
cleanup();
return false;
}
// **获取DXGI设备以访问适配器**
IDXGIDevice* dxgi_device = nullptr;
hr = device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgi_device));
if (FAILED(hr)) {
std::println(std::cerr, "mirage: 获取 DXGI 设备失败. HRESULT: 0x{:#06x}", hr);
cleanup();
return false;
}
// **获取适配器**
IDXGIAdapter* dxgi_adapter = nullptr;
hr = dxgi_device->GetAdapter(&dxgi_adapter);
dxgi_device->Release();
// **获取适配器**
IDXGIAdapter* dxgi_adapter = nullptr;
hr = dxgi_device->GetAdapter(&dxgi_adapter);
dxgi_device->Release();
if (FAILED(hr)) {
std::println(std::cerr, "mirage: 无法获取 DXGI 适配器. HRESULT: 0x{:#06x}", hr);
cleanup();
return false;
}
if (FAILED(hr)) {
std::println(std::cerr, "mirage: 无法获取 DXGI 适配器. HRESULT: 0x{:#06x}", hr);
cleanup();
return false;
}
// **获取适配器描述信息**
DXGI_ADAPTER_DESC adapter_desc;
hr = dxgi_adapter->GetDesc(&adapter_desc);
if (FAILED(hr)) {
std::println(std::cerr, "mirage: 无法获取 DXGI 适配器描述信息. HRESULT: 0x{:#06x}", hr);
}
// **获取适配器描述信息**
DXGI_ADAPTER_DESC adapter_desc;
hr = dxgi_adapter->GetDesc(&adapter_desc);
if (FAILED(hr)) { 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<void**>(&dxgi_factory));
if (SUCCEEDED(hr)) {
std::println(std::cout, "mirage: 使用 DXGI Factory6");
} else {
// 尝试Factory5 - Windows 10 Anniversary Update (1607)或更高版本
hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory5), reinterpret_cast<void**>(&dxgi_factory));
if (SUCCEEDED(hr)) {
std::println(std::cout, "mirage: 使用 DXGI Factory5");
} else {
// 尝试Factory4 - Windows 10初始版本
hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory4), reinterpret_cast<void**>(&dxgi_factory));
if (SUCCEEDED(hr)) {
std::println(std::cout, "mirage: 使用 DXGI Factory4");
} else {
// 尝试Factory3 - Windows 8.1
hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory3), reinterpret_cast<void**>(&dxgi_factory));
if (SUCCEEDED(hr)) {
std::println(std::cout, "mirage: 使用 DXGI Factory3");
} else {
// 尝试Factory2 - Windows 8支持FLIP模式交换链
hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgi_factory));
if (SUCCEEDED(hr)) {
std::println(std::cout, "mirage: 使用 DXGI Factory2");
} else {
// 回退到基本Factory1 - Windows 7
hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgi_factory));
if (SUCCEEDED(hr)) {
std::println(std::cout, "mirage: 使用 DXGI Factory1");
} else {
// 最后尝试原始Factory
hr = dxgi_adapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgi_factory));
if (SUCCEEDED(hr)) {
std::println(std::cout, "mirage: 使用 DXGI Factory");
} else {
std::println(std::cerr, "mirage: 无法获取 DXGI Factory. HRESULT: 0x{:#06x}", hr);
dxgi_adapter->Release();
cleanup();
return false;
}
}
}
}
}
}
}
struct dxgi_factory_func_data {
IID iid{};
std::string name;
};
#define DXGI_FUNC_DATA(dxgi_class) dxgi_factory_func_data{ __uuidof(dxgi_class), #dxgi_class }
const std::array func_datas = {
// **尝试获取最新的DXGI工厂版本 - 从最新的Factory6开始尝试**
// Windows 10 Fall Creators Update (1709)或更高版本支持
DXGI_FUNC_DATA(IDXGIFactory6),
// 尝试Factory5 - Windows 10 Anniversary Update (1607)或更高版本
DXGI_FUNC_DATA(IDXGIFactory5),
// 尝试Factory4 - Windows 10初始版本
DXGI_FUNC_DATA(IDXGIFactory4),
// 尝试Factory3 - Windows 8.1
DXGI_FUNC_DATA(IDXGIFactory3),
// 尝试Factory2 - Windows 8支持FLIP模式交换链
DXGI_FUNC_DATA(IDXGIFactory2),
// 回退到基本Factory1 - Windows 7
DXGI_FUNC_DATA(IDXGIFactory1),
// 最后尝试原始Factory
DXGI_FUNC_DATA(IDXGIFactory),
};
#undef DXGI_FUNC_DATA
// **检查是否支持撕裂(tearing)功能**
BOOL allow_tearing = FALSE;
// IDXGIFactory5及以上版本支持CheckFeatureSupport
IDXGIFactory5* factory5 = nullptr;
if (SUCCEEDED(dxgi_factory->QueryInterface(__uuidof(IDXGIFactory5), (void**)&factory5))) {
if (SUCCEEDED(factory5->CheckFeatureSupport(
DXGI_FEATURE_PRESENT_ALLOW_TEARING,
&allow_tearing,
sizeof(allow_tearing)))) {
std::println(std::cout, "mirage: 防撕裂支持: {}", (bool)allow_tearing);
}
factory5->Release();
}
tearing_supported = allow_tearing == TRUE;
// **获取DXGI工厂**
for (const auto& data: func_datas) {
hr = dxgi_adapter->GetParent(data.iid, reinterpret_cast<void**>(&dxgi_factory));
if (SUCCEEDED(hr)) {
std::println(std::cout, "mirage: 使用 {}", data.name);
break;
}
}
if (FAILED(hr)) {
std::println(std::cerr, "mirage: 无法获取 DXGI Factory. HRESULT: 0x{:#06x}", hr);
dxgi_adapter->Release();
cleanup();
return false;
}
dxgi_adapter->Release();
// **检查是否支持撕裂(tearing)功能**
BOOL allow_tearing = FALSE;
// IDXGIFactory5及以上版本支持CheckFeatureSupport
IDXGIFactory5* factory5 = nullptr;
if (SUCCEEDED(dxgi_factory->QueryInterface(__uuidof(IDXGIFactory5), (void**)&factory5))) {
if (SUCCEEDED(factory5->CheckFeatureSupport(
DXGI_FEATURE_PRESENT_ALLOW_TEARING,
&allow_tearing,
sizeof(allow_tearing)))) { std::println(std::cout, "mirage: 防撕裂支持: {}", (bool) allow_tearing); }
factory5->Release();
}
tearing_supported = allow_tearing == TRUE;
dxgi_adapter->Release();
// 输出初始化成功信息
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);
// 输出初始化成功信息
std::println(std::cout, "mirage: 成功创建 D3D11 设备");
{
const std::u16string adapter_desc_str(reinterpret_cast<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";
switch (used_driver_type) {
case D3D_DRIVER_TYPE_HARDWARE: driver_type_str = "Hardware";
break;
case D3D_DRIVER_TYPE_WARP: driver_type_str = "WARP";
break;
case D3D_DRIVER_TYPE_REFERENCE: driver_type_str = "Reference";
break;
default: ;
}
std::println(std::cout, "mirage: 使用驱动类型: {}", driver_type_str);
// 输出驱动类型信息
auto driver_type_str = "Unknown";
switch (used_driver_type) {
case D3D_DRIVER_TYPE_HARDWARE:
driver_type_str = "Hardware";
break;
case D3D_DRIVER_TYPE_WARP:
driver_type_str = "WARP";
break;
case D3D_DRIVER_TYPE_REFERENCE:
driver_type_str = "Reference";
break;
default: ;
}
std::println(std::cout, "mirage: 使用驱动类型: {}", driver_type_str);
// 输出特性级别信息
auto feature_level_str = "Unknown";
switch (feature_level) {
case D3D_FEATURE_LEVEL_11_1: feature_level_str = "11.1";
break;
case D3D_FEATURE_LEVEL_11_0: feature_level_str = "11.0";
break;
case D3D_FEATURE_LEVEL_10_1: feature_level_str = "10.1";
break;
case D3D_FEATURE_LEVEL_10_0: feature_level_str = "10.0";
break;
default: ;
}
std::println(std::cout, "mirage: 使用特性级别: {}", feature_level_str);
// 输出特性级别信息
auto feature_level_str = "Unknown";
switch (feature_level) {
case D3D_FEATURE_LEVEL_11_1:
feature_level_str = "11.1";
break;
case D3D_FEATURE_LEVEL_11_0:
feature_level_str = "11.0";
break;
case D3D_FEATURE_LEVEL_10_1:
feature_level_str = "10.1";
break;
case D3D_FEATURE_LEVEL_10_0:
feature_level_str = "10.0";
break;
default: ;
}
std::println(std::cout, "mirage: 使用特性级别: {}", feature_level_str);
return true;
} catch (const std::exception& e) {
std::println(std::cerr, "mirage: D3D11初始化失败: {}", e.what());
cleanup();
return false;
}
return true;
}
catch (const std::exception& e) {
std::println(std::cerr, "mirage: D3D11初始化失败: {}", e.what());
cleanup();
return false;
}
}
// 资源清理函数
@@ -224,19 +228,16 @@ void windows_mirage_render_context::cleanup() {
}
sg_environment windows_mirage_render_context::get_environment() {
return {
.d3d11 = {
.device = device,
.device_context = device_context
}
};
sg_environment env{};
env.d3d11.device = device;
env.d3d11.device_context = device_context;
return env;
}
std::unique_ptr<mirage_window_state> windows_mirage_render_context::create_window_state(const Eigen::Vector2i& in_window_frame_size, void* in_window_handle) {
std::unique_ptr<mirage_window_state> windows_mirage_render_context::create_window_state(
const Eigen::Vector2i& in_window_frame_size, void* in_window_handle) {
auto state = std::make_unique<windows_render_state>();
if (!state->init(device, dxgi_factory, in_window_frame_size, in_window_handle)) {
return {};
}
if (!state->init(device, dxgi_factory, in_window_frame_size, in_window_handle)) { return {}; }
return state;
}

View File

@@ -40,7 +40,7 @@ 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::println(std::cout, "点击 Button: {}, {}", in_position.x(), in_position.y());
color_ = normal_color_;
color_ = hover_color_;
invalidate(invalidate_reason::paint);
}
@@ -75,7 +75,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::println(std::cout, "鼠标释放 Button: {}, {}", in_position.x(), in_position.y());
color_ = normal_color_;
color_ = hover_color_;
invalidate(invalidate_reason::paint);
return hit_test_handle::handled();
}

View File

@@ -4,23 +4,23 @@
struct button_args {
WARG(linear_color, normal_color, linear_color(0.2f, 0.2f, 0.2f, 1))
WARG(linear_color, hover_color, linear_color(0.1f, 0.1f, 0.1f, 1))
WARG(linear_color, pressed_color, linear_color(0.1f, 0.1f, 0.1f, 1))
WARG(linear_color, pressed_color, linear_color(0.05f, 0.05f, 0.05f, 1))
};
class mbutton : public mborder<button_args> {
public:
mbutton();
virtual void init() override;
void init() override;
void setup_widget(const button_args& in_args) override;
virtual void on_paint(mirage_paint_context& in_context) override;
void on_paint(mirage_paint_context& in_context) override;
virtual void on_click(const Eigen::Vector2f& in_position, mouse_button in_button) override;
virtual void on_double_click(const Eigen::Vector2f& in_position, mouse_button in_button) override;
void on_click(const Eigen::Vector2f& in_position, mouse_button in_button) override;
void on_double_click(const Eigen::Vector2f& in_position, mouse_button in_button) override;
hit_test_handle on_mouse_move(const Eigen::Vector2f& in_position) override { return hit_test_handle::handled(); }
virtual void on_mouse_enter() override;
virtual void on_mouse_leave() override;
virtual hit_test_handle on_mouse_button_down(const Eigen::Vector2f& in_position, mouse_button in_button) override;
virtual hit_test_handle on_mouse_button_up(const Eigen::Vector2f& in_position, mouse_button in_button) override;
void on_mouse_enter() override;
void on_mouse_leave() override;
hit_test_handle on_mouse_button_down(const Eigen::Vector2f& in_position, mouse_button in_button) override;
hit_test_handle on_mouse_button_up(const Eigen::Vector2f& in_position, mouse_button in_button) override;
private:
linear_color normal_color_;
linear_color hover_color_;

View File

@@ -150,4 +150,4 @@ public:
auto& name(const type* in_value) { \
name##_ = *in_value; \
return *this; \
} \
}

View File

@@ -22,7 +22,7 @@
const auto& name() const { return name##_.value(); } \
auto has_##name() const { return name##_.has_value(); } \
protected: \
std::optional<type> name##_; \
std::optional<type> name##_;
#define SLOT_CONTENT() \
public: \
@@ -56,4 +56,4 @@
return size_; \
} \
protected: \
widget_size size_ = widget_size::auto_size();
widget_size size_ = widget_size::auto_size();