MetaCore/tests/FilamentImGuiDemo.cpp

172 lines
5.7 KiB
C++

#include <windows.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/Texture.h>
#include <filament/RenderTarget.h>
#include <filament/Skybox.h>
#include <imgui.h>
#include "MetaCoreRender/MetaCoreImGuiHelper.h"
#include <utils/Entity.h>
#include <utils/EntityManager.h>
#include <iostream>
#include <chrono>
using namespace filament;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
int main() {
std::cout << "[Demo] Starting..." << std::endl;
HINSTANCE hInstance = GetModuleHandle(nullptr);
int nCmdShow = SW_SHOW;
// 1. 注册窗口类
std::cout << "[Demo] Registering window class..." << std::endl;
WNDCLASSEXW wcex = {0};
wcex.cbSize = sizeof(WNDCLASSEXW);
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.lpszClassName = L"FilamentImGuiDemoClass";
RegisterClassExW(&wcex);
// 2. 创建窗口
std::cout << "[Demo] Creating window..." << std::endl;
HWND hWnd = CreateWindowExW(0, L"FilamentImGuiDemoClass", L"Filament + ImGui 离屏渲染最小化 Demo", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720, nullptr, nullptr, hInstance, nullptr);
if (!hWnd) {
std::cout << "[Demo] Failed to create window!" << std::endl;
return -1;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// 3. 初始化 Filament
std::cout << "[Demo] Creating Filament Engine (OpenGL)..." << std::endl;
Engine* engine = Engine::create(Engine::Backend::OPENGL);
if (!engine) {
std::cout << "[Demo] Failed to create Engine!" << std::endl;
return -1;
}
std::cout << "[Demo] Creating Renderer..." << std::endl;
Renderer* renderer = engine->createRenderer();
std::cout << "[Demo] Creating SwapChain..." << std::endl;
SwapChain* swapChain = engine->createSwapChain(hWnd);
std::cout << "[Demo] Creating Scene..." << std::endl;
Scene* scene = engine->createScene();
std::cout << "[Demo] Creating View..." << std::endl;
View* view = engine->createView();
view->setScene(scene);
std::cout << "[Demo] Creating Camera..." << std::endl;
utils::Entity cameraEntity = utils::EntityManager::get().create();
Camera* camera = engine->createCamera(cameraEntity);
view->setCamera(camera);
view->setViewport({0, 0, 1280, 720});
std::cout << "[Demo] Creating Skybox..." << std::endl;
Skybox* skybox = Skybox::Builder().color({1.0f, 0.0f, 1.0f, 1.0f}).build(*engine);
scene->setSkybox(skybox);
// 4. 创建离屏 RenderTarget
std::cout << "[Demo] Creating offscreen texture..." << std::endl;
Texture* viewportTexture = Texture::Builder()
.width(800).height(600).levels(1)
.usage(Texture::Usage::COLOR_ATTACHMENT | Texture::Usage::SAMPLEABLE)
.format(Texture::InternalFormat::RGBA8)
.build(*engine);
std::cout << "[Demo] Creating RenderTarget..." << std::endl;
RenderTarget* renderTarget = RenderTarget::Builder()
.texture(RenderTarget::AttachmentPoint::COLOR, viewportTexture)
.build(*engine);
std::cout << "[Demo] Creating offscreen View..." << std::endl;
View* offscreenView = engine->createView();
offscreenView->setScene(scene);
offscreenView->setCamera(camera);
offscreenView->setRenderTarget(renderTarget);
offscreenView->setViewport({0, 0, 800, 600});
offscreenView->setPostProcessingEnabled(true);
// 5. 初始化 ImGui
std::cout << "[Demo] Initializing ImGui..." << std::endl;
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2(1280, 720);
std::cout << "[Demo] Creating UI View..." << std::endl;
View* uiView = engine->createView();
uiView->setViewport({0, 0, 1280, 720});
uiView->setPostProcessingEnabled(false);
std::cout << "[Demo] Creating MetaCoreImGuiHelper..." << std::endl;
MetaCore::MetaCoreImGuiHelper imguiHelper(engine, uiView, "C:\\Windows\\Fonts\\msyh.ttc");
std::cout << "[Demo] Setting Display Size..." << std::endl;
imguiHelper.setDisplaySize(1280, 720);
std::cout << "[Demo] Entering message loop..." << std::endl;
MSG msg = {0};
bool quit = false;
while (!quit) {
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) quit = true;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (renderer->beginFrame(swapChain)) {
// 1. 渲染离屏 3D 场景
renderer->render(offscreenView);
// 2. 构建 ImGui 界面
ImGui::NewFrame();
ImGui::SetNextWindowSize(ImVec2(820, 640), ImGuiCond_FirstUseEver);
ImGui::Begin("3D Viewport");
ImGui::Image((void*)viewportTexture, ImVec2(800, 600), ImVec2(0, 1), ImVec2(1, 0));
ImGui::End();
ImGui::Render();
// 3. 处理 ImGui 命令
imguiHelper.processImGuiCommands(ImGui::GetDrawData(), io);
// 4. 渲染 UI
renderer->render(uiView);
renderer->endFrame();
}
Sleep(16);
}
std::cout << "[Demo] Cleaning up..." << std::endl;
// 省略详细清理,由操作系统回收
return 0;
}