mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-11-04 07:01:04 +01: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