129 lines
4.5 KiB
C++
129 lines
4.5 KiB
C++
#include <filament/Camera.h>
|
|
#include <filament/Engine.h>
|
|
#include <filament/RenderTarget.h>
|
|
#include <filament/Renderer.h>
|
|
#include <filament/Scene.h>
|
|
#include <filament/Skybox.h>
|
|
#include <filament/SwapChain.h>
|
|
#include <filament/Texture.h>
|
|
#include <filament/View.h>
|
|
#include <filament/Viewport.h>
|
|
#include <imgui.h>
|
|
#include <utils/Entity.h>
|
|
#include <utils/EntityManager.h>
|
|
|
|
#include "MetaCoreRender/MetaCoreImGuiHelper.h"
|
|
|
|
#include <cstdint>
|
|
#include <iostream>
|
|
|
|
using namespace filament;
|
|
|
|
int main() {
|
|
constexpr std::uint32_t displayWidth = 1280;
|
|
constexpr std::uint32_t displayHeight = 720;
|
|
constexpr std::uint32_t viewportWidth = 800;
|
|
constexpr std::uint32_t viewportHeight = 600;
|
|
|
|
std::cout << "[Demo] Creating headless Filament engine..." << std::endl;
|
|
// uiBlit currently ships OpenGL shader material data. The swap chain is
|
|
// offscreen, while Filament's Linux OpenGL platform still requires X11.
|
|
Engine* engine = Engine::create(Engine::Backend::OPENGL);
|
|
if (engine == nullptr) {
|
|
std::cerr << "[Demo] Failed to create Filament engine." << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
Renderer* renderer = engine->createRenderer();
|
|
SwapChain* swapChain = engine->createSwapChain(displayWidth, displayHeight);
|
|
Scene* scene = engine->createScene();
|
|
View* sceneView = engine->createView();
|
|
View* uiView = engine->createView();
|
|
if (renderer == nullptr || swapChain == nullptr || scene == nullptr ||
|
|
sceneView == nullptr || uiView == nullptr) {
|
|
std::cerr << "[Demo] Failed to create Filament headless resources." << std::endl;
|
|
Engine::destroy(&engine);
|
|
return 1;
|
|
}
|
|
|
|
utils::Entity cameraEntity = utils::EntityManager::get().create();
|
|
Camera* camera = engine->createCamera(cameraEntity);
|
|
sceneView->setScene(scene);
|
|
sceneView->setCamera(camera);
|
|
|
|
Skybox* skybox = Skybox::Builder()
|
|
.color({1.0F, 0.0F, 1.0F, 1.0F})
|
|
.build(*engine);
|
|
scene->setSkybox(skybox);
|
|
|
|
Texture* viewportTexture = Texture::Builder()
|
|
.width(viewportWidth)
|
|
.height(viewportHeight)
|
|
.levels(1)
|
|
.usage(Texture::Usage::COLOR_ATTACHMENT | Texture::Usage::SAMPLEABLE)
|
|
.format(Texture::InternalFormat::RGBA8)
|
|
.build(*engine);
|
|
RenderTarget* renderTarget = RenderTarget::Builder()
|
|
.texture(RenderTarget::AttachmentPoint::COLOR, viewportTexture)
|
|
.build(*engine);
|
|
|
|
sceneView->setRenderTarget(renderTarget);
|
|
sceneView->setViewport({0, 0, viewportWidth, viewportHeight});
|
|
sceneView->setPostProcessingEnabled(true);
|
|
uiView->setViewport({0, 0, displayWidth, displayHeight});
|
|
uiView->setPostProcessingEnabled(false);
|
|
|
|
IMGUI_CHECKVERSION();
|
|
ImGui::CreateContext();
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
io.DisplaySize = ImVec2(static_cast<float>(displayWidth), static_cast<float>(displayHeight));
|
|
io.DeltaTime = 1.0F / 60.0F;
|
|
|
|
{
|
|
MetaCore::MetaCoreImGuiHelper imguiHelper(engine, uiView, "", ImGui::GetCurrentContext());
|
|
imguiHelper.setDisplaySize(displayWidth, displayHeight);
|
|
|
|
// This is a deterministic offscreen smoke demo rather than an interactive
|
|
// platform window. A few frames are enough to exercise both render paths.
|
|
for (int frame = 0; frame < 3; ++frame) {
|
|
if (!renderer->beginFrame(swapChain)) {
|
|
continue;
|
|
}
|
|
|
|
renderer->render(sceneView);
|
|
|
|
ImGui::NewFrame();
|
|
ImGui::SetNextWindowSize(ImVec2(820.0F, 640.0F), ImGuiCond_Always);
|
|
ImGui::Begin("3D Viewport");
|
|
ImGui::Image(
|
|
reinterpret_cast<ImTextureID>(viewportTexture),
|
|
ImVec2(static_cast<float>(viewportWidth), static_cast<float>(viewportHeight)),
|
|
ImVec2(0.0F, 1.0F),
|
|
ImVec2(1.0F, 0.0F)
|
|
);
|
|
ImGui::End();
|
|
ImGui::Render();
|
|
|
|
imguiHelper.processImGuiCommands(ImGui::GetDrawData(), io);
|
|
renderer->render(uiView);
|
|
renderer->endFrame();
|
|
}
|
|
}
|
|
|
|
ImGui::DestroyContext();
|
|
engine->destroy(renderTarget);
|
|
engine->destroy(viewportTexture);
|
|
engine->destroy(skybox);
|
|
engine->destroy(sceneView);
|
|
engine->destroy(uiView);
|
|
engine->destroy(scene);
|
|
engine->destroyCameraComponent(cameraEntity);
|
|
utils::EntityManager::get().destroy(cameraEntity);
|
|
engine->destroy(renderer);
|
|
engine->destroy(swapChain);
|
|
Engine::destroy(&engine);
|
|
|
|
std::cout << "[Demo] Headless render completed." << std::endl;
|
|
return 0;
|
|
}
|