From fc4860e30a33f66b81cfc57f0766f73bb55f0196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 26 May 2019 18:42:06 +0200 Subject: [PATCH] Platform: give the docs the love they deserve. --- doc/platforms-html5.dox | 21 +- src/Magnum/Platform/EmscriptenApplication.cpp | 41 ++- src/Magnum/Platform/EmscriptenApplication.h | 244 +++++++++--------- src/Magnum/Platform/Sdl2Application.h | 42 +-- 4 files changed, 159 insertions(+), 189 deletions(-) diff --git a/doc/platforms-html5.dox b/doc/platforms-html5.dox index 156adf547..56520dfab 100644 --- a/doc/platforms-html5.dox +++ b/doc/platforms-html5.dox @@ -98,13 +98,13 @@ Magnum source to the `modules/` dir in your project so it is able to find the WebGL libraries. Magnum provides Emscripten application wrappers in @ref Platform::Sdl2Application -and @ref Platform::EmscriptenApplication. See their documentation for more information -about general usage. You can also use the Emscripten APIs directly or any other -way. +and @ref Platform::EmscriptenApplication. See their documentation for more +information about general usage. You can also use the Emscripten APIs directly +or any other way. -@note @ref Platform::Sdl2Application and @ref Platform::EmscriptenApplication - also contains a fully configured bootstrap projects that are ready to build - and deploy. Check their documentation for details. +@note @ref Platform::EmscriptenApplication also contains a fully configured + bootstrap project that is ready to build and deploy. Check its + documentation for details. To target the web browser, you need to provide a HTML markup for your application. Template one is below. The markup references two files, @@ -198,9 +198,8 @@ EGL and WebGL libraries. Windowless Magnum apps (i.e. apps that use the OpenGL context without a window) can be run in the browser as well using the @ref Platform::WindowlessEglApplication -class. See its documentation for more information -about general usage. You can also use the Emscripten APIs directly or any other -way. +class. See its documentation for more information about general usage. You can +also use the Emscripten APIs directly or any other way. @note @ref Platform::WindowlessEglApplication also contains a fully configured bootstrap project that's ready to build and deploy. Check its documentation @@ -350,8 +349,8 @@ Module.doNotCaptureKeyboard = true; @endcode -The above is implicitly set for @ref Platform::WindowlessEglApplicaiton, because -it does not have an event loop. +The above is implicitly set for @ref Platform::WindowlessEglApplication, +because it does not have an event loop. @cb{.js} Module.doNotCaptureKeyboard @ce is not supported by @ref Platform::EmscriptenApplication. diff --git a/src/Magnum/Platform/EmscriptenApplication.cpp b/src/Magnum/Platform/EmscriptenApplication.cpp index c84e5c13b..d7dcf3019 100644 --- a/src/Magnum/Platform/EmscriptenApplication.cpp +++ b/src/Magnum/Platform/EmscriptenApplication.cpp @@ -107,27 +107,25 @@ namespace { }; /* Translate emscripten key code (as defined by - https://www.w3.org/TR/uievents-code/#key-code-attribute-value) - to Key enum. - - @param key Keyboard layout dependent key string, e.g. 'a', or '-' - @param code Keyboard layout independent key string, e.g. 'KeyA' or 'Minus'. - Note that the y key on some layouts may result in 'KeyZ'. - */ + https://www.w3.org/TR/uievents-code/#key-code-attribute-value) + to Key enum. `key` is a keyboard layout dependent key string, e.g. 'a', + or '-'; `code` is a keyboard layout independent key string, e.g. 'KeyA' + or 'Minus'. Note that the Y key on some layouts may result in 'KeyZ'. */ Key toKey(const EM_UTF8* const key, const EM_UTF8* const code) { const std::size_t keyLength = std::strlen(key); if(keyLength == 0) return Key::Unknown; /* We use key for a-z as it gives us a keyboard layout respecting - representation of the key, i.e. we get `z` for z depending on layout - where code may give us `y` independent of the layout. */ + representation of the key, i.e. we get `z` for z depending on layout + where code may give us `y` independent of the layout. */ if(keyLength == 1) { if(key[0] >= 'a' && key[0] <= 'z') return Key(key[0]); else if(key[0] >= 'A' && key[0] <= 'Z') return Key(key[0] - 'A' + 'a'); } - /* We use code for 0-9 as it allows us to differentiate towards Numpad digits. - For digits independent of numpad or not, key is e.g. '0' for Zero */ + /* We use code for 0-9 as it allows us to differentiate towards Numpad + digits. For digits independent of numpad or not, key is e.g. '0' for + Zero */ const std::size_t codeLength = std::strlen(code); if(Utility::String::viewBeginsWith({code, codeLength}, "Digit")) { return Key(code[5]); @@ -307,11 +305,9 @@ bool EmscriptenApplication::tryCreate(const Configuration& configuration, const attrs.enableExtensionsByDefault = !!(glConfiguration.flags() & GLConfiguration::Flag::EnableExtensionsByDefault); - #ifdef MAGNUM_TARGET_GLES3 - /* WebGL 2 */ + #ifdef MAGNUM_TARGET_GLES3 /* WebGL 2 */ attrs.majorVersion = 2; - #elif defined(MAGNUM_TARGET_GLES2) - /* WebGL 1 */ + #elif defined(MAGNUM_TARGET_GLES2) /* WebGL 1 */ attrs.minorVersion = 1; #else #error unsupported OpenGL ES version @@ -327,8 +323,8 @@ bool EmscriptenApplication::tryCreate(const Configuration& configuration, const EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context("#canvas", &attrs); if(!context) { - /* When context creation fails, `context` is a negative integer matching - EMSCRIPTEN_RESULT_* defines */ + /* When context creation fails, `context` is a negative integer + matching EMSCRIPTEN_RESULT_* defines */ Error{} << "Platform::EmscriptenApplication::tryCreate(): cannot create WebGL context (EMSCRIPTEN_RESULT" << context << Debug::nospace << ")"; return false; @@ -469,7 +465,7 @@ void EmscriptenApplication::stopTextInput() { } void EmscriptenApplication::setTextInputRect(const Range2Di&) { - // TODO: Place a hidden input field at given rect + /** @todo place a hidden input field at given rect */ } void EmscriptenApplication::viewportEvent(ViewportEvent&) {} @@ -565,12 +561,11 @@ EmscriptenApplication::MouseMoveEvent::Modifiers EmscriptenApplication::MouseMov Vector2 EmscriptenApplication::MouseScrollEvent::offset() const { /* From emscripten's Browser.getMouseWheelDelta() function in - library_browser.js: + library_browser.js: - DOM_DELTA_PIXEL => 100 pixels = 1 step - DOM_DELTA_LINE => 3 lines = 1 step - DOM_DELTA_PAGE => 1 page = 80 steps - */ + DOM_DELTA_PIXEL => 100 pixels = 1 step + DOM_DELTA_LINE => 3 lines = 1 step + DOM_DELTA_PAGE => 1 page = 80 steps */ const Float f = (_event->deltaMode == DOM_DELTA_PIXEL) ? -0.01f : ((_event->deltaMode == DOM_DELTA_LINE) ? -1.0f/3.0f : -80.0f); diff --git a/src/Magnum/Platform/EmscriptenApplication.h b/src/Magnum/Platform/EmscriptenApplication.h index 29c1fb20a..bc3b1cba3 100644 --- a/src/Magnum/Platform/EmscriptenApplication.h +++ b/src/Magnum/Platform/EmscriptenApplication.h @@ -65,16 +65,43 @@ in the @ref building-corrade-cross-emscripten "Corrade" and @section Platform-EmscriptenApplication-bootstrap Bootstrap application -Fully contained base application using @ref EmscriptenApplication for Emscripten -build and CMake setup is available in `base-emscripten` branch of +Fully contained base application using @ref Sdl2Application for desktop build +and @ref EmscriptenApplication for Emscripten build along with full HTML markup +and CMake setup is available in `base-emscripten` branch of the [Magnum Bootstrap](https://github.com/mosra/magnum-bootstrap) repository, download it as [tar.gz](https://github.com/mosra/magnum-bootstrap/archive/base-emscripten.tar.gz) or [zip](https://github.com/mosra/magnum-bootstrap/archive/base-emscripten.zip) -file. After extracting the downloaded archive, you can build in -the same way as with @ref Sdl2Application. +file. After extracting the downloaded archive, you can do the desktop build in +the same way as with @ref Sdl2Application. For the Emscripten build you also +need to put the contents of toolchains repository from +https://github.com/mosra/toolchains in a `toolchains/` subdirectory. There are +two toolchain files. The `generic/Emscripten.cmake` is for the classical +(asm.js) build, the `generic/Emscripten-wasm.cmake` is for WebAssembly build. +Don't forget to adapt `EMSCRIPTEN_PREFIX` variable in +`toolchains/generic/Emscripten*.cmake` to path where Emscripten is installed; +you can also pass it explicitly on command-line using `-DEMSCRIPTEN_PREFIX`. +Default is `/usr/emscripten`. + +Then create build directory and run `cmake` and build/install commands in it. +Set `CMAKE_PREFIX_PATH` to where you have all the dependencies installed, set +`CMAKE_INSTALL_PREFIX` to have the files installed in proper location (a +webserver, e.g. `/srv/http/emscripten`). + +@code{.sh} +mkdir build-emscripten && cd build-emscripten +cmake .. \ + -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Emscripten.cmake" \ + -DCMAKE_PREFIX_PATH=/usr/lib/emscripten/system \ + -DCMAKE_INSTALL_PREFIX=/srv/http/emscripten +cmake --build . +cmake --build . --target install +@endcode + +You can then open `MyApplication.html` in your browser (through a webserver, +e.g. http://localhost/emscripten/MyApplication.html). Detailed information about deployment for Emscripten and all needed boilerplate -together with a troubleshooting guide is available in @ref platforms-emscripten. +together with a troubleshooting guide is available in @ref platforms-html5. @section Platform-EmscriptenApplication-usage General usage @@ -94,7 +121,7 @@ endif() @endcode If no other application is requested, you can also use the generic -`Magnum::Application` alias to simplify porting. Again, see @ref building and +`Magnum::Application` alias to simplify porting. See @ref building and @ref cmake for more information. In C++ code you need to implement at least @ref drawEvent() to be able to draw @@ -409,8 +436,7 @@ class EmscriptenApplication { /** * @brief Whether text input is active * - * If text input is active, text input events go to @ref textInputEvent() - * and @ref textEditingEvent(). + * If text input is active, text input events go to @ref textInputEvent(). * @note Note that in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten" the * value is emulated and might not reflect external events like * closing on-screen keyboard. @@ -423,8 +449,7 @@ class EmscriptenApplication { /** * @brief Start text input * - * Starts text input that will go to @ref textInputEvent() and - * @ref textEditingEvent(). + * Starts text input that will go to @ref textInputEvent(). * @see @ref stopTextInput(), @ref isTextInputActive(), * @ref setTextInputRect() */ @@ -433,10 +458,9 @@ class EmscriptenApplication { /** * @brief Stop text input * - * Stops text input that went to @ref textInputEvent() and - * @ref textEditingEvent(). - * @see @ref startTextInput(), @ref isTextInputActive(), @ref textInputEvent() - * @ref textEditingEvent() + * Stops text input that went to @ref textInputEvent(). + * @see @ref startTextInput(), @ref isTextInputActive(), + * @ref textInputEvent() */ void stopTextInput(); @@ -492,7 +516,7 @@ CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::Flags) /** @brief WebGL context configuration -Double-buffered RGBA canvas with depth and stencil buffers. +The created context is always with a double-buffered OpenGL context. @see @ref EmscriptenApplication(), @ref Configuration, @ref create(), @ref tryCreate() */ @@ -501,80 +525,61 @@ class EmscriptenApplication::GLConfiguration { /** * @brief Context flag * - * @see @ref Flags, @ref setFlags(), @ref Context::Flag - * @requires_gles Context flags are not available in WebGL. + * @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag */ enum class Flag: Int { /** - * Premultiplied alpha - * - * If set, the alpha channel of the rendering context will be - * treated as representing premultiplied alpha values. If not set, the - * alpha channel represents non-premultiplied alpha. + * Premultiplied alpha. If set, the alpha channel of the rendering + * context will be treated as representing premultiplied alpha + * values. If not set, the alpha channel represents + * non-premultiplied alpha. */ PremultipliedAlpha = 1 << 0, /** - * Preserve drawing buffer - * - * If set, the contents of the drawing buffer are preserved between - * consecutive @ref EmscriptenApplication::drawEvent() calls. If not, - * color, depth and stencil are cleared at before - * @ref EmscriptenApplication::drawEvent(). - * Not setting this gives better performance. + * Preserve drawing buffer. If set, the contents of the drawing + * buffer are preserved between consecutive @ref drawEvent() calls. + * If not, color, depth and stencil are cleared before entering + * @ref drawEvent(). Not setting this gives better performance. */ PreserveDrawingBuffer = 1 << 1, /** - * Prefer low power to high performance - * - * If set, the WebGL power preference will be set to reduce power - * consumption. + * Prefer low power to high performance. If set, the WebGL power + * preference will be set to reduce power consumption. */ PreferLowPowerToHighPerformance = 1 << 2, /** - * Fail if major performance caveat - * - * If set, requests context creation to abort if the browser is - * only able to create a context that does not give good hardware- - * accelerated performance. + * Fail if major performance caveat. If set, requests context + * creation to abort if the browser is only able to create a + * context that does not give good hardware-accelerated + * performance. */ FailIfMajorPerformanceCaveat = 1 << 3, /** - * Explicit swap control - * - * For more details, see the - * [Emscripten API reference](https://emscripten.org/docs/api_reference/html5.h.html#c.EmscriptenWebGLContextAttributes.explicitSwapControl) - * for more details. + * Explicit swap control. For more details, see the + * [Emscripten API reference](https://emscripten.org/docs/api_reference/html5.h.html#c.EmscriptenWebGLContextAttributes.explicitSwapControl). */ ExplicitSwapControl = 1 << 4, /** - * Enable WebGL extensions by default - * - * For more details, see the - * [Emscripten API reference](https://emscripten.org/docs/api_reference/html5.h.html#c.EmscriptenWebGLContextAttributes.enableExtensionsByDefault) - * for more details. + * Enable WebGL extensions by default. Enabled by default. For more + * details, see @ref Platform-EmscriptenApplication-webgl and the + * [Emscripten API reference](https://emscripten.org/docs/api_reference/html5.h.html#c.EmscriptenWebGLContextAttributes.enableExtensionsByDefault). */ EnableExtensionsByDefault = 1 << 5, /** - * Render via offscreen back buffer - * - * For more details, see the - * [Emscripten API reference](https://emscripten.org/docs/api_reference/html5.h.html#c.EmscriptenWebGLContextAttributes.renderViaOffscreenBackBuffer) - * for more details. + * Render via offscreen back buffer. For more details, see the + * [Emscripten API reference](https://emscripten.org/docs/api_reference/html5.h.html#c.EmscriptenWebGLContextAttributes.renderViaOffscreenBackBuffer). */ RenderViaOffscreenBackBuffer = 1 << 6, /** - * Proxy content to main thread - * - * For more details, see the - * [Emscripten API reference](https://emscripten.org/docs/api_reference/html5.h.html#c.EmscriptenWebGLContextAttributes.proxyContextToMainThread) - * for more details. + * Proxy content to main thread. For more details, see the + * [Emscripten API reference](https://emscripten.org/docs/api_reference/html5.h.html#c.EmscriptenWebGLContextAttributes.proxyContextToMainThread). */ ProxyContextToMainThread = 1 << 7 }; @@ -582,15 +587,13 @@ class EmscriptenApplication::GLConfiguration { /** * @brief Context flags * - * @see @ref setFlags(), @ref Context::Flags + * @see @ref setFlags(), @ref GL::Context::Flags */ typedef Containers::EnumSet Flags; /*implicit*/ GLConfiguration(); - /** - * @brief Context flags - */ + /** @brief Context flags */ Flags flags() const { return _flags; } /** @@ -714,7 +717,6 @@ CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::GLConfiguration::Flags) /** @brief Configuration -Double-buffered RGBA canvas with depth and stencil buffers. @see @ref EmscriptenApplication(), @ref GLConfiguration, @ref create(), @ref tryCreate() */ @@ -736,6 +738,13 @@ class EmscriptenApplication::Configuration { */ Contextless = 1 << 0, + /** + * Resizable canvas. This causes the framebuffer to be resized + * when the @cb{.html} @ce size changes, either directly + * or as a consequence of browser window size change. + * + * Implement @ref viewportEvent() to react to the resizing events. + */ Resizable = 1 << 1 }; @@ -754,7 +763,7 @@ class EmscriptenApplication::Configuration { * * @note This function does nothing and is included only for * compatibility with other toolkits. You need to set the title - * separately in the `EmscriptenManifest.xml` file. + * separately in the HTML markup. */ template Configuration& setTitle(const T&) { return *this; } @@ -797,9 +806,7 @@ class EmscriptenApplication::Configuration { /** * @brief Set window flags - * @return Reference to self (for method chaining) - * - * Default is @ref WindowFlag::Focused. + * @return Reference to self (for method chaining) */ Configuration& setWindowFlags(WindowFlags windowFlags) { _windowFlags = windowFlags; @@ -959,12 +966,18 @@ class EmscriptenApplication::InputEvent { /** @brief Moving is not allowed */ InputEvent& operator=(InputEvent&&) = delete; - /** @copydoc Sdl2Application::InputEvent::setAccepted() */ - void setAccepted(bool accepted = true) { _accepted = accepted; } - - /** @copydoc Sdl2Application::InputEvent::isAccepted() */ + /** @brief Whether the event is accepted */ bool isAccepted() const { return _accepted; } + /** + * @brief Set event as accepted + * + * If the event is ignored (i.e., not set as accepted), it is + * propagated to other elements on the page. By default each event is + * ignored and thus propagated. + */ + void setAccepted(bool accepted = true) { _accepted = accepted; } + protected: explicit InputEvent(): _accepted(false) {} @@ -1067,12 +1080,7 @@ CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::MouseMoveEvent::Buttons) */ class EmscriptenApplication::MouseScrollEvent: public EmscriptenApplication::InputEvent { public: - - /** - * @brief Scroll offset - * - * Offset in the unit described by @ref MouseScrollEvent::deltaMode(). - */ + /** @brief Scroll offset */ Vector2 offset() const; /** @brief Position */ @@ -1160,33 +1168,33 @@ class EmscriptenApplication::KeyEvent: public EmscriptenApplication::InputEvent */ RightSuper, - Enter, /**< Enter */ - Esc, /**< Escape */ - - Up, /**< Up arrow */ - Down, /**< Down arrow */ - Left, /**< Left arrow */ - Right, /**< Right arrow */ - Home, /**< Home */ - End, /**< End */ - PageUp, /**< Page up */ - PageDown, /**< Page down */ - Backspace, /**< Backspace */ - Insert, /**< Insert */ - Delete, /**< Delete */ - - F1, /**< F1 */ - F2, /**< F2 */ - F3, /**< F3 */ - F4, /**< F4 */ - F5, /**< F5 */ - F6, /**< F6 */ - F7, /**< F7 */ - F8, /**< F8 */ - F9, /**< F9 */ - F10, /**< F10 */ - F11, /**< F11 */ - F12, /**< F12 */ + Enter, /**< Enter */ + Esc, /**< Escape */ + + Up, /**< Up arrow */ + Down, /**< Down arrow */ + Left, /**< Left arrow */ + Right, /**< Right arrow */ + Home, /**< Home */ + End, /**< End */ + PageUp, /**< Page up */ + PageDown, /**< Page down */ + Backspace, /**< Backspace */ + Insert, /**< Insert */ + Delete, /**< Delete */ + + F1, /**< F1 */ + F2, /**< F2 */ + F3, /**< F3 */ + F4, /**< F4 */ + F5, /**< F5 */ + F6, /**< F6 */ + F7, /**< F7 */ + F8, /**< F8 */ + F9, /**< F9 */ + F10, /**< F10 */ + F11, /**< F11 */ + F12, /**< F12 */ Zero = '0', /**< Zero */ One, /**< One */ @@ -1226,11 +1234,11 @@ class EmscriptenApplication::KeyEvent: public EmscriptenApplication::InputEvent Y, /**< Letter Y */ Z, /**< Letter Z */ - Space, /**< Space */ - Tab, /**< Tab */ - Comma, /**< Comma */ - Period, /**< Period */ - Minus, /**< Minus */ + Space, /**< Space */ + Tab, /**< Tab */ + Comma, /**< Comma */ + Period, /**< Period */ + Minus, /**< Minus */ /* Note: This may only be represented as SHIFT + = */ Plus, /**< Plus */ Slash, /**< Slash */ @@ -1270,10 +1278,13 @@ class EmscriptenApplication::KeyEvent: public EmscriptenApplication::InputEvent NumEqual /**< Numpad equal */ }; - /** @brief Key + /** + * @brief Key * - * Note that the key is mapped from `EmscriptenKeyboardEvent::code` in - * all cases except A-Z, which are mapped from `EmscriptenkeyboardEvent::key`, + * Note that the key is mapped from @m_class{m-doc-external} + * [EmscriptenKeyboardEvent::code](https://emscripten.org/docs/api_reference/html5.h.html#c.EmscriptenKeyboardEvent.code) + * in all cases except A--Z, which are mapped from + * @m_class{m-doc-external} [EmscriptenkeyboardEvent::key](https://emscripten.org/docs/api_reference/html5.h.html#c.EmscriptenKeyboardEvent.key), * which respects the keyboard layout. */ Key key() const; @@ -1314,14 +1325,7 @@ class EmscriptenApplication::TextInputEvent { /** @brief Whether the event is accepted */ bool isAccepted() const { return _accepted; } - /** - * @brief Set event as accepted - * - * If the event is ignored (i.e., not set as accepted), it might be - * propagated elsewhere, for example to another screen when using - * @ref BasicScreenedApplication "ScreenedApplication". By default is - * each event ignored and thus propagated. - */ + /** @copydoc EmscriptenApplication::InputEvent::setAccepted() */ void setAccepted(bool accepted = true) { _accepted = accepted; } /** @brief Input text in UTF-8 */ diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h index 1d6fed5d6..6fbd84619 100644 --- a/src/Magnum/Platform/Sdl2Application.h +++ b/src/Magnum/Platform/Sdl2Application.h @@ -109,41 +109,13 @@ See @ref cmake for more information. @section Platform-Sdl2Application-bootstrap-emscripten Bootstrap application for Emscripten -Fully contained base application using @ref Sdl2Application for both desktop -and Emscripten build along with full HTML markup and CMake setup is available -in `base-emscripten` branch of [Magnum Bootstrap](https://github.com/mosra/magnum-bootstrap) -repository, download it as [tar.gz](https://github.com/mosra/magnum-bootstrap/archive/base-emscripten.tar.gz) -or [zip](https://github.com/mosra/magnum-bootstrap/archive/base-emscripten.zip) -file. After extracting the downloaded archive, you can do the desktop build in -the same way as above. For the Emscripten build you also need to put the -contents of toolchains repository from https://github.com/mosra/toolchains -in `toolchains/` subdirectory. There are two toolchain files. The -`generic/Emscripten.cmake` is for the classical (asm.js) build, the -`generic/Emscripten-wasm.cmake` is for WebAssembly build. Don't forget to adapt -`EMSCRIPTEN_PREFIX` variable in `toolchains/generic/Emscripten*.cmake` to path -where Emscripten is installed; you can also pass it explicitly on command-line -using `-DEMSCRIPTEN_PREFIX`. Default is `/usr/emscripten`. - -Then create build directory and run `cmake` and build/install commands in it. -Set `CMAKE_PREFIX_PATH` to where you have all the dependencies installed, set -`CMAKE_INSTALL_PREFIX` to have the files installed in proper location (a -webserver, e.g. `/srv/http/emscripten`). - -@code{.sh} -mkdir build-emscripten && cd build-emscripten -cmake .. \ - -DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Emscripten.cmake" \ - -DCMAKE_PREFIX_PATH=/usr/lib/emscripten/system \ - -DCMAKE_INSTALL_PREFIX=/srv/http/emscripten -cmake --build . -cmake --build . --target install -@endcode - -You can then open `MyApplication.html` in your browser (through a webserver, -e.g. http://localhost/emscripten/MyApplication.html). - -Detailed information about deployment for Emscripten and all needed boilerplate -together with a troubleshooting guide is available in @ref platforms-html5. +The dedicated application implementation for Emscripten is +@ref EmscriptenApplication, which also provides a bootstrap project along with +full HTML markup and CMake setup. @ref Sdl2Application however supports +Emscripten as well --- set up the bootstrap application as +@ref Platform-EmscriptenApplication-bootstrap "described in the EmscriptenApplication docs" +and then change `src/CMakeLists.txt` and the @cpp #include @ce to use +@ref Sdl2Application for both the native and the web build. @section Platform-Sdl2Application-bootstrap-ios Bootstrap application for iOS