Files
aorii/src/core/renderer/renderer_context.cpp
2025-02-04 19:25:09 +08:00

183 lines
7.5 KiB
C++

#include "renderer_context.h"
#include "renderer.h"
#include "renderer_text.h"
#include "pipeline/sdf_text_pipeline.h"
#include "pipeline/segment_pipeline.h"
#include "pipeline/texture_pipeline.h"
aorii_text* text = nullptr;
void renderer_context::init() {
text = new aorii_text();
// D:\Projects\aorii\JetBrainsMono-Regular.ttf
// text->initialize(LR"(C:\Windows\Fonts\Deng.ttf)");
// text->add_font(LR"(C:\Windows\Fonts\seguiemj.ttf)");
// text->precache_common_characters();
}
void renderer_context::draw_rectangle(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size, const linear_color& in_color) {
to_rect_pipeline();
make_rect(in_pos, in_size, in_color);
}
void renderer_context::draw_rounded_rectangle(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size, const linear_color& in_color, float in_angle, const rect_radius& in_radius) {
to_rounded_rect_pipeline(in_pos, in_size, in_radius);
// in_angle传入的是角度, 需要转换为弧度
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
in_angle = in_angle * M_PI / 180;
make_rect(in_pos, in_size, in_color, in_angle);
// 立刻绘制并重置管线, 因为下一个绘制命令的参数可能不同, 所以无法合批
flush();
}
void renderer_context::draw_line(const Eigen::Vector2f& in_pos_p1, const Eigen::Vector2f& in_pos_p2, const linear_color& in_color, float in_thickness) {
}
void renderer_context::draw_texture(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size,
renderer_texture* in_texture, const linear_color& in_color) {
to_texture_pipeline(in_texture);
make_rect(in_pos, in_size, in_color);
// 立刻绘制并重置管线, 因为下一个绘制命令的参数可能不同, 所以无法合批
flush();
}
void renderer_context::draw_string(const Eigen::Vector2f& in_pos, const std::u32string& in_str, float in_height, const linear_color& in_color) {
// to_text_pipeline(in_color);
//
// const auto& measure = text->measure_text(in_str, in_height);
//
// for (const auto& mch: measure) {
// const auto info = mch.item;
// if (!info)
// continue;
// const Eigen::Vector2f pos = mch.offset + in_pos;
// const Eigen::Vector2f size = Eigen::Vector2f{ info->get_width(), info->get_height() } * mch.size_scale;
//
// aorii_vertex_param param{};
// param.param_a1 = info->tex_u;
// param.param_a2 = info->tex_v;
// param.param_a3 = info->tex_z;
// param.param_b1 = info->u_size;
// param.param_b2 = info->v_size;
// // param.param_b3 = info->get_width() * mch.size_scale > 15 ? 0.01 : 0;
// param.param_b3 = info->get_width() * mch.size_scale > 15 ? 0.01 : 0;
//
// make_rect(pos, size, in_color, 0, param);
// }
}
void renderer_context::set_projection_matrix(const Eigen::Matrix4f& in_matrix, const Eigen::Vector2i& in_framebuffer_size) {
projection_matrix = in_matrix;
framebuffer_size = in_framebuffer_size;
// // 更新默认管线的投影矩阵
// const auto rect_p = aorii::get_renderer_raw()->get_rect_pipeline();
// rect_p->set_param({ in_matrix });
// // 更新纹理管线的投影矩阵
// const auto texture_p = aorii::get_renderer_raw()->get_texture_pipeline();
// texture_p->set_param({ in_matrix });
// 圆角矩形管线的投影矩阵不需要更新, 因为它在每次绘制时都会更新
// 线段管线的投影矩阵不需要更新, 因为它在每次绘制时都会更新
}
void renderer_context::to_rect_pipeline() {
// const auto rect_p = aorii::get_renderer_raw()->get_rect_pipeline();
// switch_pipeline(rect_p);
}
void renderer_context::to_rounded_rect_pipeline(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size, const rect_radius& in_radius) {
// const auto rounded_rect_p = aorii::get_renderer_raw()->get_rounded_rect_pipeline();
// switch_pipeline(rounded_rect_p);
//
// rounded_rect_pipeline::param param;
// param.projection_matrix = projection_matrix;
// param.size = in_size;
// param.pos = in_pos;
// param.radius = in_radius;
// rounded_rect_p->set_param(param);
}
void renderer_context::to_texture_pipeline(renderer_texture* in_texture) {
// const auto texture_p = aorii::get_renderer_raw()->get_texture_pipeline();
// switch_pipeline(texture_p);
// texture_p->set_texture(in_texture);
}
void renderer_context::to_segment_pipeline(const Eigen::Vector2f& in_pos_p1, const Eigen::Vector2f& in_pos_p2, float in_thickness) {
// const auto segment_p = aorii::get_renderer_raw()->get_segment_pipeline();
// switch_pipeline(segment_p);
//
// segment_pipeline::param param;
// param.projection_matrix = projection_matrix;
// param.point_a = in_pos_p1;
// param.point_b = in_pos_p2;
// param.thickness = in_thickness;
// segment_p->set_param(param);
}
void renderer_context::to_text_pipeline(const linear_color& in_color) {
// const auto text_p = aorii::get_renderer_raw()->get_text_pipeline();
// switch_pipeline(text_p);
//
// sdf_text_pipeline::param param;
// param.projection_matrix = projection_matrix;
// text_p->set_param(param);
//
// sdf_text_pipeline::sdf_font_param font_param;
// font_param.smoothing = 1;
// font_param.thickness = 1;
// font_param.outline_width = 0;
// font_param.outline_color = in_color;
// text_p->set_sdf_font_param(font_param);
// text_p->set_glyph_texture(text->get_texture_array());
}
void renderer_context::make_rect(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size,
const linear_color& in_color, float in_angle, const aorii_vertex_param& in_param) {
aorii_vertex v1{ { in_pos.x(), in_pos.y() }, { 0, 0 }, in_color, in_param }; // 左上角
aorii_vertex v2{ { in_pos.x() + in_size.x(), in_pos.y() }, { 1, 0 }, in_color, in_param }; // 右上角
aorii_vertex v3{ { in_pos.x(), in_pos.y() + in_size.y() }, { 0, 1 }, in_color, in_param }; // 左下角
aorii_vertex v4{ { in_pos.x() + in_size.x(), in_pos.y() + in_size.y() }, { 1, 1 }, in_color, in_param }; // 右下角
if (in_angle != 0) {
auto center = in_pos + in_size * 0.5f;
const Eigen::Affine2f transform =
Eigen::Translation2f(center) * // 平移到旋转中心
Eigen::Rotation2Df(in_angle) * // 旋转
Eigen::Translation2f(-center); // 平移回原点
v1.position = transform * v1.position.homogeneous();
v2.position = transform * v2.position.homogeneous();
v3.position = transform * v3.position.homogeneous();
v4.position = transform * v4.position.homogeneous();
}
const uint32_t base_index = vertices.size();
vertices.push_back(v1);
vertices.push_back(v2);
vertices.push_back(v3);
// vertices.push_back(v3);
// vertices.push_back(v2);
vertices.push_back(v4);
triangles.push_back(aorii_triangle{ base_index + 0, base_index + 1, base_index + 2 });
triangles.push_back(aorii_triangle{ base_index + 2, base_index + 1, base_index + 3 });
}
void renderer_context::rotate_vertex(const float in_angle, const Eigen::Vector2f& in_center) {
const Eigen::Affine2f transform =
Eigen::Translation<float, 2>(in_center) * // 平移到旋转中心
Eigen::Rotation2D<float>(in_angle) * // 旋转
Eigen::Translation<float, 2>(-in_center); // 平移回原点
for (auto& vertex : vertices) {
vertex.position = transform * vertex.position;
}
}