Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added example project of Win32 and OpenGL implementation. #2772

Closed
wants to merge 2 commits into from

Conversation

danec020
Copy link

This pull request is for the example project show casing using Dear ImGui's docking branch working with Win32 window API and OpenGl3 using the Glad loader.

To use:
-Pull commit.
-Load ImGui solution.
-Set imgui_impl_opengl3.h to use #define IMGUI_IMPL_OPENGL_LOADER_GLAD
-Set included example project as startup.
-Build and run.

Screenshot

Copy link

@corentin-plouet corentin-plouet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main issue is the way you've integrated the loader; you've hard-wired glad in. You should be able to make it work with gl3w. Which of course does not prevent you from using glad in your own project (I use glad myself).

The second issue is the way you have disrupted the way windows.h is included. I'm pretty sure it's fine the way it is currently.

Otherwise there are a few whitespace changes that add noise.

#include "glad/glad.h"
#include <tchar.h>

#define IMGUI_IMPL_OPENGL_LOADER_GLAD

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has no effect here.

@@ -0,0 +1,229 @@
#include <Windows.h>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be lowercase windows.h (is it even required to include this one here?)
Generally, it's a good practice to order your headers from most specific to least specific, such that you would have first file-specific headers (in this case the ones related to win32 and opengl3) then project-specific headers (imgui) then third-party library and finally system headers like stdio.
This way you can detect when your own headers have implicit dependencies that you forgot to add.

@@ -33,7 +33,7 @@
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
#define IMGUI_IMPL_OPENGL_LOADER_GL3W
#define IMGUI_IMPL_OPENGL_LOADER_GLAD

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See general comment regarding glad, below.
This line should be reverted; it breaks the Linux/macOS builds. The logic is wrong anyway: there is already a test for GLAD right above.

g_glcontext = (HGLRC)glcontext;
g_focused_hWnd = g_hWnd;

ImGuiIO& io = ImGui::GetIO(); (void)io;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's that cast to void on the right?

MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767);
#undef MAP_BUTTON
#undef MAP_ANALOG
#define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completely gratuitous white space changes here.

data->Hwnd = ::CreateWindowEx(
data->DwExStyle, _T("ImGui Platform"), _T("Untitled"), data->DwStyle, // Style, class name, window name
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area
parent_window, NULL, ::GetModuleHandle(NULL), NULL); // Parent window, Menu, Instance, Param

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gratuitous whitespace change.

}

static bool ImGui_ImplWin32_GetWindowFocus(ImGuiViewport* viewport)
{
ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData;
IM_ASSERT(data->Hwnd != 0);
ImDrawList* list = ImGui::GetBackgroundDrawList(viewport);
//return g_focused_hWnd == data->Hwnd;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to remove that line instead of leaving it commented.

@@ -0,0 +1,290 @@
#ifndef __khrplatform_h_

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two issues here:

  1. glad files (maybe not this one, but the other two) are generated based on the developer or project's spec. Maybe not such a big deal for an example program though, but...
  2. This adds an extra dependency. ImGui already ships with gl3w as a GL loader.

So it would be better to use gl3w instead of glad. Unless there is a good reason not too? I assume gl3w works on Windows but I have not tested myself.

Look at the existing examples to see how it's integrated. Generally you don't have to touch the code, there is already the #ifdef logic to pick the right one based on what you specify when building it.

@@ -13,7 +13,6 @@
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we want this one gone...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had removed it and put it in the header. Which was probably a mistake left over when I was cleaning up the file. I will bring it back and remove the one in the header file so it is like it was before.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then you should also move the MEAN_AND_LEAN stuff

@@ -9,8 +9,9 @@
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.

#pragma once
#include <windows.h>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the comment below.
You don't want to drag windows.h in other header files because it's enormous (even when defining WIN32_LEAN_AND_MEAN).

@ocornut
Copy link
Owner

ocornut commented Sep 1, 2019 via email

@danec020
Copy link
Author

danec020 commented Sep 1, 2019

Thanks for the feedback and you are right. I will clean up those white space changes and remove the dependencies. I am sorry about adding Glad, I thought it would be ok since the project already supported Glad but I can use Gl3w and that should help with the changes to the branch.

@danec020
Copy link
Author

danec020 commented Sep 1, 2019

Ok, the latest version should have only the necessary changes. I tried to be extra careful cleaning it up for you so please let me know if I missed anything. Will the pull request get the history of all my commits or just the latest? If I need to, I can delete the fork and start a new one with just one commit with the latest changes so we don't clutter the history.

@ocornut
Copy link
Owner

ocornut commented Sep 1, 2019 via email

@danec020
Copy link
Author

danec020 commented Sep 1, 2019

Done. Should now be a single commit.

@corentin-plouet
Copy link

Much better indeed.
The batch file to build it is still broken though. You should be able to look at the other ones for Windows and the SDL OpenGL one to make something that works.

I don't think we have Windows CI at the moment. I might look at that at some point.

…Gl3 via Glad.

Trying to remove the white space changes that were made to the original for no reason.

Removed changes to Updating the mouse position.

Removing more unnecessary changes.

Cleaned up some more unneeded changes and whitespace.

Switched the projec to using gl3w. Project should be cleaned of all uneccessary white spaces and code. Everything has tested and worked.

Had to add back the windows header and delete to forward declarations.

Was able to remove the windows dependence from the header with forward declaration.

Setup the batch file to properly build the project from command line.
@danec020
Copy link
Author

danec020 commented Sep 2, 2019

Really sorry for all the time of yours that I have wasted not doing this correctly. I have updated the batch file now and ran it in the command line with a successful build.

@ocornut
Copy link
Owner

ocornut commented Sep 2, 2019

Thank you @danec020 for taking the time to update this, much appreciated.
Also thanks to @corentin-plouet for helping with the review :)

As is, I believe the changes in imgui_impl_win32.cpp would be breaking all other back-ends since they create an OpenGL context. This topic has been approach various time but it never got fully solved right yet. Linking to #2359, #2290 , #2022, #1553,
However I believe we now have enough reference to design a working thing.

In my attempt to do it for multi-viewports here:
#1553 (comment)

I added the win32<>gl glue code in the main.cpp code.
I belive that win32 glue code which you currently added in imgui_impl_win32.cpp should somehow be moved either to the app (main.cpp) either the renderer backend (imgui_impl_openglX.cpp) (preferably) but for the later it would need an indication from the platform whether the context was already created or not and that indication would need to be stored in a back-end agnostic manner (e.g. something in ImGuiPlatformIO).

The problem stem from the fact that our platform<>renderer split approach doesn't perfectly fit the situation for GL+Win32.

I think we need to be looking at those 4 topics together, find a suitable solution for multi-viewports, once that solution is agreed upon we can add the example to master and then add the multi-viewports compliant feature.

To be honest I believe the situation is a little bit hairy. Bonus point is that when we solve it we'll be solving FIVE issues at once and that prospect keeps me awake at night in excitement. I'll be looking at it when I have time.

@danec020
Copy link
Author

danec020 commented Sep 4, 2019

Which sections of code do you feel would be non breaking? I have removed the code creating the second GLContext and updated it to use the PixelFormat and GlContext of the main window. This way whatever the implementation the user uses for their window, our child window would be setup the same way.

This eleminated the need for the glue code in the imgui_impl_win32.cpp. Does the new RenderWindow and SwapBuffer methods cause any concern for issues? That shouldn't break anything if the user had already supplied their own? Let me know what you think about the changes and we can keep nudging it in the right direction. I should have the changes up soon.

…is created it uses the main window's context and pixel format. Removed extra additions to the code that used a unique GL Context per viewport.
@danec020
Copy link
Author

danec020 commented Sep 8, 2019

Just checking in to see if you seen my edited comment. Does this address some of the concerns?

@danec020
Copy link
Author

danec020 commented Oct 9, 2019

@ocornut I also have discovered that when you have multiple Viewports outside the main window the program slows tremendously. The cpu usage and ram isn't changing but the response in imgui is very laggy and nonresponsive.

@ocornut
Copy link
Owner

ocornut commented Oct 9, 2019

It's probably mishandling vsync/swap, should be fixed.

@LipkeGu
Copy link

LipkeGu commented Oct 11, 2019

It seems also it doenst respond to any Input resize etc...

@danec020
Copy link
Author

I am not sure I follow what you mean by input resize? Do you have a screenshot?

@LipkeGu
Copy link

LipkeGu commented Oct 11, 2019

When i try to resize the imgu window, it doesnt respond to mouseInput. neighter i can move it to another Position...
imgui_input

@danec020
Copy link
Author

I do not have that issue. Sorry.

@strangezakary
Copy link

Hi @danec020 !

I just happened to stumble upon this PR so i figured I’d add some feedback / food for thought here.

Firstly, the way your are initializing OpenGL isn’t really “modern” or the way you supposed to do it anymore. The way you are doing it is fine for quickly getting a context up and running, but not how you are supposed to do it for applications that will run on many PCs. I’m not sure if this is really a concern or not given that people aren’t supposed to just copy these examples (even though I imagine many do). In my experience creating OpenGL contexts the “modern” way (wglCreateContextAttribsArb) also reduces driver to driver output variation like we are getting above.

Secondly (this one is easier to digest), since this is just a window app it is recommended to use WinMain this will automatically give you a hInstance so you won’t have to call GetModuleHandle anymore.

I’d be able to go ahead and make these changes if desired.

Thanks
Zak

@strangezakary
Copy link

@ocornut Hey Omar. Is this example something that you are interested in adding to the repo. If so i can take the weekend and put something together as it shouldn't be too much work

@ocornut
Copy link
Owner

ocornut commented Oct 25, 2019

@StrangeZak I am very interested in this but every variations of this PR comes with their own sets of issues and I don't have much of the energy to be wading through them and providing the feedback/fixes at the moment.
Happy to hear suggestion of changes to the initialization process, ideally backed with data/references. Your first suggestion looks adequate but the second suggestion feels offtopic and unnecessary.

@ocornut ocornut force-pushed the docking branch 2 times, most recently from 4a6447b to 6822493 Compare October 8, 2020 14:06
@Donione
Copy link

Donione commented Mar 1, 2021

@ocornut I also have discovered that when you have multiple Viewports outside the main window the program slows tremendously. The cpu usage and ram isn't changing but the response in imgui is very laggy and nonresponsive.

It's probably mishandling vsync/swap, should be fixed.

I did some poking around and this seems to be caused by the constant GetDC calls in the RenderWindow/SwapBuffers functions.
Saving the HDC in ImGuiViewportDataWin32 on window creation is a way to solve this.

ImGui_ImplWin32_EnableDpiAwareness();

// Create application window
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CS_CLASSDC means all windows created with this window class will share 1 Device context.
So no matter how many times you call GetDC (and no matter on what window with this class) they all share 1 DC.
Are you sure that is the correct option here?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the big slowdown is not as much from calling GetDC repeatedly as it is from not calling ReleaseDC afterwards.
Is it generally bad idea to just store the DC once?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attaching a profiler will tell you exactly where the slowdown comes from, instead of guessing at it.

Comment on lines -3 to +4
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio 15
VisualStudioVersion = 15.0.28307.779
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably revert this?

@ocornut ocornut changed the title Added example project of Win32 and OpenGl implementation. Added example project of Win32 and OpenGL implementation. Jan 4, 2022
ocornut pushed a commit that referenced this pull request Apr 19, 2023
…2772, #2600, #2359, #2022, #1553)

Removed mulit-viewpot stuff in this commit on master, will be re-added separately.
@ocornut
Copy link
Owner

ocornut commented Apr 19, 2023

Closed/solved, see #3218 (comment)

@ocornut ocornut closed this Apr 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants