init
This commit is contained in:
289
third/imgui/imgui_helper.cpp
Normal file
289
third/imgui/imgui_helper.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
#include "imgui_helper.h"
|
||||
#include "ComKit.h"
|
||||
#include "imgui.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include <dbt.h>
|
||||
#include <format>
|
||||
#ifdef _WIN32
|
||||
bool ImGuiHelper::CreateDeviceD3d(HWND hWnd) {
|
||||
DXGI_SWAP_CHAIN_DESC sd = {0};
|
||||
sd.BufferCount = 2;
|
||||
sd.BufferDesc.Width = 0;
|
||||
sd.BufferDesc.Height = 0;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.BufferDesc.RefreshRate.Numerator = 60;
|
||||
sd.BufferDesc.RefreshRate.Denominator = 1;
|
||||
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.OutputWindow = hWnd;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.Windowed = true;
|
||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
|
||||
UINT createDeviceFlags = 0;
|
||||
D3D_FEATURE_LEVEL featureLevel;
|
||||
const D3D_FEATURE_LEVEL featureLevelArray[2] = {D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_0};
|
||||
HRESULT res = D3D11CreateDeviceAndSwapChain(
|
||||
nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags,
|
||||
featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain,
|
||||
&g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
|
||||
if (res == DXGI_ERROR_UNSUPPORTED) {
|
||||
res = D3D11CreateDeviceAndSwapChain(
|
||||
nullptr, D3D_DRIVER_TYPE_WARP, nullptr, createDeviceFlags,
|
||||
featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain,
|
||||
&g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
|
||||
}
|
||||
if (res != S_OK)
|
||||
return false;
|
||||
CreateRenderTarget();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGuiHelper::CleanupDeviceD3d() {
|
||||
CleanupRenderTarget();
|
||||
if (g_pSwapChain) {
|
||||
g_pSwapChain->Release();
|
||||
g_pSwapChain = nullptr;
|
||||
}
|
||||
if (g_pd3dDeviceContext) {
|
||||
g_pd3dDeviceContext->Release();
|
||||
g_pSwapChain = nullptr;
|
||||
}
|
||||
if (g_pd3dDevice) {
|
||||
g_pd3dDevice->Release();
|
||||
g_pd3dDevice = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiHelper::CleanupRenderTarget() {
|
||||
if (g_pMainRenderTargetView) {
|
||||
g_pMainRenderTargetView->Release();
|
||||
g_pMainRenderTargetView = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiHelper::CreateRenderTarget() {
|
||||
ID3D11Texture2D *pBackBuffer;
|
||||
g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr,
|
||||
&g_pMainRenderTargetView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
|
||||
LRESULT ImGuiHelper::WndProc(HWND hWnd, UINT msg, WPARAM wParam,
|
||||
LPARAM lParam) {
|
||||
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) {
|
||||
return true;
|
||||
}
|
||||
switch (msg) {
|
||||
case WM_SYSCOMMAND:
|
||||
if ((wParam & 0xfff0) == SC_KEYMENU) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
::PostQuitMessage(0);
|
||||
return 0;
|
||||
case WM_DEVICECHANGE:
|
||||
PDEV_BROADCAST_HDR pHdr = reinterpret_cast<PDEV_BROADCAST_HDR>(lParam);
|
||||
switch (wParam) {
|
||||
case DBT_DEVICEARRIVAL:
|
||||
if (pHdr->dbch_devicetype == DBT_DEVTYP_PORT) {
|
||||
PDEV_BROADCAST_PORT pPort =
|
||||
reinterpret_cast<PDEV_BROADCAST_PORT>(pHdr);
|
||||
spdlog::log(spdlog::level::debug,
|
||||
std::format("port: [{}] add", pPort->dbcp_name));
|
||||
ComKit::FlushLog();
|
||||
ComKit::GetAllComPortNames();
|
||||
ComKit::Work();
|
||||
} else {
|
||||
spdlog::log(spdlog::level::debug,
|
||||
std::format("port: other device [{}] add",
|
||||
pHdr->dbch_devicetype));
|
||||
}
|
||||
break;
|
||||
case DBT_DEVICEREMOVECOMPLETE:
|
||||
if (pHdr->dbch_devicetype == DBT_DEVTYP_PORT) {
|
||||
PDEV_BROADCAST_PORT pPort =
|
||||
reinterpret_cast<PDEV_BROADCAST_PORT>(pHdr);
|
||||
spdlog::log(
|
||||
spdlog::level::debug,
|
||||
std::format("port: [{}] removed", pPort->dbcp_name));
|
||||
ComKit::FlushLog();
|
||||
ComKit::GetAllComPortNames();
|
||||
} else {
|
||||
spdlog::log(spdlog::level::debug,
|
||||
std::format("port: other device [{}] add",
|
||||
pHdr->dbch_devicetype));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ::DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
ImGuiHelper::ImGuiHelper(int width, int height, const char *windowTitle) {
|
||||
this->windowTitle = *windowTitle;
|
||||
wc = {sizeof(wc), CS_CLASSDC, WndProc,
|
||||
0L, 0L, GetModuleHandle(nullptr),
|
||||
nullptr, nullptr, nullptr,
|
||||
nullptr, "Windows", nullptr};
|
||||
::RegisterClassEx(&wc);
|
||||
hWnd = ::CreateWindow(wc.lpszClassName, windowTitle, WS_OVERLAPPEDWINDOW,
|
||||
100, 100, width, height, nullptr, nullptr,
|
||||
wc.hInstance, nullptr);
|
||||
if (!CreateDeviceD3d(hWnd)) {
|
||||
CleanupDeviceD3d();
|
||||
::UnregisterClass(wc.lpszClassName, wc.hInstance);
|
||||
return;
|
||||
}
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
(void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
io.ConfigViewportsNoAutoMerge = true;
|
||||
io.ConfigViewportsNoTaskBarIcon = false;
|
||||
|
||||
ImGui::StyleColorsLight();
|
||||
ImGui_ImplWin32_Init(hWnd);
|
||||
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
|
||||
}
|
||||
|
||||
void ImGuiHelper::Render(const std::function<void()> &context,
|
||||
bool &isRunning) {
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
::ShowWindow(hWnd, SW_HIDE);
|
||||
UpdateWindow(hWnd);
|
||||
MSG msg;
|
||||
while (isRunning) {
|
||||
while (::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
if (msg.message == WM_QUIT) {
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
context();
|
||||
ImGui::Render();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
const float clear_color_with_alpha[4] = {
|
||||
clear_color.x * clear_color.w, clear_color.y * clear_color.w,
|
||||
clear_color.z * clear_color.w, clear_color.w};
|
||||
g_pd3dDeviceContext->OMSetRenderTargets(1, &g_pMainRenderTargetView,
|
||||
nullptr);
|
||||
g_pd3dDeviceContext->ClearRenderTargetView(g_pMainRenderTargetView,
|
||||
clear_color_with_alpha);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
g_pSwapChain->Present(1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiHelper::~ImGuiHelper() {
|
||||
ImGui_ImplDX11_Shutdown();
|
||||
ImGui_ImplWin32_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
::DestroyWindow(hWnd);
|
||||
::UnregisterClass(wc.lpszClassName, wc.hInstance);
|
||||
}
|
||||
#elif __linux__
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
static void glfw_error_callback(int error, const char *description) {
|
||||
fprintf(stderr, "GLFW ERROR %d: %s\n", error, description);
|
||||
}
|
||||
|
||||
const char *ImGuiHelper::glsl_version = "#version 150";
|
||||
|
||||
ImGuiHelper::ImGuiHelper(int width, int height, const std::string &windowTitle)
|
||||
: width(width), height(height), windowTitle(windowTitle) {
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
window =
|
||||
glfwCreateWindow(width, height, windowTitle.c_str(), nullptr, nullptr);
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
io = &ImGui::GetIO();
|
||||
(void)io;
|
||||
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
io->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
||||
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
io->ConfigViewportsNoAutoMerge = true;
|
||||
ImGuiStyle &style = ImGui::GetStyle();
|
||||
if (io->ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
|
||||
style.WindowRounding = .0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.f;
|
||||
}
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplOpenGL3_Init(ImGuiHelper::glsl_version);
|
||||
}
|
||||
|
||||
void ImGuiHelper::Render(const std::function<void()> &context,
|
||||
bool &isRunning) {
|
||||
ImVec4 clear_color = ImVec4{.45f, .55f, .60f, 1.f};
|
||||
while (isRunning) {
|
||||
glfwPollEvents();
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
context();
|
||||
|
||||
// Rending
|
||||
ImGui::Render();
|
||||
int display_w, display_h;
|
||||
glfwGetFramebufferSize(window, &display_w, &display_h);
|
||||
glViewport(0, 0, display_w, display_h);
|
||||
glClearColor(clear_color.x * clear_color.w,
|
||||
clear_color.y * clear_color.w,
|
||||
clear_color.z * clear_color.w, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
if (io->ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
|
||||
GLFWwindow *backup_current_context = glfwGetCurrentContext();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
glfwMakeContextCurrent(backup_current_context);
|
||||
}
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
ImGuiHelper::~ImGuiHelper() {
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user