#include "MetaCoreRender/MetaCoreRenderDevice.h" #include "MetaCorePlatform/MetaCoreWindow.h" #include "camera.h" #include "displayRegion.h" #include "graphicsEngine.h" #include "graphicsWindow.h" #include "pandaFramework.h" #include "pandaNode.h" #include "perspectiveLens.h" #include "windowFramework.h" #include #include namespace MetaCore { class MetaCoreRenderDevice::MetaCoreRenderDeviceImpl { public: MetaCoreWindow* Window = nullptr; PandaFramework* Framework = nullptr; WindowFramework* WindowFrameworkHandle = nullptr; GraphicsWindow* GraphicsWindowHandle = nullptr; GraphicsEngine* GraphicsEngineHandle = nullptr; DisplayRegion* SceneDisplayRegion = nullptr; NodePath SceneRoot{}; NodePath EditorCamera{}; bool Initialized = false; }; MetaCoreRenderDevice::MetaCoreRenderDevice() : Impl_(std::make_unique()) { } MetaCoreRenderDevice::~MetaCoreRenderDevice() { Shutdown(); } bool MetaCoreRenderDevice::Initialize(MetaCoreWindow& window) { if (Impl_->Initialized) { return true; } auto* frameworkHandle = static_cast(window.GetNativeFrameworkHandle()); auto* windowFrameworkHandle = static_cast(window.GetNativeWindowFrameworkHandle()); auto* graphicsWindowHandle = static_cast(window.GetNativeGraphicsWindowHandle()); if (frameworkHandle == nullptr || windowFrameworkHandle == nullptr || graphicsWindowHandle == nullptr) { return false; } Impl_->Window = &window; Impl_->Framework = frameworkHandle; Impl_->WindowFrameworkHandle = windowFrameworkHandle; Impl_->GraphicsWindowHandle = graphicsWindowHandle; Impl_->GraphicsEngineHandle = frameworkHandle->get_graphics_engine(); if (Impl_->GraphicsEngineHandle == nullptr) { return false; } Impl_->GraphicsEngineHandle->set_auto_flip(false); Impl_->GraphicsEngineHandle->open_windows(); if (Impl_->WindowFrameworkHandle->get_display_region_2d() != nullptr) { Impl_->WindowFrameworkHandle->get_display_region_2d()->set_active(false); } Impl_->SceneDisplayRegion = Impl_->WindowFrameworkHandle->get_display_region_3d(); if (Impl_->SceneDisplayRegion == nullptr) { return false; } Impl_->GraphicsWindowHandle->set_clear_color_active(true); Impl_->GraphicsWindowHandle->set_clear_color(LColor(0.38F, 0.48F, 0.62F, 1.0F)); PT(PandaNode) sceneRootNode = new PandaNode("MetaCoreSceneRoot"); Impl_->SceneRoot = Impl_->WindowFrameworkHandle->get_render().attach_new_node(sceneRootNode); Impl_->SceneRoot.set_shader_auto(); Impl_->EditorCamera = Impl_->WindowFrameworkHandle->make_camera(); Impl_->SceneDisplayRegion->set_camera(Impl_->EditorCamera); Impl_->SceneDisplayRegion->set_sort(0); Impl_->SceneDisplayRegion->set_scissor_enabled(true); Impl_->SceneDisplayRegion->set_clear_color_active(false); if (auto* cameraNode = DCAST(Camera, Impl_->EditorCamera.node()); cameraNode != nullptr) { PT(PerspectiveLens) lens = new PerspectiveLens(); lens->set_fov(60.0F); lens->set_near_far(0.05F, 500.0F); cameraNode->set_lens(lens); } Impl_->Initialized = true; return true; } void MetaCoreRenderDevice::Shutdown() { if (!Impl_->Initialized) { return; } if (!Impl_->EditorCamera.is_empty()) { Impl_->EditorCamera.remove_node(); Impl_->EditorCamera = NodePath(); } if (!Impl_->SceneRoot.is_empty()) { Impl_->SceneRoot.remove_node(); Impl_->SceneRoot = NodePath(); } Impl_->SceneDisplayRegion = nullptr; Impl_->GraphicsEngineHandle = nullptr; Impl_->GraphicsWindowHandle = nullptr; Impl_->WindowFrameworkHandle = nullptr; Impl_->Framework = nullptr; Impl_->Window = nullptr; Impl_->Initialized = false; } void MetaCoreRenderDevice::RenderFrame() const { if (Impl_->GraphicsEngineHandle != nullptr) { Impl_->GraphicsEngineHandle->render_frame(); } } void MetaCoreRenderDevice::PresentFrame() const { if (Impl_->GraphicsEngineHandle != nullptr) { Impl_->GraphicsEngineHandle->flip_frame(); } } void MetaCoreRenderDevice::SetSceneViewportRect(const MetaCoreViewportRect& viewportRect) { if (Impl_->SceneDisplayRegion == nullptr || Impl_->Window == nullptr) { return; } const auto [framebufferWidth, framebufferHeight] = Impl_->Window->GetFramebufferSize(); if (framebufferWidth <= 0 || framebufferHeight <= 0 || viewportRect.Width <= 1.0F || viewportRect.Height <= 1.0F) { Impl_->SceneDisplayRegion->set_active(false); return; } const float clampedLeft = std::clamp(viewportRect.Left / static_cast(framebufferWidth), 0.0F, 1.0F); const float clampedRight = std::clamp((viewportRect.Left + viewportRect.Width) / static_cast(framebufferWidth), 0.0F, 1.0F); const float clampedTop = std::clamp(viewportRect.Top / static_cast(framebufferHeight), 0.0F, 1.0F); const float clampedBottom = std::clamp((viewportRect.Top + viewportRect.Height) / static_cast(framebufferHeight), 0.0F, 1.0F); Impl_->SceneDisplayRegion->set_active(true); Impl_->SceneDisplayRegion->set_dimensions( clampedLeft, clampedRight, 1.0F - clampedBottom, 1.0F - clampedTop ); } void* MetaCoreRenderDevice::GetNativeWindowFrameworkHandle() const { return Impl_->WindowFrameworkHandle; } void* MetaCoreRenderDevice::GetNativeSceneRootHandle() const { return Impl_->SceneRoot.is_empty() ? nullptr : static_cast(&Impl_->SceneRoot); } void* MetaCoreRenderDevice::GetNativeEditorCameraHandle() const { return Impl_->EditorCamera.is_empty() ? nullptr : static_cast(&Impl_->EditorCamera); } } // namespace MetaCore