feat: 实现 Filament 离屏渲染与 ImGui 视口嵌合(打通 RTT 管线)

This commit is contained in:
ayuan9957 2026-05-14 15:36:17 +08:00
parent 2799ddc0e3
commit 3bf03f4b1f
8 changed files with 543 additions and 7 deletions

View File

@ -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;
}

View File

@ -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
)

View File

@ -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();

View File

@ -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 {

View 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

View File

@ -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

View File

@ -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

View 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()