171 lines
5.7 KiB
C++
171 lines
5.7 KiB
C++
#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 <algorithm>
|
|
#include <memory>
|
|
|
|
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<MetaCoreRenderDeviceImpl>()) {
|
|
}
|
|
|
|
MetaCoreRenderDevice::~MetaCoreRenderDevice() {
|
|
Shutdown();
|
|
}
|
|
|
|
bool MetaCoreRenderDevice::Initialize(MetaCoreWindow& window) {
|
|
if (Impl_->Initialized) {
|
|
return true;
|
|
}
|
|
|
|
auto* frameworkHandle = static_cast<PandaFramework*>(window.GetNativeFrameworkHandle());
|
|
auto* windowFrameworkHandle = static_cast<WindowFramework*>(window.GetNativeWindowFrameworkHandle());
|
|
auto* graphicsWindowHandle = static_cast<GraphicsWindow*>(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<float>(framebufferWidth), 0.0F, 1.0F);
|
|
const float clampedRight = std::clamp((viewportRect.Left + viewportRect.Width) / static_cast<float>(framebufferWidth), 0.0F, 1.0F);
|
|
const float clampedTop = std::clamp(viewportRect.Top / static_cast<float>(framebufferHeight), 0.0F, 1.0F);
|
|
const float clampedBottom = std::clamp((viewportRect.Top + viewportRect.Height) / static_cast<float>(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<void*>(&Impl_->SceneRoot);
|
|
}
|
|
|
|
void* MetaCoreRenderDevice::GetNativeEditorCameraHandle() const {
|
|
return Impl_->EditorCamera.is_empty() ? nullptr : static_cast<void*>(&Impl_->EditorCamera);
|
|
}
|
|
|
|
} // namespace MetaCore
|