172 lines
5.7 KiB
C++
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;
|
|
}
|