feat: 实现 Filament 离屏渲染与 ImGui 视口嵌合(打通 RTT 管线)
This commit is contained in:
parent
2799ddc0e3
commit
3bf03f4b1f
@ -150,7 +150,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
MetaCore::MetaCoreEditorViewportRenderer viewportRenderer;
|
||||
if (!viewportRenderer.Initialize(renderDevice)) {
|
||||
if (!viewportRenderer.Initialize(renderDevice, window)) {
|
||||
std::cerr << "MetaCorePlayer: viewport renderer initialize failed\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -27,6 +27,9 @@ endif()
|
||||
include(MetaCorePanda3D)
|
||||
metacore_prepare_panda3d()
|
||||
|
||||
include(MetaCoreFilament)
|
||||
|
||||
|
||||
find_package(glm CONFIG REQUIRED)
|
||||
find_package(imgui CONFIG REQUIRED)
|
||||
|
||||
@ -207,6 +210,7 @@ target_compile_options(MetaCoreScene PRIVATE ${METACORE_COMMON_WARNINGS})
|
||||
set(METACORE_RENDER_HEADERS
|
||||
Source/MetaCoreRender/Public/MetaCoreRender/MetaCoreEditorViewportRenderer.h
|
||||
Source/MetaCoreRender/Public/MetaCoreRender/MetaCorePandaSceneBridge.h
|
||||
Source/MetaCoreRender/Public/MetaCoreRender/MetaCoreFilamentSceneBridge.h
|
||||
Source/MetaCoreRender/Public/MetaCoreRender/MetaCoreRenderDevice.h
|
||||
Source/MetaCoreRender/Public/MetaCoreRender/MetaCoreRenderTypes.h
|
||||
)
|
||||
@ -214,9 +218,11 @@ set(METACORE_RENDER_HEADERS
|
||||
set(METACORE_RENDER_SOURCES
|
||||
Source/MetaCoreRender/Private/MetaCoreEditorViewportRenderer.cpp
|
||||
Source/MetaCoreRender/Private/MetaCorePandaSceneBridge.cpp
|
||||
Source/MetaCoreRender/Private/MetaCoreFilamentSceneBridge.cpp
|
||||
Source/MetaCoreRender/Private/MetaCoreRenderDevice.cpp
|
||||
)
|
||||
|
||||
|
||||
add_library(MetaCoreRender STATIC
|
||||
${METACORE_RENDER_HEADERS}
|
||||
${METACORE_RENDER_SOURCES}
|
||||
@ -236,6 +242,9 @@ target_link_libraries(MetaCoreRender
|
||||
glm::glm
|
||||
)
|
||||
|
||||
metacore_use_filament(MetaCoreRender)
|
||||
|
||||
|
||||
target_compile_options(MetaCoreRender PRIVATE ${METACORE_COMMON_WARNINGS})
|
||||
|
||||
set(METACORE_RUNTIME_DATA_HEADERS
|
||||
@ -320,7 +329,6 @@ set(METACORE_EDITOR_SOURCES
|
||||
Source/MetaCoreEditor/Private/MetaCoreEditorModule.cpp
|
||||
Source/MetaCoreEditor/Private/MetaCoreSceneInteractionService.cpp
|
||||
third_party/ImGuizmo/ImGuizmo.cpp
|
||||
third_party/cgltf/cgltf.cpp
|
||||
third_party/stb/stb_image_impl.cpp
|
||||
)
|
||||
|
||||
|
||||
@ -658,7 +658,7 @@ bool MetaCoreEditorApp::Initialize() {
|
||||
}
|
||||
|
||||
MetaCoreTraceStartup("metacore.app: initialize viewport");
|
||||
if (!ViewportRenderer_.Initialize(RenderDevice_)) {
|
||||
if (!ViewportRenderer_.Initialize(RenderDevice_, Window_)) {
|
||||
MetaCoreTraceStartup("metacore.app: initialize viewport failed");
|
||||
return false;
|
||||
}
|
||||
@ -990,6 +990,10 @@ void MetaCoreEditorApp::DrawEditorFrame() {
|
||||
|
||||
bool gizmoCanvasOpen = true;
|
||||
if (ImGui::Begin("MetaCoreSceneGizmoCanvas", &gizmoCanvasOpen, gizmoCanvasFlags)) {
|
||||
// 绘制 Filament 离屏渲染的 3D 画面
|
||||
uint32_t texId = ViewportRenderer_.GetFilamentGLTextureId();
|
||||
ImGui::Image((void*)(intptr_t)texId, ImVec2(viewportState.Width, viewportState.Height));
|
||||
|
||||
SceneInteractionService_.HandleGizmoManipulation(*EditorContext_);
|
||||
|
||||
gizmoUsing = ImGuizmo::IsUsing();
|
||||
|
||||
@ -39,7 +39,7 @@ void MetaCoreTrace(const char* message) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool MetaCoreEditorViewportRenderer::Initialize(MetaCoreRenderDevice& renderDevice) {
|
||||
bool MetaCoreEditorViewportRenderer::Initialize(MetaCoreRenderDevice& renderDevice, MetaCoreWindow& window) {
|
||||
MetaCoreTrace("metacore.render: viewport init enter");
|
||||
Shutdown();
|
||||
|
||||
@ -48,6 +48,11 @@ bool MetaCoreEditorViewportRenderer::Initialize(MetaCoreRenderDevice& renderDevi
|
||||
MetaCoreTrace("metacore.render: viewport scene runtime bind failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FilamentSceneBridge_.Initialize(window)) {
|
||||
MetaCoreTrace("metacore.render: viewport filament scene runtime bind failed");
|
||||
return false;
|
||||
}
|
||||
MetaCoreTrace("metacore.render: viewport scene runtime ready");
|
||||
|
||||
RenderDevice_ = &renderDevice;
|
||||
@ -56,12 +61,15 @@ bool MetaCoreEditorViewportRenderer::Initialize(MetaCoreRenderDevice& renderDevi
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MetaCoreEditorViewportRenderer::Shutdown() {
|
||||
SceneBridge_.Shutdown();
|
||||
FilamentSceneBridge_.Shutdown();
|
||||
RenderDevice_ = nullptr;
|
||||
ViewportRect_ = MetaCoreViewportRect{};
|
||||
}
|
||||
|
||||
|
||||
void MetaCoreEditorViewportRenderer::SetViewportRect(const MetaCoreViewportRect& viewportRect) {
|
||||
ViewportRect_ = viewportRect;
|
||||
if (RenderDevice_ != nullptr) {
|
||||
@ -75,12 +83,21 @@ void MetaCoreEditorViewportRenderer::RenderSceneToViewport(const MetaCoreScene&
|
||||
}
|
||||
|
||||
RenderDevice_->SetSceneViewportRect(ViewportRect_);
|
||||
SceneBridge_.ApplySceneView(sceneView);
|
||||
SceneBridge_.SyncScene(scene, false);
|
||||
|
||||
// 更新并渲染 Filament 桥接器
|
||||
FilamentSceneBridge_.ApplySceneView(sceneView);
|
||||
FilamentSceneBridge_.SyncScene(scene, false);
|
||||
FilamentSceneBridge_.Render(); // 恢复 Render 调用,因为现在是离屏渲染
|
||||
}
|
||||
|
||||
|
||||
void MetaCoreEditorViewportRenderer::SetProjectRootPath(const std::filesystem::path& projectRootPath) {
|
||||
SceneBridge_.SetProjectRootPath(projectRootPath);
|
||||
FilamentSceneBridge_.SetProjectRootPath(projectRootPath);
|
||||
}
|
||||
|
||||
uint32_t MetaCoreEditorViewportRenderer::GetFilamentGLTextureId() const {
|
||||
return FilamentSceneBridge_.GetGLTextureId();
|
||||
}
|
||||
|
||||
bool MetaCoreEditorViewportRenderer::TryGetObjectWorldMatrix(MetaCoreId objectId, glm::mat4& worldMatrix) const {
|
||||
|
||||
408
Source/MetaCoreRender/Private/MetaCoreFilamentSceneBridge.cpp
Normal file
408
Source/MetaCoreRender/Private/MetaCoreFilamentSceneBridge.cpp
Normal file
@ -0,0 +1,408 @@
|
||||
#include "MetaCoreRender/MetaCoreFilamentSceneBridge.h"
|
||||
#include "MetaCorePlatform/MetaCoreWindow.h"
|
||||
#include "MetaCoreScene/MetaCoreScene.h"
|
||||
#include "MetaCoreScene/MetaCoreComponents.h"
|
||||
#include "MetaCoreRender/MetaCoreRenderTypes.h"
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Scene.h>
|
||||
#include <filament/View.h>
|
||||
#include <filament/Camera.h>
|
||||
#include <filament/SwapChain.h>
|
||||
#include <filament/Renderer.h>
|
||||
#include <filament/Viewport.h>
|
||||
#include <filament/TransformManager.h>
|
||||
#include <filament/Texture.h>
|
||||
#include <filament/RenderTarget.h>
|
||||
#include <filament/LightManager.h>
|
||||
|
||||
#include <gltfio/AssetLoader.h>
|
||||
#include <gltfio/FilamentAsset.h>
|
||||
#include <gltfio/ResourceLoader.h>
|
||||
#include <gltfio/MaterialProvider.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
#include <utils/EntityManager.h>
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
// 引入 Windows 和 OpenGL 头文件以创建纹理
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
namespace MetaCore {
|
||||
|
||||
class MetaCoreFilamentSceneBridge::MetaCoreFilamentSceneBridgeImpl {
|
||||
public:
|
||||
MetaCoreFilamentSceneBridgeImpl() = default;
|
||||
|
||||
~MetaCoreFilamentSceneBridgeImpl() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
bool Initialize(MetaCoreWindow& window) {
|
||||
std::cout << "FilamentSceneBridge: Initializing..." << std::endl;
|
||||
|
||||
// 创建 Filament Engine (不共享上下文,避免闪退)
|
||||
Engine_ = filament::Engine::create();
|
||||
|
||||
if (!Engine_) {
|
||||
std::cerr << "Failed to create Filament Engine with shared context!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 创建无窗口的 1x1 交换链 (因为我们是离屏渲染,不需要绑定真实窗口,避免 OpenGL 上下文冲突)
|
||||
SwapChain_ = Engine_->createSwapChain(1, 1, 0);
|
||||
if (!SwapChain_) {
|
||||
std::cerr << "Failed to create Filament headless SwapChain!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 创建渲染器
|
||||
Renderer_ = Engine_->createRenderer();
|
||||
|
||||
// 创建场景
|
||||
Scene_ = Engine_->createScene();
|
||||
|
||||
// 创建默认灯光
|
||||
Light_ = utils::EntityManager::get().create();
|
||||
filament::LightManager::Builder(filament::LightManager::Type::DIRECTIONAL)
|
||||
.color(filament::Color::toLinear<filament::ACCURATE>({ 1.0f, 1.0f, 1.0f }))
|
||||
.intensity(100000.0f)
|
||||
.direction({ 0.5f, -1.0f, -0.5f })
|
||||
.castShadows(true)
|
||||
.build(*Engine_, Light_);
|
||||
Scene_->addEntity(Light_);
|
||||
|
||||
// 创建相机
|
||||
utils::Entity cameraEntity = utils::EntityManager::get().create();
|
||||
Camera_ = Engine_->createCamera(cameraEntity);
|
||||
|
||||
// 创建视图
|
||||
View_ = Engine_->createView();
|
||||
View_->setScene(Scene_);
|
||||
View_->setCamera(Camera_);
|
||||
|
||||
// 初始化离屏渲染纹理
|
||||
auto [width, height] = window.GetFramebufferSize();
|
||||
|
||||
// 1. 创建 OpenGL 纹理
|
||||
glGenTextures(1, &GLTextureId_);
|
||||
glBindTexture(GL_TEXTURE_2D, GLTextureId_);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// 2. 导入到 Filament 作为颜色附件
|
||||
FilamentTexture_ = filament::Texture::Builder()
|
||||
.width(static_cast<uint32_t>(width))
|
||||
.height(static_cast<uint32_t>(height))
|
||||
.usage(filament::Texture::Usage::COLOR_ATTACHMENT | filament::Texture::Usage::SAMPLEABLE)
|
||||
.format(filament::Texture::InternalFormat::RGBA8)
|
||||
.import(static_cast<intptr_t>(GLTextureId_))
|
||||
.build(*Engine_);
|
||||
|
||||
// 3. 创建深度纹理
|
||||
DepthTexture_ = filament::Texture::Builder()
|
||||
.width(static_cast<uint32_t>(width))
|
||||
.height(static_cast<uint32_t>(height))
|
||||
.usage(filament::Texture::Usage::DEPTH_ATTACHMENT)
|
||||
.format(filament::Texture::InternalFormat::DEPTH24)
|
||||
.build(*Engine_);
|
||||
|
||||
// 4. 创建 RenderTarget 并绑定
|
||||
RenderTarget_ = filament::RenderTarget::Builder()
|
||||
.texture(filament::RenderTarget::AttachmentPoint::COLOR, FilamentTexture_)
|
||||
.texture(filament::RenderTarget::AttachmentPoint::DEPTH, DepthTexture_)
|
||||
.build(*Engine_);
|
||||
|
||||
// 5. 设置到 View
|
||||
View_->setRenderTarget(RenderTarget_);
|
||||
View_->setViewport({0, 0, static_cast<uint32_t>(width), static_cast<uint32_t>(height)});
|
||||
|
||||
// 初始化 gltfio (使用 JIT Shader Provider,需要链接 filamat)
|
||||
MaterialProvider_ = filament::gltfio::createJitShaderProvider(Engine_);
|
||||
AssetLoader_ = filament::gltfio::AssetLoader::create({ Engine_, MaterialProvider_, nullptr });
|
||||
|
||||
std::cout << "FilamentSceneBridge: Initialized with Offscreen Texture ID: " << GLTextureId_ << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
if (Engine_) {
|
||||
std::cout << "FilamentSceneBridge: Shutting down..." << std::endl;
|
||||
|
||||
// 销毁所有加载的资产
|
||||
for (auto& [id, asset] : LoadedAssets_) {
|
||||
AssetLoader_->destroyAsset(asset);
|
||||
}
|
||||
LoadedAssets_.clear();
|
||||
|
||||
// 销毁 gltfio 资源
|
||||
if (AssetLoader_) {
|
||||
filament::gltfio::AssetLoader::destroy(&AssetLoader_);
|
||||
AssetLoader_ = nullptr;
|
||||
}
|
||||
if (MaterialProvider_) {
|
||||
MaterialProvider_->destroyMaterials();
|
||||
delete MaterialProvider_;
|
||||
MaterialProvider_ = nullptr;
|
||||
}
|
||||
|
||||
// 销毁离屏渲染资源
|
||||
if (RenderTarget_) {
|
||||
Engine_->destroy(RenderTarget_);
|
||||
RenderTarget_ = nullptr;
|
||||
}
|
||||
if (FilamentTexture_) {
|
||||
Engine_->destroy(FilamentTexture_);
|
||||
FilamentTexture_ = nullptr;
|
||||
}
|
||||
if (DepthTexture_) {
|
||||
Engine_->destroy(DepthTexture_);
|
||||
DepthTexture_ = nullptr;
|
||||
}
|
||||
if (GLTextureId_) {
|
||||
glDeleteTextures(1, &GLTextureId_);
|
||||
GLTextureId_ = 0;
|
||||
}
|
||||
|
||||
// 销毁 View
|
||||
Engine_->destroy(View_);
|
||||
|
||||
// 销毁相机组件和实体
|
||||
if (Camera_) {
|
||||
utils::Entity cameraEntity = Camera_->getEntity();
|
||||
Engine_->destroyCameraComponent(cameraEntity);
|
||||
utils::EntityManager::get().destroy(cameraEntity);
|
||||
}
|
||||
|
||||
// 销毁其他资源
|
||||
Engine_->destroy(Scene_);
|
||||
Engine_->destroy(Renderer_);
|
||||
Engine_->destroy(SwapChain_);
|
||||
|
||||
// 最后销毁 Engine
|
||||
filament::Engine::destroy(&Engine_);
|
||||
Engine_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SetProjectRootPath(const std::filesystem::path& projectRootPath) {
|
||||
ProjectRootPath_ = projectRootPath;
|
||||
}
|
||||
|
||||
void SyncScene(const MetaCoreScene& scene, bool compatibilityMeshOnly) {
|
||||
if (!AssetLoader_) return;
|
||||
|
||||
for (const auto& gameObject : scene.GetGameObjects()) {
|
||||
if (!gameObject.HasComponent<MetaCoreMeshRendererComponent>()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& meshRenderer = gameObject.GetComponent<MetaCoreMeshRendererComponent>();
|
||||
if (meshRenderer.MeshSource != MetaCoreMeshSourceKind::Asset) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string modelPath = meshRenderer.SourceModelPath;
|
||||
if (modelPath.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::filesystem::path absolutePath = ProjectRootPath_ / modelPath;
|
||||
|
||||
// 如果已经加载过,更新位置即可
|
||||
if (LoadedAssets_.contains(gameObject.GetId())) {
|
||||
UpdateTransform(gameObject);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 加载新模型
|
||||
std::cout << "FilamentSceneBridge: Loading GLTF: " << absolutePath << std::endl;
|
||||
|
||||
std::ifstream file(absolutePath, std::ios::binary);
|
||||
if (!file.is_open()) {
|
||||
std::cerr << "Failed to open file: " << absolutePath << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<char> buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
|
||||
filament::gltfio::FilamentAsset* asset = AssetLoader_->createAsset(
|
||||
reinterpret_cast<const uint8_t*>(buffer.data()),
|
||||
static_cast<uint32_t>(buffer.size())
|
||||
);
|
||||
|
||||
if (!asset) {
|
||||
std::cerr << "Failed to create asset!" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 加载贴图等资源
|
||||
filament::gltfio::ResourceLoader resourceLoader({ Engine_ });
|
||||
resourceLoader.loadResources(asset);
|
||||
|
||||
// 添加到场景
|
||||
Scene_->addEntities(asset->getEntities(), asset->getEntityCount());
|
||||
|
||||
LoadedAssets_[gameObject.GetId()] = asset;
|
||||
|
||||
// 更新初始位置
|
||||
UpdateTransform(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
void ApplySceneView(const MetaCoreSceneView& sceneView) {
|
||||
if (!Camera_ || !View_) return;
|
||||
|
||||
// 设置相机位置和朝向
|
||||
Camera_->lookAt(
|
||||
{ sceneView.CameraPosition.x, sceneView.CameraPosition.y, sceneView.CameraPosition.z },
|
||||
{ sceneView.CameraTarget.x, sceneView.CameraTarget.y, sceneView.CameraTarget.z },
|
||||
{ sceneView.CameraUp.x, sceneView.CameraUp.y, sceneView.CameraUp.z }
|
||||
);
|
||||
|
||||
// 获取当前视口大小计算宽高比
|
||||
const auto& viewport = View_->getViewport();
|
||||
double aspect = 1.0;
|
||||
if (viewport.height > 0) {
|
||||
aspect = static_cast<double>(viewport.width) / static_cast<double>(viewport.height);
|
||||
}
|
||||
|
||||
// 设置透视投影
|
||||
double fov = sceneView.VerticalFieldOfViewDegrees;
|
||||
double nearClip = 0.1;
|
||||
double farClip = 1000.0;
|
||||
|
||||
Camera_->setProjection(fov, aspect, nearClip, farClip, filament::Camera::Fov::VERTICAL);
|
||||
}
|
||||
|
||||
void Render() {
|
||||
if (Renderer_ && SwapChain_ && View_) {
|
||||
filament::Renderer::ClearOptions options;
|
||||
options.clearColor = { 1.0f, 0.0f, 1.0f, 1.0f }; // 粉色,方便辨认
|
||||
options.clear = true;
|
||||
Renderer_->setClearOptions(options);
|
||||
|
||||
if (Renderer_->beginFrame(SwapChain_)) {
|
||||
Renderer_->render(View_);
|
||||
Renderer_->endFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t GetGLTextureId() const {
|
||||
return GLTextureId_;
|
||||
}
|
||||
|
||||
bool TryGetObjectWorldMatrix(MetaCoreId objectId, glm::mat4& worldMatrix) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasRuntimeSyncFailure() const { return false; }
|
||||
const std::string& GetLastRuntimeSyncFailure() const { return EmptyString_; }
|
||||
|
||||
private:
|
||||
void UpdateTransform(const MetaCoreGameObject& gameObject) {
|
||||
auto it = LoadedAssets_.find(gameObject.GetId());
|
||||
if (it == LoadedAssets_.end()) return;
|
||||
|
||||
filament::gltfio::FilamentAsset* asset = it->second;
|
||||
utils::Entity rootEntity = asset->getRoot();
|
||||
|
||||
auto& tm = Engine_->getTransformManager();
|
||||
auto instance = tm.getInstance(rootEntity);
|
||||
if (instance) {
|
||||
if (!gameObject.HasComponent<MetaCoreTransformComponent>()) return;
|
||||
|
||||
const auto& transform = gameObject.GetComponent<MetaCoreTransformComponent>();
|
||||
|
||||
glm::mat4 matrix = glm::mat4(1.0f);
|
||||
matrix = glm::translate(matrix, transform.Position);
|
||||
matrix = glm::rotate(matrix, glm::radians(transform.RotationEulerDegrees.x), {1, 0, 0});
|
||||
matrix = glm::rotate(matrix, glm::radians(transform.RotationEulerDegrees.y), {0, 1, 0});
|
||||
matrix = glm::rotate(matrix, glm::radians(transform.RotationEulerDegrees.z), {0, 0, 1});
|
||||
matrix = glm::scale(matrix, transform.Scale);
|
||||
|
||||
tm.setTransform(instance, *reinterpret_cast<const filament::math::mat4f*>(glm::value_ptr(matrix)));
|
||||
}
|
||||
}
|
||||
|
||||
filament::Engine* Engine_ = nullptr;
|
||||
filament::SwapChain* SwapChain_ = nullptr;
|
||||
filament::Renderer* Renderer_ = nullptr;
|
||||
filament::Scene* Scene_ = nullptr;
|
||||
filament::Camera* Camera_ = nullptr;
|
||||
filament::View* View_ = nullptr;
|
||||
|
||||
filament::gltfio::AssetLoader* AssetLoader_ = nullptr;
|
||||
filament::gltfio::MaterialProvider* MaterialProvider_ = nullptr;
|
||||
|
||||
std::unordered_map<MetaCoreId, filament::gltfio::FilamentAsset*> LoadedAssets_;
|
||||
|
||||
GLuint GLTextureId_ = 0;
|
||||
filament::Texture* FilamentTexture_ = nullptr;
|
||||
filament::Texture* DepthTexture_ = nullptr;
|
||||
filament::RenderTarget* RenderTarget_ = nullptr;
|
||||
utils::Entity Light_;
|
||||
|
||||
std::filesystem::path ProjectRootPath_{};
|
||||
std::string EmptyString_{};
|
||||
};
|
||||
|
||||
MetaCoreFilamentSceneBridge::MetaCoreFilamentSceneBridge()
|
||||
: Impl_(std::make_unique<MetaCoreFilamentSceneBridgeImpl>()) {}
|
||||
|
||||
MetaCoreFilamentSceneBridge::~MetaCoreFilamentSceneBridge() = default;
|
||||
|
||||
bool MetaCoreFilamentSceneBridge::Initialize(MetaCoreWindow& window) {
|
||||
return Impl_->Initialize(window);
|
||||
}
|
||||
|
||||
void MetaCoreFilamentSceneBridge::Shutdown() {
|
||||
Impl_->Shutdown();
|
||||
}
|
||||
|
||||
void MetaCoreFilamentSceneBridge::SetProjectRootPath(const std::filesystem::path& projectRootPath) {
|
||||
Impl_->SetProjectRootPath(projectRootPath);
|
||||
}
|
||||
|
||||
void MetaCoreFilamentSceneBridge::SyncScene(const MetaCoreScene& scene, bool compatibilityMeshOnly) {
|
||||
Impl_->SyncScene(scene, compatibilityMeshOnly);
|
||||
}
|
||||
|
||||
void MetaCoreFilamentSceneBridge::ApplySceneView(const MetaCoreSceneView& sceneView) {
|
||||
Impl_->ApplySceneView(sceneView);
|
||||
}
|
||||
|
||||
void MetaCoreFilamentSceneBridge::Render() {
|
||||
Impl_->Render();
|
||||
}
|
||||
|
||||
uint32_t MetaCoreFilamentSceneBridge::GetGLTextureId() const {
|
||||
return Impl_->GetGLTextureId();
|
||||
}
|
||||
|
||||
bool MetaCoreFilamentSceneBridge::TryGetObjectWorldMatrix(MetaCoreId objectId, glm::mat4& worldMatrix) const {
|
||||
return Impl_->TryGetObjectWorldMatrix(objectId, worldMatrix);
|
||||
}
|
||||
|
||||
bool MetaCoreFilamentSceneBridge::HasRuntimeSyncFailure() const {
|
||||
return Impl_->HasRuntimeSyncFailure();
|
||||
}
|
||||
|
||||
const std::string& MetaCoreFilamentSceneBridge::GetLastRuntimeSyncFailure() const {
|
||||
return Impl_->GetLastRuntimeSyncFailure();
|
||||
}
|
||||
|
||||
} // namespace MetaCore
|
||||
@ -1,30 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "MetaCoreRender/MetaCorePandaSceneBridge.h"
|
||||
#include "MetaCoreRender/MetaCoreFilamentSceneBridge.h"
|
||||
#include "MetaCoreRender/MetaCoreRenderTypes.h"
|
||||
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
namespace MetaCore {
|
||||
|
||||
class MetaCoreRenderDevice;
|
||||
class MetaCoreWindow;
|
||||
class MetaCoreScene;
|
||||
|
||||
class MetaCoreEditorViewportRenderer {
|
||||
public:
|
||||
bool Initialize(MetaCoreRenderDevice& renderDevice);
|
||||
bool Initialize(MetaCoreRenderDevice& renderDevice, MetaCoreWindow& window);
|
||||
void Shutdown();
|
||||
void SetViewportRect(const MetaCoreViewportRect& viewportRect);
|
||||
void RenderSceneToViewport(const MetaCoreScene& scene, const MetaCoreSceneView& sceneView);
|
||||
void SetProjectRootPath(const std::filesystem::path& projectRootPath);
|
||||
[[nodiscard]] uint32_t GetFilamentGLTextureId() const;
|
||||
|
||||
[[nodiscard]] bool TryGetObjectWorldMatrix(MetaCoreId objectId, glm::mat4& worldMatrix) const;
|
||||
|
||||
private:
|
||||
MetaCoreRenderDevice* RenderDevice_ = nullptr;
|
||||
MetaCorePandaSceneBridge SceneBridge_{};
|
||||
MetaCoreFilamentSceneBridge FilamentSceneBridge_{};
|
||||
MetaCoreViewportRect ViewportRect_{};
|
||||
|
||||
};
|
||||
|
||||
} // namespace MetaCore
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "MetaCoreFoundation/MetaCoreId.h"
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace MetaCore {
|
||||
|
||||
class MetaCoreWindow;
|
||||
class MetaCoreScene;
|
||||
struct MetaCoreSceneView;
|
||||
|
||||
/**
|
||||
* @brief Filament 场景桥接器,负责将 MetaCore 的场景数据同步到 Filament 渲染引擎中
|
||||
*/
|
||||
class MetaCoreFilamentSceneBridge {
|
||||
public:
|
||||
MetaCoreFilamentSceneBridge();
|
||||
~MetaCoreFilamentSceneBridge();
|
||||
|
||||
bool Initialize(MetaCoreWindow& window);
|
||||
void Shutdown();
|
||||
void SetProjectRootPath(const std::filesystem::path& projectRootPath);
|
||||
void SyncScene(const MetaCoreScene& scene, bool compatibilityMeshOnly = false);
|
||||
void ApplySceneView(const MetaCoreSceneView& sceneView);
|
||||
void Render();
|
||||
[[nodiscard]] uint32_t GetGLTextureId() const;
|
||||
|
||||
[[nodiscard]] bool TryGetObjectWorldMatrix(MetaCoreId objectId, glm::mat4& worldMatrix) const;
|
||||
[[nodiscard]] bool HasRuntimeSyncFailure() const;
|
||||
[[nodiscard]] const std::string& GetLastRuntimeSyncFailure() const;
|
||||
|
||||
private:
|
||||
class MetaCoreFilamentSceneBridgeImpl;
|
||||
std::unique_ptr<MetaCoreFilamentSceneBridgeImpl> Impl_{};
|
||||
};
|
||||
|
||||
} // namespace MetaCore
|
||||
51
cmake/MetaCoreFilament.cmake
Normal file
51
cmake/MetaCoreFilament.cmake
Normal file
@ -0,0 +1,51 @@
|
||||
# Filament SDK configuration for MetaCore
|
||||
|
||||
set(METACORE_FILAMENT_ROOT "${CMAKE_SOURCE_DIR}/third_party/filament_installed" CACHE PATH "Path to installed Filament SDK")
|
||||
set(METACORE_FILAMENT_INCLUDE_DIR "${METACORE_FILAMENT_ROOT}/include")
|
||||
set(METACORE_FILAMENT_LIB_DIR "${METACORE_FILAMENT_ROOT}/lib/x86_64")
|
||||
|
||||
function(metacore_use_filament target_name)
|
||||
if(NOT TARGET ${target_name})
|
||||
message(FATAL_ERROR "Target ${target_name} does not exist.")
|
||||
endif()
|
||||
|
||||
message(STATUS "Linking Filament to ${target_name}")
|
||||
|
||||
# 定义核心库
|
||||
set(_filament_libs
|
||||
"${METACORE_FILAMENT_LIB_DIR}/filament.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/backend.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/utils.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/filabridge.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/filaflat.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/filamat.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/shaders.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/bluegl.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/gltfio.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/gltfio_core.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/abseil.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/perfetto.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/dracodec.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/geometry.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/smol-v.lib"
|
||||
"${METACORE_FILAMENT_LIB_DIR}/zstd.lib"
|
||||
opengl32.lib
|
||||
gdi32.lib
|
||||
user32.lib
|
||||
shlwapi.lib
|
||||
)
|
||||
|
||||
target_include_directories(${target_name} PRIVATE "${METACORE_FILAMENT_INCLUDE_DIR}")
|
||||
target_link_libraries(${target_name} PRIVATE ${_filament_libs})
|
||||
|
||||
# Filament 需要 C++17 或更高版本
|
||||
target_compile_features(${target_name} PRIVATE cxx_std_17)
|
||||
|
||||
# 针对 MSVC 的一些必要宏定义
|
||||
if(MSVC)
|
||||
target_compile_definitions(${target_name} PRIVATE
|
||||
WIN32_LEAN_AND_MEAN
|
||||
_CRT_SECURE_NO_WARNINGS
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
Loading…
Reference in New Issue
Block a user