一些边界检查

This commit is contained in:
Nanako 2024-11-22 17:12:14 +08:00
parent a522ba5961
commit 8a7ee7de46
2 changed files with 104 additions and 15 deletions

View File

@ -22,11 +22,11 @@ void on_mouse_scroll(GLFWwindow* window, double xoffset, double yoffset) {
const auto font_image = image_accessor<pixel_r8>(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<pixel_r8>(data, test_texture->size());
auto image = image_accessor<pixel_rgb16f>(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;

View File

@ -2,6 +2,54 @@
#include <cstdint>
#include <Eigen/Eigen>
template<typename From, typename To>
To convert(const From& value) {
// 获取 From 类型的最小值和最大值
constexpr auto source_min = std::numeric_limits<From>::min(); // 最小值
constexpr auto source_max = std::numeric_limits<From>::max(); // 最大值
// 获取 To 类型的最小值和最大值
constexpr auto target_min = std::numeric_limits<To>::min(); // 最小值
constexpr auto target_max = std::numeric_limits<To>::max(); // 最大值
// 如果源和目标类型相同,直接返回
if constexpr (std::is_same_v<From, To>) {
return value;
}
// 线性映射公式
auto a = static_cast<double>(value) - source_min;
auto b = static_cast<double>(target_max) - target_min;
auto c = (source_max - source_min);
return static_cast<To>(target_min + a * b / c);
}
template<typename From, typename To>
To color_convert(const From& value) {
// 获取 To 类型的最小值和最大值
constexpr auto target_min = std::numeric_limits<To>::min(); // 最小值
constexpr auto target_max = std::numeric_limits<To>::max(); // 最大值
constexpr auto source_min = std::numeric_limits<From>::min(); // 最小值
constexpr auto source_max = std::numeric_limits<From>::max(); // 最大值
// 如果源和目标类型相同,直接返回
if constexpr (std::is_same_v<From, To>) {
return value;
}
// 如果是整形
if constexpr (std::is_integral_v<From> && std::is_integral_v<To>) {
return convert<From, To>(value);
}
// 如果是浮点型, 将value映射到 [0, 1] 区间
auto a = To(value - source_min);
auto b = To(source_max - source_min);
auto result = a / b;
return result;
}
template<typename T, int N>
struct pixel {
using pixel_type = T;
@ -109,15 +157,7 @@ struct pixel {
auto operator=(const pixel<U, N2>& rhs) {
constexpr int Num = std::min(N, N2);
memset(data, 0, sizeof(data));
if constexpr (std::is_same_v<T, U>) {
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<U>::max() * std::numeric_limits<T>::max();
}
}
for (int i = 0; i < Num; ++i) { data[i] = color_convert<U, T>(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<typename T>
void copy_from(const image_accessor<T>& 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<typename T>
void copy_from(const image_accessor<T>& 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<typename T>
void offset_copy_from(const image_accessor<T>& 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<uint8_t, 1>;
using pixel_rg8 = pixel<uint8_t, 2>;
using pixel_rgb8 = pixel<uint8_t, 3>;
using pixel_rgba8 = pixel<uint8_t, 4>;
using pixel_a8 = pixel<uint8_t, 1>;
using pixel_r16 = pixel<uint16_t, 1>;
using pixel_rg16 = pixel<uint16_t, 2>;
using pixel_rgb16 = pixel<uint16_t, 3>;
using pixel_rgba16 = pixel<uint16_t, 4>;
using pixel_a16 = pixel<uint16_t, 1>;
using pixel_r16f = pixel<Eigen::half, 1>;
using pixel_rg16f = pixel<Eigen::half, 2>;
using pixel_rgb16f = pixel<Eigen::half, 3>;
using pixel_rgba16f = pixel<Eigen::half, 4>;
using pixel_a16f = pixel<Eigen::half, 1>;
using pixel_r = pixel<float, 1>;
using pixel_rg = pixel<float, 2>;
using pixel_rgb = pixel<float, 3>;
using pixel_rgba = pixel<float, 4>;
using pixel_a = pixel<float, 1>;