mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	Examples: (Again, but better) made SDL+GL and GLFW+GL examples build with Emscripten. (#2492, #2494, #3699, #3705)
This commit is contained in:
		| @@ -98,7 +98,8 @@ All changes: | |||||||
| - Backends: WebGPU: Fix building for latest WebGPU specs (remove implicit layout generation). | - Backends: WebGPU: Fix building for latest WebGPU specs (remove implicit layout generation). | ||||||
|   (#6117, #4116, #3632) [@tonygrue, @bfierz] |   (#6117, #4116, #3632) [@tonygrue, @bfierz] | ||||||
| - Examples: refactored SDL+GL and GLFW+GL examples to compile with Emscripten. | - Examples: refactored SDL+GL and GLFW+GL examples to compile with Emscripten. | ||||||
|   (the dedicated example_emscripten_opengl3/ has been removed) (#2492, #2494, #3699, #3705) |   (#2492, #2494, #3699, #3705) [@ocornut, @nicolasnoble] | ||||||
|  |   The dedicated example_emscripten_opengl3/ has been removed. | ||||||
| - Examples: Win32: Fixed examples using RegisterClassW() since 1.89 to also call | - Examples: Win32: Fixed examples using RegisterClassW() since 1.89 to also call | ||||||
|   DefWindowProcW() instead of DefWindowProc() so that title text are correctly converted |   DefWindowProcW() instead of DefWindowProc() so that title text are correctly converted | ||||||
|   when application is compiled without /DUNICODE. (#5725, #5961, #5975) [@markreidvfx] |   when application is compiled without /DUNICODE. (#5725, #5961, #5975) [@markreidvfx] | ||||||
|   | |||||||
| @@ -20,6 +20,11 @@ | |||||||
| #pragma comment(lib, "legacy_stdio_definitions") | #pragma comment(lib, "legacy_stdio_definitions") | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | // This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details. | ||||||
|  | #ifdef __EMSCRIPTEN__ | ||||||
|  | #include "../libs/emscripten/emscripten_mainloop_stub.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
| static void glfw_error_callback(int error, const char* description) | static void glfw_error_callback(int error, const char* description) | ||||||
| { | { | ||||||
|     fprintf(stderr, "GLFW Error %d: %s\n", error, description); |     fprintf(stderr, "GLFW Error %d: %s\n", error, description); | ||||||
| @@ -85,6 +90,7 @@ int main(int, char**) | |||||||
|     // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. |     // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. | ||||||
|     // - Read 'docs/FONTS.md' for more instructions and details. |     // - Read 'docs/FONTS.md' for more instructions and details. | ||||||
|     // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! |     // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! | ||||||
|  |     // - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details. | ||||||
|     //io.Fonts->AddFontDefault(); |     //io.Fonts->AddFontDefault(); | ||||||
|     //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); |     //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); | ||||||
|     //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); |     //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); | ||||||
| @@ -99,7 +105,14 @@ int main(int, char**) | |||||||
|     ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); |     ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); | ||||||
|  |  | ||||||
|     // Main loop |     // Main loop | ||||||
|  | #ifdef __EMSCRIPTEN__ | ||||||
|  |     // For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file. | ||||||
|  |     // You may manually call LoadIniSettingsFromMemory() to load settings from your own storage. | ||||||
|  |     io.IniFilename = NULL; | ||||||
|  |     EMSCRIPTEN_MAINLOOP_BEGIN | ||||||
|  | #else | ||||||
|     while (!glfwWindowShouldClose(window)) |     while (!glfwWindowShouldClose(window)) | ||||||
|  | #endif | ||||||
|     { |     { | ||||||
|         // Poll and handle events (inputs, window resize, etc.) |         // Poll and handle events (inputs, window resize, etc.) | ||||||
|         // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. |         // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. | ||||||
| @@ -161,6 +174,9 @@ int main(int, char**) | |||||||
|  |  | ||||||
|         glfwSwapBuffers(window); |         glfwSwapBuffers(window); | ||||||
|     } |     } | ||||||
|  | #ifdef __EMSCRIPTEN__ | ||||||
|  |     EMSCRIPTEN_MAINLOOP_END; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     // Cleanup |     // Cleanup | ||||||
|     ImGui_ImplOpenGL3_Shutdown(); |     ImGui_ImplOpenGL3_Shutdown(); | ||||||
|   | |||||||
| @@ -14,6 +14,11 @@ | |||||||
| #include <SDL_opengl.h> | #include <SDL_opengl.h> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | // This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details. | ||||||
|  | #ifdef __EMSCRIPTEN__ | ||||||
|  | #include "../libs/emscripten/emscripten_mainloop_stub.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
| // Main code | // Main code | ||||||
| int main(int, char**) | int main(int, char**) | ||||||
| { | { | ||||||
| @@ -81,6 +86,7 @@ int main(int, char**) | |||||||
|     // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. |     // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. | ||||||
|     // - Read 'docs/FONTS.md' for more instructions and details. |     // - Read 'docs/FONTS.md' for more instructions and details. | ||||||
|     // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! |     // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! | ||||||
|  |     // - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details. | ||||||
|     //io.Fonts->AddFontDefault(); |     //io.Fonts->AddFontDefault(); | ||||||
|     //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); |     //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); | ||||||
|     //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); |     //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); | ||||||
| @@ -96,7 +102,14 @@ int main(int, char**) | |||||||
|  |  | ||||||
|     // Main loop |     // Main loop | ||||||
|     bool done = false; |     bool done = false; | ||||||
|  | #ifdef __EMSCRIPTEN__ | ||||||
|  |     // For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file. | ||||||
|  |     // You may manually call LoadIniSettingsFromMemory() to load settings from your own storage. | ||||||
|  |     io.IniFilename = NULL; | ||||||
|  |     EMSCRIPTEN_MAINLOOP_BEGIN | ||||||
|  | #else | ||||||
|     while (!done) |     while (!done) | ||||||
|  | #endif | ||||||
|     { |     { | ||||||
|         // Poll and handle events (inputs, window resize, etc.) |         // Poll and handle events (inputs, window resize, etc.) | ||||||
|         // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. |         // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. | ||||||
| @@ -163,6 +176,9 @@ int main(int, char**) | |||||||
|         ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); |         ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); | ||||||
|         SDL_GL_SwapWindow(window); |         SDL_GL_SwapWindow(window); | ||||||
|     } |     } | ||||||
|  | #ifdef __EMSCRIPTEN__ | ||||||
|  |     EMSCRIPTEN_MAINLOOP_END; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     // Cleanup |     // Cleanup | ||||||
|     ImGui_ImplOpenGL3_Shutdown(); |     ImGui_ImplOpenGL3_Shutdown(); | ||||||
|   | |||||||
							
								
								
									
										37
									
								
								examples/libs/emscripten/emscripten_mainloop_stub.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								examples/libs/emscripten/emscripten_mainloop_stub.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | // What does this file solves? | ||||||
|  | // - Since Dear ImGui 1.00 we took pride that most of our examples applications had their entire | ||||||
|  | //   main-loop inside the main() function. That's because: | ||||||
|  | //   - It makes the examples easier to read, keeping the code sequential. | ||||||
|  | //   - It permit the use of local variables, making it easier to try things and perform quick | ||||||
|  | //     changes when someone needs to quickly test something (vs having to structure the example | ||||||
|  | //     in order to pass data around). This is very important because people use those examples | ||||||
|  | //     to craft easy-to-past repro when they want to discuss features or report issues. | ||||||
|  | //   - It conveys at a glance that this is a no-BS framework, it won't take your main loop away from you. | ||||||
|  | //   - It is generally nice and elegant. | ||||||
|  | // - However, comes Emscripten... it is a wonderful and magical tech but it requires a "main loop" function. | ||||||
|  | // - Only some of our examples would run on Emscripten. Typically the ones rendering with GL or WGPU ones. | ||||||
|  | // - I tried to refactor those examples but felt it was problematic that other examples didn't follow the | ||||||
|  | //   same layout. Why would the SDL+GL example be structured one way and the SGL+DX11 be structured differently? | ||||||
|  | //   Especially as we are trying hard to convey that using a Dear ImGui backend in an *existing application* | ||||||
|  | //   should requires only a few dozens lines of code, and this should be consistent and symmetrical for all backends. | ||||||
|  | // - So the next logical step was to refactor all examples to follow that layout of using a "main loop" function. | ||||||
|  | //   This worked, but it made us lose all the nice things we had... | ||||||
|  |  | ||||||
|  | // Since only about 3 examples really need to run with Emscripten, here's our solution: | ||||||
|  | // - Use some weird macros and capturing lambda to turn a loop in main() into a function. | ||||||
|  | // - Hide all that crap in this file so it doesn't make our examples unusually ugly. | ||||||
|  | //   As a stance and principle of Dear ImGui development we don't use C++ headers and we don't | ||||||
|  | //   want to suggest to the newcomer that we would ever use C++ headers as this would affect | ||||||
|  | //   the initial judgment of many of our target audience. | ||||||
|  | // - Technique is based on this idea: https://github.com/ocornut/imgui/pull/2492/ | ||||||
|  | #ifdef __EMSCRIPTEN__ | ||||||
|  | #include <emscripten.h> | ||||||
|  | #include <functional> | ||||||
|  | static std::function<void()>            MainLoopForEmscriptenP; | ||||||
|  | static void MainLoopForEmscripten()     { MainLoopForEmscriptenP(); } | ||||||
|  | #define EMSCRIPTEN_MAINLOOP_BEGIN       MainLoopForEmscriptenP = [&]() | ||||||
|  | #define EMSCRIPTEN_MAINLOOP_END         ; emscripten_set_main_loop(MainLoopForEmscripten, 0, true) | ||||||
|  | #else | ||||||
|  | #define EMSCRIPTEN_MAINLOOP_BEGIN | ||||||
|  | #define EMSCRIPTEN_MAINLOOP_END | ||||||
|  | #endif | ||||||
		Reference in New Issue
	
	Block a user
	 ocornut
					ocornut