Files
mirage_old/src/core/renderer/render_context.cpp
2025-02-24 04:43:48 +08:00

185 lines
6.4 KiB
C++

#include "render_context.h"
#include "LLGL/Utils/VertexFormat.h"
#include "mirage.h"
#include "rendering_common.h"
#include "shader_loader.h"
#include "LLGL/Utils/Parse.h"
struct pipeline_param {
Eigen::Matrix4f mvp;
};
namespace mirage {
render_context::~render_context() {
if (command_buffer) {
get_renderer()->Release(*command_buffer);
}
if (swap_chain) {
get_renderer()->Release(*swap_chain);
}
}
bool render_context::init(const swap_chain_descriptor& in_desc, const std::shared_ptr<LLGL::Surface>& in_surface) {
LLGL::SwapChainDescriptor temp = in_desc;
temp.resolution = in_surface->GetContentSize();
swap_chain = get_renderer()->CreateSwapChain(temp, in_surface);
if (swap_chain == nullptr) {
spdlog::error("无法创建交换链");
return false;
}
command_buffer = get_renderer()->CreateCommandBuffer(LLGL::CommandBufferFlags::ImmediateSubmit);
if (command_buffer == nullptr) {
spdlog::error("无法创建命令缓冲区");
return false;
}
set_vsync(in_desc.vsync);
vertex_buffer = create_vertex_buffer(64);
index_buffer = create_index_buffer(64);
param_buffer = create_constant_buffer<pipeline_param>();
pipeline_param param;
param.mvp = get_projection_matrix();
param_buffer->set(param);
LLGL::PipelineLayoutDescriptor pipeline_layout_desc;
// pipeline_layout_desc.bindings.emplace_back(
// LLGL::ResourceType::Buffer,
// LLGL::BindFlags::VertexBuffer,
// LLGL::StageFlags::VertexStage,
// 0
// );
pipeline_layout_desc.bindings.emplace_back(
LLGL::ResourceType::Buffer,
LLGL::BindFlags::ConstantBuffer,
LLGL::StageFlags::VertexStage | LLGL::StageFlags::FragmentStage,
1
);
pipeline = generated_pipelines::create_aorii_rect_pipeline(get_renderer(), swap_chain->GetRenderPass(), pipeline_layout_desc);
push_rectangle({0, 0}, {100, 100}, linear_color::white);
return true;
}
render_context::update_status render_context::render_update(const duration_type& in_delta_time) {
if (!command_buffer || !swap_chain) {
return update_status::fail;
}
if (!swap_chain->IsPresentable()) {
return update_status::wait_for_present;
}
if (new_size) {
swap_chain->ResizeBuffers(new_size.value());
pipeline_param param;
param.mvp = get_projection_matrix();
param_buffer->set(param);
new_size.reset();
}
command_buffer->Begin(); {
command_buffer->SetViewport(swap_chain->GetResolution());
command_buffer->SetIndexBuffer(index_buffer->get_raw());
command_buffer->SetVertexBuffer(vertex_buffer->get_raw());
command_buffer->BeginRenderPass(*swap_chain); {
command_buffer->Clear(LLGL::ClearFlags::Color, {0.1f, 0.1f, 0.2f, 1.0f});
command_buffer->SetPipelineState(*pipeline.pipeline_state);
command_buffer->SetResource(0, param_buffer->get_raw());
command_buffer->DrawIndexed(index_buffer->get_size() / sizeof(uint32_t), 0);
}
command_buffer->EndRenderPass();
}
command_buffer->End();
get_renderer()->GetCommandQueue()->Submit(*command_buffer);
swap_chain->Present();
return update_status::success;
}
void render_context::resize_swap_chain(const LLGL::Extent2D& in_size, long in_flag) {
if (!swap_chain)
return;
new_size = in_size;
}
void render_context::set_vsync(bool in_vsync) {
if (!swap_chain)
return;
swap_chain->SetVsyncInterval(in_vsync ? 1 : 0);
vsync = in_vsync;
spdlog::info("垂直同步: {}", vsync);
}
void render_context::push_rectangle(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size,
const linear_color_type& in_color) {
vertex va{};
vertex vb{};
vertex vc{};
vertex vd{};
va.color = in_color;
vb.color = in_color;
vc.color = in_color;
vd.color = in_color;
va.position = in_pos;
vb.position = {in_pos.x() + in_size.x(), in_pos.y()};
vc.position = in_pos + in_size;
vd.position = {in_pos.x(), in_pos.y() + in_size.y()};
va.uv = {0.0f, 0.0f};
vb.uv = {1.0f, 0.0f};
vc.uv = {1.0f, 1.0f};
vd.uv = {0.0f, 1.0f};
const auto index_offset = static_cast<uint32_t>(vertex_buffer->get_size() / sizeof(vertex));
// 根据index_offset计算索引
const triangle_index_t ta = {0 + index_offset, 1 + index_offset, 2 + index_offset};
const triangle_index_t tb = {0 + index_offset, 2 + index_offset, 3 + index_offset};
std::vector quad_indices = {ta, tb};
std::vector quad_vertices = {va, vb, vc, vd};
vertex_buffer->push(quad_vertices);
index_buffer->push(quad_indices);
}
Eigen::Matrix4f render_context::get_projection_matrix() const {
const bool is_clip_range_unit_cube = get_renderer()->GetRenderingCaps().clippingRange ==
LLGL::ClippingRange::MinusOneToOne;
const auto& size = swap_chain->GetResolution();
Eigen::Matrix4f matrix = Eigen::Matrix4f::Identity();
if (is_clip_range_unit_cube) {
// 对于 [-1, 1] 的裁剪范围
matrix(0, 0) = 2.0f / size.width;
matrix(1, 1) = -2.0f / size.height;
matrix(2, 2) = 1.0f;
matrix(3, 3) = 1.0f;
matrix(3, 0) = -1.0f;
matrix(3, 1) = 1.0f;
// 调整Z轴范围从[-1,1]
matrix(2, 2) = 2.0f;
matrix(3, 2) = -1.0f;
} else {
// 对于 [0, 1] 的裁剪范围
matrix(0, 0) = 2.0f / size.width;
matrix(1, 1) = -2.0f / size.height;
matrix(2, 2) = 1.0f;
matrix(3, 3) = 1.0f;
matrix(3, 0) = -1.0f;
matrix(3, 1) = 1.0f;
// 调整Z轴范围从[0,1]
matrix(2, 2) = 1.0f;
matrix(3, 2) = 0.0f;
}
return matrix;
}
} // namespace mirage