#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& 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 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(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