Skip to content

Commit

Permalink
Examples: Amend Win32/Winapi + OpenGL example for multi-viewport. (#3218
Browse files Browse the repository at this point in the history
  • Loading branch information
ocornut committed Apr 19, 2023
1 parent 4bc51c6 commit f498f08
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 31 deletions.
4 changes: 2 additions & 2 deletions backends/imgui_impl_win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1165,11 +1165,11 @@ static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd,
return DefWindowProc(hWnd, msg, wParam, lParam);
}

static void ImGui_ImplWin32_InitPlatformInterface(bool platformHasOwnDC)
static void ImGui_ImplWin32_InitPlatformInterface(bool platform_has_own_dc)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW | (platformHasOwnDC ? CS_OWNDC : 0);
wcex.style = CS_HREDRAW | CS_VREDRAW | (platform_has_own_dc ? CS_OWNDC : 0);
wcex.lpfnWndProc = ImGui_ImplWin32_WndProcHandler_PlatformWindow;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
Expand Down
51 changes: 22 additions & 29 deletions examples/example_win32_opengl3/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ 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)
// Support function for multi-viewports
// Unlike most other backend combination, we need specific hooks to combine Win32+OpenGL.
// We could in theory decide to support Win32-specific code in OpenGL backend via e.g. an hypothetical ImGui_ImplOpenGL3_InitForRawWin32().
static void Hook_Renderer_CreateWindow(ImGuiViewport* viewport)
{
assert(viewport->RendererUserData == NULL);

Expand All @@ -39,7 +41,7 @@ static void Win32_CreateWindow(ImGuiViewport* viewport)
viewport->RendererUserData = data;
}

static void Win32_DestroyWindow(ImGuiViewport* viewport)
static void Hook_Renderer_DestroyWindow(ImGuiViewport* viewport)
{
if (viewport->RendererUserData != NULL)
{
Expand All @@ -50,25 +52,17 @@ static void Win32_DestroyWindow(ImGuiViewport* viewport)
}
}

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

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

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

if (data)
{
SwapBuffers(data->hDC);
}
if (WGL_WindowData* data = (WGL_WindowData*)viewport->RendererUserData)
::SwapBuffers(data->hDC);
}

// Main code
Expand Down Expand Up @@ -119,22 +113,20 @@ int main(int, char**)
ImGui_ImplWin32_InitForOpenGL(hwnd);
ImGui_ImplOpenGL3_Init();

// Win32+GL needs specific hooks for viewport, as there are specific things needed to tie Win32 and GL api.
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;
IM_ASSERT(platform_io.Renderer_CreateWindow == NULL);
IM_ASSERT(platform_io.Renderer_DestroyWindow == NULL);
IM_ASSERT(platform_io.Renderer_SwapBuffers == NULL);
IM_ASSERT(platform_io.Platform_RenderWindow == NULL);
platform_io.Renderer_CreateWindow = Hook_Renderer_CreateWindow;
platform_io.Renderer_DestroyWindow = Hook_Renderer_DestroyWindow;
platform_io.Renderer_SwapBuffers = Hook_Renderer_SwapBuffers;
platform_io.Platform_RenderWindow = Hook_Platform_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 @@ -227,6 +219,7 @@ int main(int, char**)
{
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);
}
Expand Down

0 comments on commit f498f08

Please sign in to comment.