Init Repo

This commit is contained in:
2026-06-03 09:00:11 +08:00
commit 9be48d8b9e
155 changed files with 14827 additions and 0 deletions
+255
View File
@@ -0,0 +1,255 @@
#include "ImGuiContext.h"
#include "../utils/Logger.h"
#include "../utils/GLExt.h"
#include "../utils/PathUtils.h"
#include <imgui.h>
#include <imgui_impl_win32.h>
#include <imgui_impl_opengl3.h>
// Forward declare message handler from imgui_impl_win32.cpp
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
namespace UsdLayerManager {
ImGuiContext::ImGuiContext()
: m_hwnd(nullptr)
, m_hdc(nullptr)
, m_hglrc(nullptr)
, m_shouldClose(false)
, m_width(1280)
, m_height(720) {
}
ImGuiContext::~ImGuiContext() {
Shutdown();
}
bool ImGuiContext::Initialize(const std::string& windowTitle, int width, int height) {
m_width = width;
m_height = height;
LOG_INFO("Initializing ImGui context...");
// Create application window
WNDCLASSEXW wc = {
sizeof(wc),
CS_OWNDC,
WndProc,
0L,
0L,
GetModuleHandle(nullptr),
nullptr,
nullptr,
nullptr,
nullptr,
L"UsdLayerManager",
nullptr
};
::RegisterClassExW(&wc);
m_hwnd = ::CreateWindowW(
wc.lpszClassName,
L"USD Layer Manager",
WS_OVERLAPPEDWINDOW,
100, 100,
m_width, m_height,
nullptr,
nullptr,
wc.hInstance,
nullptr
);
if (!m_hwnd) {
LOG_ERROR("Failed to create window");
return false;
}
// Store this pointer in window user data
::SetWindowLongPtr(m_hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
// Initialize OpenGL
if (!CreateDeviceWGL()) {
LOG_ERROR("Failed to initialize OpenGL");
::DestroyWindow(m_hwnd);
::UnregisterClassW(wc.lpszClassName, wc.hInstance);
return false;
}
// Initialize OpenGL extensions
if (!GL::InitExtensions()) {
LOG_ERROR("Failed to initialize OpenGL extensions");
}
// Show the window
::ShowWindow(m_hwnd, SW_SHOWDEFAULT);
::UpdateWindow(m_hwnd);
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
// DockingEnable only — NavEnableKeyboard is intentionally omitted for a DCC
// viewport application that manages its own keyboard shortcuts.
// With NavEnableKeyboard set, io.WantCaptureKeyboard becomes true whenever any
// ImGui window is focused, which would block all viewport hotkeys (F, A, etc.).
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
// Load Inter font.
// The build directory copies the font as Inter.ttc; the install step renames
// it to Inter.ttf. Try .ttf first (install layout), fall back to .ttc (build).
{
ImFontConfig fontConfig;
fontConfig.FontNo = 0; // select Regular face from the .ttc collection
// Build exe-relative font paths so they work from both build and install dirs
std::string fontPath0 = ResourcePath("resources/font/Inter.ttf");
std::string fontPath1 = ResourcePath("resources/font/Inter.ttc");
const char* tryPaths[] = { fontPath0.c_str(), fontPath1.c_str() };
bool loaded = false;
for (const char* p : tryPaths) {
ImFont* f = io.Fonts->AddFontFromFileTTF(p, 16.0f, &fontConfig);
if (f) {
LOG_INFO(std::string("Loaded Inter font from ") + p);
loaded = true;
break;
}
}
if (!loaded) {
LOG_WARNING("Could not load Inter font; using built-in default");
io.Fonts->AddFontDefault();
}
}
// Setup Dear ImGui style
ImGui::StyleColorsDark();
// Setup Platform/Renderer backends
ImGui_ImplWin32_Init(m_hwnd);
ImGui_ImplOpenGL3_Init("#version 130");
LOG_INFO("ImGui context initialized successfully");
return true;
}
void ImGuiContext::Shutdown() {
if (m_hwnd) {
LOG_INFO("Shutting down ImGui context...");
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyPlatformWindows();
ImGui::DestroyContext();
CleanupDeviceWGL();
::DestroyWindow(m_hwnd);
::UnregisterClassW(L"UsdLayerManager", ::GetModuleHandle(nullptr));
m_hwnd = nullptr;
}
}
void ImGuiContext::NewFrame() {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
}
void ImGuiContext::Render() {
ImGui::Render();
glViewport(0, 0, m_width, m_height);
glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
::SwapBuffers(m_hdc);
}
bool ImGuiContext::ProcessEvents() {
MSG msg;
while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE)) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
if (msg.message == WM_QUIT) {
m_shouldClose = true;
}
}
return !m_shouldClose;
}
bool ImGuiContext::CreateDeviceWGL() {
m_hdc = ::GetDC(m_hwnd);
PIXELFORMATDESCRIPTOR pfd = {};
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
int pixelFormat = ::ChoosePixelFormat(m_hdc, &pfd);
if (pixelFormat == 0) {
LOG_ERROR("ChoosePixelFormat failed");
return false;
}
if (!::SetPixelFormat(m_hdc, pixelFormat, &pfd)) {
LOG_ERROR("SetPixelFormat failed");
return false;
}
m_hglrc = ::wglCreateContext(m_hdc);
if (!m_hglrc) {
LOG_ERROR("wglCreateContext failed");
return false;
}
if (!::wglMakeCurrent(m_hdc, m_hglrc)) {
LOG_ERROR("wglMakeCurrent failed");
return false;
}
return true;
}
void ImGuiContext::CleanupDeviceWGL() {
if (m_hglrc) {
::wglMakeCurrent(nullptr, nullptr);
::wglDeleteContext(m_hglrc);
m_hglrc = nullptr;
}
if (m_hdc) {
::ReleaseDC(m_hwnd, m_hdc);
m_hdc = nullptr;
}
}
LRESULT WINAPI ImGuiContext::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) {
return true;
}
ImGuiContext* context = reinterpret_cast<ImGuiContext*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
switch (msg) {
case WM_SIZE:
if (context && wParam != SIZE_MINIMIZED) {
context->m_width = LOWORD(lParam);
context->m_height = HIWORD(lParam);
}
return 0;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
break;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProcW(hWnd, msg, wParam, lParam);
}
} // namespace UsdLayerManager