From 8a7ee7de462133304464f05466fb1819f7b8ee53 Mon Sep 17 00:00:00 2001 From: Nanako <469449812@qq.com> Date: Fri, 22 Nov 2024 17:12:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=80=E4=BA=9B=E8=BE=B9=E7=95=8C=E6=A3=80?= =?UTF-8?q?=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/backend/dx/dx_window.cpp | 6 +- src/renderer/core/pixel_format/pixel.h | 113 ++++++++++++++++++++++--- 2 files changed, 104 insertions(+), 15 deletions(-) diff --git a/src/renderer/backend/dx/dx_window.cpp b/src/renderer/backend/dx/dx_window.cpp index 17d201b..74899f2 100644 --- a/src/renderer/backend/dx/dx_window.cpp +++ b/src/renderer/backend/dx/dx_window.cpp @@ -22,11 +22,11 @@ void on_mouse_scroll(GLFWwindow* window, double xoffset, double yoffset) { const auto font_image = image_accessor(character.buffer, character.size); delete test_texture; - test_texture = get_renderer_raw()->create_texture(character.size, texture_format::R8_UNORM); + test_texture = get_renderer_raw()->create_texture(character.size, texture_format::RGB16_FLOAT); uint32_t row_pitch = 0; const auto data = test_texture->lock(&row_pitch); - auto image = image_accessor(data, test_texture->size()); + auto image = image_accessor(data, test_texture->size()); image.set_row_pitch(row_pitch); image.copy_from(font_image); test_texture->unlock(); @@ -94,7 +94,7 @@ bool dx_window::create_surface(GLFWwindow* in_window) { // test_texture = dx->load_image(R"(D:\69054578_p0.jpg)", texture_format::RGBA8_UNORM); glfwSetScrollCallback(get_glfw_window(), on_mouse_scroll); - text = aorii_text::load_font("C:/Windows/Fonts/simsunb.ttf", true, 48); + text = aorii_text::load_font("C:/Windows/Fonts/simsunb.ttf", false, 48); on_mouse_scroll(nullptr, 0, 0); return true; diff --git a/src/renderer/core/pixel_format/pixel.h b/src/renderer/core/pixel_format/pixel.h index f119e2a..dc4908c 100644 --- a/src/renderer/core/pixel_format/pixel.h +++ b/src/renderer/core/pixel_format/pixel.h @@ -2,6 +2,54 @@ #include #include +template +To convert(const From& value) { + // 获取 From 类型的最小值和最大值 + constexpr auto source_min = std::numeric_limits::min(); // 最小值 + constexpr auto source_max = std::numeric_limits::max(); // 最大值 + + // 获取 To 类型的最小值和最大值 + constexpr auto target_min = std::numeric_limits::min(); // 最小值 + constexpr auto target_max = std::numeric_limits::max(); // 最大值 + + // 如果源和目标类型相同,直接返回 + if constexpr (std::is_same_v) { + return value; + } + + // 线性映射公式 + auto a = static_cast(value) - source_min; + auto b = static_cast(target_max) - target_min; + auto c = (source_max - source_min); + return static_cast(target_min + a * b / c); +} + +template +To color_convert(const From& value) { + // 获取 To 类型的最小值和最大值 + constexpr auto target_min = std::numeric_limits::min(); // 最小值 + constexpr auto target_max = std::numeric_limits::max(); // 最大值 + + constexpr auto source_min = std::numeric_limits::min(); // 最小值 + constexpr auto source_max = std::numeric_limits::max(); // 最大值 + + // 如果源和目标类型相同,直接返回 + if constexpr (std::is_same_v) { + return value; + } + + // 如果是整形 + if constexpr (std::is_integral_v && std::is_integral_v) { + return convert(value); + } + + // 如果是浮点型, 将value映射到 [0, 1] 区间 + auto a = To(value - source_min); + auto b = To(source_max - source_min); + auto result = a / b; + return result; +} + template struct pixel { using pixel_type = T; @@ -109,15 +157,7 @@ struct pixel { auto operator=(const pixel& rhs) { constexpr int Num = std::min(N, N2); memset(data, 0, sizeof(data)); - if constexpr (std::is_same_v) { - for (int i = 0; i < Num; ++i) { - data[i] = rhs.data[i]; - } - } else { - for (int i = 0; i < Num; ++i) { - data[i] = (float)rhs.data[i] / std::numeric_limits::max() * std::numeric_limits::max(); - } - } + for (int i = 0; i < Num; ++i) { data[i] = color_convert(rhs.data[i]); } return *this; } }; @@ -135,16 +175,56 @@ struct image_accessor { : data(in_data), width(in_size.x()), height(in_size.y()), row_pitch(in_size.x()) { } + /** + * 将另一个图片复制到此图片 + * @tparam T 源像素格式 + * @param rhs 源图像 + */ template void copy_from(const image_accessor& rhs) { - assert(width == rhs.width && height == rhs.height); - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { + const int temp_width = std::min(width, rhs.width); + const int temp_height = std::min(height, rhs.height); + for (int y = 0; y < temp_height; ++y) { + for (int x = 0; x < temp_width; ++x) { get_pixel(x, y) = rhs.get_pixel(x, y); } } } + /** + * 将另一个图片复制到此图片, 从源图像的指定位置开始 + * @tparam T 源像素格式 + * @param rhs 源图像 + * @param rhs_pos 从源图像的此处开始复制 + */ + template + void copy_from(const image_accessor& rhs, const Eigen::Vector2i& rhs_pos) { + const int temp_width = std::min(width, rhs.width - rhs_pos.x()); + const int temp_height = std::min(height, rhs.height - rhs_pos.y()); + for (int y = 0; y < temp_height; ++y) { + for (int x = 0; x < temp_width; ++x) { + get_pixel(x, y) = rhs.get_pixel(x + rhs_pos.x(), y + rhs_pos.y()); + } + } + } + + /** + * 将另一个图片复制到此图片, 从此图片偏移开始 + * @tparam T 源像素格式 + * @param rhs 源图像 + * @param in_start 从此处开始复制 + */ + template + void offset_copy_from(const image_accessor& rhs, const Eigen::Vector2i& in_start) { + const int temp_width = std::min(width - in_start.x(), rhs.width); + const int temp_height = std::min(height - in_start.y(), rhs.height); + for (int y = 0; y < temp_height; ++y) { + for (int x = 0; x < temp_width; ++x) { + get_pixel(x + in_start.x(), y + in_start.y()) = rhs.get_pixel(x, y); + } + } + } + P& get_pixel(const int x, const int y) { if (x < 0 || x >= width || y < 0 || y >= height) { throw std::out_of_range("Pixel access out of bounds."); @@ -187,13 +267,22 @@ using pixel_r8 = pixel; using pixel_rg8 = pixel; using pixel_rgb8 = pixel; using pixel_rgba8 = pixel; +using pixel_a8 = pixel; using pixel_r16 = pixel; using pixel_rg16 = pixel; using pixel_rgb16 = pixel; using pixel_rgba16 = pixel; +using pixel_a16 = pixel; + +using pixel_r16f = pixel; +using pixel_rg16f = pixel; +using pixel_rgb16f = pixel; +using pixel_rgba16f = pixel; +using pixel_a16f = pixel; using pixel_r = pixel; using pixel_rg = pixel; using pixel_rgb = pixel; using pixel_rgba = pixel; +using pixel_a = pixel;