diff options
Diffstat (limited to 'src/imgui/examples/libs/emscripten')
-rw-r--r-- | src/imgui/examples/libs/emscripten/emscripten_mainloop_stub.h | 37 | ||||
-rw-r--r-- | src/imgui/examples/libs/emscripten/shell_minimal.html | 65 |
2 files changed, 102 insertions, 0 deletions
diff --git a/src/imgui/examples/libs/emscripten/emscripten_mainloop_stub.h b/src/imgui/examples/libs/emscripten/emscripten_mainloop_stub.h new file mode 100644 index 0000000..05cf60f --- /dev/null +++ b/src/imgui/examples/libs/emscripten/emscripten_mainloop_stub.h @@ -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 diff --git a/src/imgui/examples/libs/emscripten/shell_minimal.html b/src/imgui/examples/libs/emscripten/shell_minimal.html new file mode 100644 index 0000000..bcf6262 --- /dev/null +++ b/src/imgui/examples/libs/emscripten/shell_minimal.html @@ -0,0 +1,65 @@ +<!doctype html> +<html lang="en-us"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/> + <title>Dear ImGui Emscripten example</title> + <style> + body { margin: 0; background-color: black } + /* FIXME: with our GLFW example this block seems to break resizing and io.DisplaySize gets stuck */ + .emscripten { + position: absolute; + top: 0px; + left: 0px; + margin: 0px; + border: 0; + width: 100%; + height: 100%; + overflow: hidden; + display: block; + image-rendering: optimizeSpeed; + image-rendering: -moz-crisp-edges; + image-rendering: -o-crisp-edges; + image-rendering: -webkit-optimize-contrast; + image-rendering: optimize-contrast; + image-rendering: crisp-edges; + image-rendering: pixelated; + -ms-interpolation-mode: nearest-neighbor; + } + </style> + </head> + <body> + <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas> + <script type='text/javascript'> + var Module = { + preRun: [], + postRun: [], + print: (function() { + return function(text) { + text = Array.prototype.slice.call(arguments).join(' '); + console.log(text); + }; + })(), + printErr: function(text) { + text = Array.prototype.slice.call(arguments).join(' '); + console.error(text); + }, + canvas: (function() { + var canvas = document.getElementById('canvas'); + //canvas.addEventListener("webglcontextlost", function(e) { alert('FIXME: WebGL context lost, please reload the page'); e.preventDefault(); }, false); + return canvas; + })(), + setStatus: function(text) { + console.log("status: " + text); + }, + monitorRunDependencies: function(left) { + // no run dependencies to log + } + }; + window.onerror = function() { + console.log("onerror: " + event); + }; + </script> + {{{ SCRIPT }}} + </body> +</html> |