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).
 | 
			
		||||
  (#6117, #4116, #3632) [@tonygrue, @bfierz]
 | 
			
		||||
- 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
 | 
			
		||||
  DefWindowProcW() instead of DefWindowProc() so that title text are correctly converted
 | 
			
		||||
  when application is compiled without /DUNICODE. (#5725, #5961, #5975) [@markreidvfx]
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,11 @@
 | 
			
		||||
#pragma comment(lib, "legacy_stdio_definitions")
 | 
			
		||||
#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)
 | 
			
		||||
{
 | 
			
		||||
    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.
 | 
			
		||||
    // - 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 \\ !
 | 
			
		||||
    // - 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->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.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);
 | 
			
		||||
 | 
			
		||||
    // 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))
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        // 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.
 | 
			
		||||
@@ -161,6 +174,9 @@ int main(int, char**)
 | 
			
		||||
 | 
			
		||||
        glfwSwapBuffers(window);
 | 
			
		||||
    }
 | 
			
		||||
#ifdef __EMSCRIPTEN__
 | 
			
		||||
    EMSCRIPTEN_MAINLOOP_END;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // Cleanup
 | 
			
		||||
    ImGui_ImplOpenGL3_Shutdown();
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,11 @@
 | 
			
		||||
#include <SDL_opengl.h>
 | 
			
		||||
#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
 | 
			
		||||
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.
 | 
			
		||||
    // - 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 \\ !
 | 
			
		||||
    // - 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->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
 | 
			
		||||
    //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
 | 
			
		||||
@@ -96,7 +102,14 @@ int main(int, char**)
 | 
			
		||||
 | 
			
		||||
    // Main loop
 | 
			
		||||
    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)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        // 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.
 | 
			
		||||
@@ -163,6 +176,9 @@ int main(int, char**)
 | 
			
		||||
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
 | 
			
		||||
        SDL_GL_SwapWindow(window);
 | 
			
		||||
    }
 | 
			
		||||
#ifdef __EMSCRIPTEN__
 | 
			
		||||
    EMSCRIPTEN_MAINLOOP_END;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // Cleanup
 | 
			
		||||
    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