• Advertisement
Sign in to follow this  

C++ ImGui questions

Recommended Posts

I am playing around with ImGui, adding a UI to my level editor, but i am having trouble with mouse clicks in ImGui triggers a click in my actual editor (Because it uses the same input states).

Right know i have just a main menu bar and the editor rendering is behind that. When i click on a menuitem for example, and select another sub item and click, i place a block in my editor - just because the input events are the same for both ImGui and my editor.

So i have a few questions:

1.) Is there a way to detect when ImGui has taken any action/hover in the previous frame, so i can skip the input handling for my editor? (This way i can prevent the issue i have right now)

2.) Can i add a imgui window which fully fits the rest of the entire screen - after a main bar has been added? (Do i manually need to calculate the size?)

3.) Should i make the entire editor with ImGUI only - so i wont get any input fuzziness problems?

Share this post


Link to post
Share on other sites
Advertisement

1) When calling ImGui::NewFrame() it is updating the io.WantCaptureMouse and io.WantCaptureKeyboard fields. You can use those fields to hide the inputs from your own application/editor. The most obvious case is that io.WantCaptureMouse will be true when hovering an ImGui window (in reality the logic is a little more complex than that, it tracks clicks/drags and active widgets).

This is answered in the FAQ under "Q: How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application?"

2) You can use ImGui::SetNextWindowPos, ImGui::SetNextWindowSize(). You do need to manually calculate the size but you can also create one fullscreen window (position = 0,0, size = io.DisplaySize) with a MenuBar, it's equivalent to creating a main menu bar.

3) I don't know what "input fuzziness" means. It should be fine to create an entire editor, many people have been doing that. One limitation of imgui with it handles inputs events is that if you expect to run at very low frame rates (e.g. 10 FPS) you will want to create a queue events and defer passing all of them to imgui at once (e.g. if you received 2 clicks in one frame). This should be handled by the library but eventually but it's not at the moment. If you don't expect to be running at super low framerate it won't be a problem.

 

Share this post


Link to post
Share on other sites
8 hours ago, ocornut said:

1) When calling ImGui::NewFrame() it is updating the io.WantCaptureMouse and io.WantCaptureKeyboard fields. You can use those fields to hide the inputs from your own application/editor. The most obvious case is that io.WantCaptureMouse will be true when hovering an ImGui window (in reality the logic is a little more complex than that, it tracks clicks/drags and active widgets).

This is answered in the FAQ under "Q: How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application?"

2) You can use ImGui::SetNextWindowPos, ImGui::SetNextWindowSize(). You do need to manually calculate the size but you can also create one fullscreen window (position = 0,0, size = io.DisplaySize) with a MenuBar, it's equivalent to creating a main menu bar.

3) I don't know what "input fuzziness" means. It should be fine to create an entire editor, many people have been doing that. One limitation of imgui with it handles inputs events is that if you expect to run at very low frame rates (e.g. 10 FPS) you will want to create a queue events and defer passing all of them to imgui at once (e.g. if you received 2 clicks in one frame). This should be handled by the library but eventually but it's not at the moment. If you don't expect to be running at super low framerate it won't be a problem.

 

Thanks, that clears it up.

 

Now i have another one, which is also about preventing click events to happen after a imgui menuitem has been clicked.

I have built a simple level editor with imgui and its set a tile in the corner always when i load a level from the main menu - just because the click of the MenuItem is still true. Can i consume that click somehow?

		void Game::EditorUpdate() {
			auto io = ImGui::GetIO();
			auto ctx = ImGui::GetCurrentContext();
			auto editorWindowSize = ImVec2(io.DisplaySize.x, io.DisplaySize.y);

			ImGui::SetNextWindowSize(editorWindowSize, ImGuiSetCond_Always);
			ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiSetCond_FirstUseEver);
			const char *mapName = activeEditorFilePath.empty() ? "Unnamed map" : activeEditorFilePath.c_str();

			ImGui::Begin(mapName, nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_MenuBar);

			// Menu
			if (ImGui::BeginMenuBar()) {
				if (ImGui::BeginMenu("File")) {
					if (ImGui::MenuItem("New map")) {
						ClearLevel();
						activeEditorFilePath = "";
					}
					if (ImGui::MenuItem("Load map...")) {
						showOpenDialog = true;
						firstTimeOpenDialog = true;
					}
					if (ImGui::MenuItem("Save map")) {
						showSaveDialog = activeEditorFilePath.empty();
						if (!showSaveDialog)
							SaveMap(activeEditorFilePath.c_str());
						else
							firstTimeSaveDialog = true;
					}
					if (ImGui::MenuItem("Save map as...")) {
						showSaveDialog = firstTimeSaveDialog = true;
					}
					if (ImGui::MenuItem("Exit")) {
						exitRequested = true;
					}
					ImGui::EndMenu();
				}
				ImGui::EndMenuBar();
			}

			// Canvas area
			auto maxRegion = ImGui::GetWindowContentRegionMax();
			auto minRegion = ImGui::GetWindowContentRegionMin();
			auto regionSize = ImVec2(maxRegion.x - minRegion.x, maxRegion.y - minRegion.y);
			const ImVec2 startCursorPos = ImGui::GetCursorScreenPos();

			RenderArea canvasArea = {};
			UpdateRenderArea(canvasArea, regionSize.x, regionSize.y, HalfGameWidth, HalfGameHeight, GameAspect);
			const f32 canvasTileSize = TileSize * canvasArea.scale;

			ImDrawList* draw_list = ImGui::GetWindowDrawList();

			const ImVec2 canvasViewportStart = ImVec2(startCursorPos.x + canvasArea.viewportOffset.x, startCursorPos.y + canvasArea.viewportOffset.y);
			const ImVec2 canvasViewportEnd = ImVec2(canvasViewportStart.x + canvasArea.viewportSize.w, canvasViewportStart.y + canvasArea.viewportSize.h);
			draw_list->AddRect(canvasViewportStart, canvasViewportEnd, ImColor(255, 255, 0));

			// Draw tiles
			for (u32 y = 0; y < TileCountForHeight; ++y) {
				u32 tileY = (TileCountForHeight - 1 - y);
				for (u32 x = 0; x < TileCountForWidth; ++x) {
					const Tile &tile = tiles[tileY * TileCountForWidth + x];
					if (tile.isSolid) {
						f32 tx = canvasViewportStart.x + x * canvasTileSize;
						f32 ty = canvasViewportStart.y + y * canvasTileSize;
						draw_list->AddRectFilled(ImVec2(tx, ty), ImVec2(tx + canvasTileSize, ty + canvasTileSize), ImColor(255, 0, 0));
					}
				}	
			}

			// Mouse hover and click actions
           	// HERE I DONT WANT TO TAKE ANY CLICK ACTION AFTER A MENU ITEM HAS BEEN CLICKED 
			if (ImGui::IsWindowFocused() && ImGui::IsMouseHoveringRect(canvasViewportStart, canvasViewportEnd)) {
				auto mp = ImGui::GetMousePos();
				s32 hoverTileX = (s32)((mp.x - canvasViewportStart.x) / canvasTileSize);
				s32 hoverTileY = (s32)((mp.y - canvasViewportStart.y) / canvasTileSize);
				f32 tx = canvasViewportStart.x + hoverTileX * canvasTileSize;
				f32 ty = canvasViewportStart.y + hoverTileY * canvasTileSize;
				draw_list->AddRect(ImVec2(tx, ty), ImVec2(tx + canvasTileSize, ty + canvasTileSize), ImColor(255, 255, 0));

				u32 invertHoverTileY = (TileCountForHeight - 1 - hoverTileY);
				if (ImGui::IsMouseDown(0)) {
					SetTile(hoverTileX, invertHoverTileY, true);
				} else if (ImGui::IsMouseDown(2)) {
					SetTile(hoverTileX, invertHoverTileY, false);
				}
			}

			ImGui::End();
		}

 

Edited by Finalspace

Share this post


Link to post
Share on other sites
1 hour ago, ocornut said:

Are you running on latest? There was a bug in 1.51 which I think is what you are having here.

For general imgui questions may I suggest asking in the imgui github, this is where all the other questions are being asked.

https://github.com/ocornut/imgui/issues

Oh great, never thought it may be a bug... After updating to the latest everything seems to work properly now.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By sergio2k18
      Hi all
      this is my first post on this forum.
      First of all i want to say you that i've searched many posts on this forum about this specific argument, without success, so i write another one....
      Im a beginner.
      I want use GPU geometry clipmaps algorithm to visualize virtual inifinte terrains. 
      I already tried to use vertex texture fetch with a single sampler2D with success.
       
      Readed many papers about the argument and all speak about the fact that EVERY level of a geometry clipmap, has its own texture. What means this exactly? i have to 
      upload on graphic card a sampler2DArray?
      With a single sampler2D is conceptually simple. Creating a vbo and ibo on cpu (the vbo contains only the positions on X-Z plane, not the heights)
      and upload on GPU the texture containing the elevations. In vertex shader i sample, for every vertex, the relative height to te uv coordinate.
      But i can't imagine how can i reproduce various 2d footprint for every level of the clipmap. The only way i can imagine is follow:
      Upload the finer texture on GPU (entire heightmap). Create on CPU, and for each level of clipmap, the 2D footprints of entire clipmap.
      So in CPU i create all clipmap levels in terms of X-Z plane. In vertex shader sampling these values is simple using vertex texture fetch.
      So, how can i to sample a sampler2DArray in vertex shader, instead of upload a sampler2D of entire clipmap?
       
       
      Sorry for my VERY bad english, i hope i have been clear.
       
    • By mangine
      Hello. I am developing a civ 6 clone set in space and I have a few issues. I am using Lua for the logic and UI of the game and c++ directx 12 for the graphics. I need a way to send information between Lua and c++ occasionally and was wondering what is the best and most flexible (and hopefully fast) way to do this. Don't forget that I also need to send things from c++ back to Lua. I know of a lua extension called "LuaBridge" on github but it is a little old and I am worried that it will not work with directx 12. Has anybody done something similar and knows a good method of sending data back and forth? I am aware that Lua is used more and more in the industry and surely plenty of AAA game programmers know the answer to this. I want a good solution that will hopefully still be viable code in a couple of years...
    • By owenjr
      Hi there.
      I'm pretty new to this and I don't know if it has been asked before, but here I go.
      I'm developing a game using SFML and C++.
      I would like to use the "Tiled" tool to load maps into my game but I don't actually find any tutorial or guide on how to exaclty use it (I know that I have to read an XML file and stuff). I just step into diverse projects that make all a mess. 
      Anyone knows where can I find good information to make my map loader by myself?
      Thanks in advantage!!
    • By MHG OstryTM
      Hello guys,
      I've released my game for the first time. I'm very excited about it and I hope you'll enjoy the game - Beer Ranger. It's a retro-like puzzle-platfromer which makes you think a lot or die trying. You have a squad of skilled dwarfs with special powers and your goal is tasty beer. There is a lot of traps as well as many solutions how to endure them - it is up to your choice how to complete the level! 
      Link to the project: Project site
      Link to the Steam site with video: Beer Ranger
      Have fun and please write feedback if you feel up to.
      Some screens: 




    • By francoisdiy
      So I wrote a programming language called C-Lesh to program games for my game maker Platformisis. It is a scripting language which tiles into the JavaScript game engine via a memory mapper using memory mapped I/O. Currently, I am porting the language as a standalone interpreter to be able to run on the PC and possibly other devices excluding the phone. The interpreter is being written in C++ so for those of you who are C++ fans you can see the different components implemented. Some background of the language and how to program in C-Lesh can be found here:

      http://www.codeloader.net/readme.html
      As I program this thing I will post code from different components and explain.
  • Advertisement