-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Description
Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.29-git
clang version 16.0.0 (https://github.com/llvm/llvm-project.git 947d529e4194e0567cfbbea99127066f76c87269)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /usr/local/Cellar/emscripten/3.1.29/libexec/llvm/bin
Failing full example below :
It basically git clone ImGui, and compiles the necessary files unmodified, to launch the "Demo Window".
#!/bin/bash
set -ex
[ -d imgui/ ] || git clone --branch v1.89.2 https://github.com/ocornut/imgui.git
files_imgui="imgui/imgui.cpp imgui/imgui_draw.cpp imgui/imgui_demo.cpp imgui/imgui_widgets.cpp imgui/imgui_tables.cpp"
files_backends="imgui/backends/imgui_impl_sdl.cpp imgui/backends/imgui_impl_opengl3.cpp"
file_main="imgui/examples/example_emscripten_opengl3/main.cpp"
read -d '' -a flags_all <<EOF || true
-s EXPORT_ALL=1 -fno-exceptions
-I ./imgui/ -DIMGUI_IMPL_API=extern\ "C"
-DIMGUI_DISABLE_FILE_FUNCTIONS -DIMGUI_DISABLE_OBSOLETE_FUNCTIONS=1
-s USE_SDL=2
-s USE_WEBGL2=1
EOF
read -r -d '' -a flags_debug <<EOF || true
-s ASSERTIONS=1
-DDEBUG -D_DEBUG -g
-s ERROR_ON_UNDEFINED_SYMBOLS=1
EOF
#emcc --clear-cache
em++ -o imgui.wasm -s SIDE_MODULE=1 $files_imgui "${flags_all[@]}" -O2
em++ -o backends.wasm -s SIDE_MODULE=1 $files_backends "${flags_all[@]}" -O2 -I ./imgui/backends/
em++ -o web1.html -s MAIN_MODULE=2 imgui.wasm backends.wasm $file_main "${flags_all[@]}" "${flags_debug[@]}" -I ./imgui/backends/
python3 -m http.server 8002
The Problem :
It works well with MAIN_MODULE=1 ; But it wont work with MAIN_MODULE=2, Google Chrome outputs :
Uncaught TypeError: Module.canvas.exitPointerLock is not a function
at _SDL_ShowCursor (web1.js:6422:28)
at stubs.<computed> (web1.js:1985:33)
at 500b98b2:0x17ac
at _ImGui_ImplSDL2_NewFrame (web1.js:2311:45)
at main_loop(void*) (web1.wasm:0x6d32)
[...]
What's weird about it it that there is not much changes needed to make it works ;
There is 3 particular curious behaviours that I observed ;
1) SDL_ShowCursor is the only thing preventing the WHOLE ImGui to works :
--- a/backends/imgui_impl_sdl.cpp
+++ b/backends/imgui_impl_sdl.cpp
@@ -481,7 +481,7 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
{
// Show OS mouse cursor
SDL_SetCursor(bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]);
- SDL_ShowCursor(SDL_TRUE);
+// SDL_ShowCursor(SDL_TRUE);
}
}
Commenting the above line make it works. (or changing it to SDL_FALSE);
2) Moving the SAME "code execution" of ONLY SDL_ShowCursor to the "main module" also works ;
I mean : this is the "call path" :
main.cpp (main module) calls ImGui_ImplSDL2_NewFrame()
`- which calls ImGui_ImplSDL2_UpdateMouseCursor() at its tail (discards the UpdateGamepads below to simplify)
`- which calls SDL_ShowCursor(SDL_TRUE) at its tail
If you just do 2 things :
- comment out the
SDL_ShowCursor(SDL_TRUE)inside the "side module" (backends/imgui_impl_sdl.cpp) - add
SDL_ShowCursor(SDL_TRUE)inside the "main module" just after the call to ImGui_ImplSDL2_NewFrame()
you would agree that the "code path execution" is the same.
(we just moved a call to SDL_ShowCursor , from the tail of the side module, to the tail of the function calling the side module)
Weirdly, it makes it works.
This is my biggest concern, of course as I shown it is work-around-able, but I wonder WHY moving a call from the "side module" to the "main module" makes it works.
Please note that I tried to enforce the SDL_ShowCursor function to not be "stripped / excluded" from the binary, by adding IN ALL CASES a call to it from the "main module", just before calling the "side module"'s ImGui_ImplSDL2_NewFrame() ;
I also tried to add a new function to the "side module", which just call SDL_ShowCursor, which I used to figure out the effect of calling SDL_ShowCursor from the "main module" vs/ with a slight indirection going through the "side module".
The observations holds : the call to SDL_ShowCursor(SDL_TRUE) from the "main module" passes okay, but if we call a one-liner function from the "side module" doing only this call, it does not work anymore.
So that's my observation : all things equal, calling SDL_ShowCursor(SDL_TRUE) from the "main module" works okay, and calling it (instead, or again, does not matter) from the "side module" JUST AFTER does not work.
So that's a little like "doing this thing from the main module works, doing the same thing from the side module does not work".
3) Slight difference in behaviour between MAIN_MODULE=1 and =2 ;
Possibly observable only on my macOS platform, due to high DPI stuff.
I told you that for MAIN_MODULE=1 to =2, to make it work, I just weirdly had to either :
- comment out the call to
SDL_ShowCursor() - or move this call to the "main module".
Well, I lied. I mean, it made ImGui mostly works, except that a bug of resolution / high dpi appears.
(the mouse coordinates are not where ImGui think it really is). This fix it :
--- a/examples/example_emscripten_opengl3/main.cpp
+++ b/examples/example_emscripten_opengl3/main.cpp
@@ -48,7 +48,7 @@ int main(int, char**)
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_DisplayMode current;
SDL_GetCurrentDisplayMode(0, ¤t);
- SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
+ SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE /*| SDL_WINDOW_ALLOW_HIGHDPI*/);
g_Window = SDL_CreateWindow("Dear ImGui Emscripten example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
g_GLContext = SDL_GL_CreateContext(g_Window);
if (!g_GLContext)
Of course it fixes it, I just commented some things related to HIGHDPI (without even knowing what I did)
What's weird me out there, is that there is some behaviour differences between MAIN_MODULE=1 and `=2.
Baring any linking or symbol problem, I would then have expected all behaviour to be the same ?
It tickles some curiosity, and maybe be a symptom of a bug.
Kind Regards,