Init Repo
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user