Skip to content

Commit

Permalink
Examples: Extend Win32/Winapi + OpenGL example for multi-viewport. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
learn-more authored and ocornut committed Apr 19, 2023
1 parent 1f2b84a commit 4bc51c6
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 5 deletions.
9 changes: 4 additions & 5 deletions backends/imgui_impl_win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
// 2016-11-12: Inputs: Only call Win32 ::SetCursor(nullptr) when io.MouseDrawCursor is set.

// Forward Declarations
static void ImGui_ImplWin32_InitPlatformInterface();
static void ImGui_ImplWin32_InitPlatformInterface(bool platformHasOwnDC);
static void ImGui_ImplWin32_ShutdownPlatformInterface();
static void ImGui_ImplWin32_UpdateMonitors();

Expand Down Expand Up @@ -153,8 +153,7 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd;
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
ImGui_ImplWin32_InitPlatformInterface();
IM_UNUSED(platform_has_own_dc); // Used in 'docking' branch
ImGui_ImplWin32_InitPlatformInterface(platform_has_own_dc);

// Dynamically load XInput library
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
Expand Down Expand Up @@ -1166,11 +1165,11 @@ static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd,
return DefWindowProc(hWnd, msg, wParam, lParam);
}

static void ImGui_ImplWin32_InitPlatformInterface()
static void ImGui_ImplWin32_InitPlatformInterface(bool platformHasOwnDC)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.style = CS_HREDRAW | CS_VREDRAW | (platformHasOwnDC ? CS_OWNDC : 0);
wcex.lpfnWndProc = ImGui_ImplWin32_WndProcHandler_PlatformWindow;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
Expand Down
77 changes: 77 additions & 0 deletions examples/example_win32_opengl3/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,48 @@ void CleanupDeviceWGL(HWND hWnd, WGL_WindowData* data);
void ResetDeviceWGL();
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);


static void Win32_CreateWindow(ImGuiViewport* viewport)
{
assert(viewport->RendererUserData == NULL);

WGL_WindowData* data = IM_NEW(WGL_WindowData);
CreateDeviceWGL((HWND)viewport->PlatformHandle, data);
viewport->RendererUserData = data;
}

static void Win32_DestroyWindow(ImGuiViewport* viewport)
{
if (viewport->RendererUserData != NULL)
{
WGL_WindowData* data = (WGL_WindowData*)viewport->RendererUserData;
CleanupDeviceWGL((HWND)viewport->PlatformHandle, data);
IM_DELETE(data);
viewport->RendererUserData = NULL;
}
}

static void Win32_RenderWindow(ImGuiViewport* viewport, void*)
{
WGL_WindowData* data = (WGL_WindowData*)viewport->RendererUserData;

if (data)
{
// Activate the platform window DC in the OpenGL rendering context
wglMakeCurrent(data->hDC, g_hRC);
}
}

static void Win32_SwapBuffers(ImGuiViewport* viewport, void*)
{
WGL_WindowData* data = (WGL_WindowData*)viewport->RendererUserData;

if (data)
{
SwapBuffers(data->hDC);
}
}

// Main code
int main(int, char**)
{
Expand Down Expand Up @@ -58,15 +100,41 @@ int main(int, char**)
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows

// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();

// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
ImGuiStyle& style = ImGui::GetStyle();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
style.WindowRounding = 0.0f;
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
}

// Setup Platform/Renderer backends
ImGui_ImplWin32_InitForOpenGL(hwnd);
ImGui_ImplOpenGL3_Init();

if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();

// Store the hdc for this new window
assert(platform_io.Renderer_CreateWindow == NULL);
platform_io.Renderer_CreateWindow = Win32_CreateWindow;
assert(platform_io.Renderer_DestroyWindow == NULL);
platform_io.Renderer_DestroyWindow = Win32_DestroyWindow;
assert(platform_io.Renderer_SwapBuffers == NULL);
platform_io.Renderer_SwapBuffers = Win32_SwapBuffers;

// We need to activate the context before drawing
assert(platform_io.Platform_RenderWindow == NULL);
platform_io.Platform_RenderWindow = Win32_RenderWindow;
}
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
Expand Down Expand Up @@ -154,6 +222,15 @@ int main(int, char**)
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

// Update and Render additional Platform Windows
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
// Restore the OpenGL rendering context to the main window DC, since platform windows might have changed it.
wglMakeCurrent(g_MainWindow.hDC, g_hRC);
}

// Present
::SwapBuffers(g_MainWindow.hDC);
}
Expand Down

0 comments on commit 4bc51c6

Please sign in to comment.