class new in 2019.10
EmscriptenApplicationEmscripten application.
Application running on Emscripten. Available only on Emscripten, see respective sections in the Corrade and Magnum building documentation.
Bootstrap application
Fully contained base application using Sdl2Application for desktop build and EmscriptenApplication for Emscripten build along with full HTML markup and CMake setup is available in base-emscripten
branch of the Magnum Bootstrap repository, download it as tar.gz or zip file. After extracting the downloaded archive, you can do the desktop build in the same way as with Sdl2Application. For the Emscripten build you also need to put the contents of toolchains repository from https:/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
).
mkdir build-emscripten && cd build-emscripten cmake .. \ -DCMAKE_TOOLCHAIN_FILE=path/to/toolchains/generic/Emscripten-wasm.cmake \ -DCMAKE_PREFIX_PATH=/usr/lib/emscripten/system \ -DCMAKE_INSTALL_PREFIX=/srv/http/emscripten cmake --build . cmake --build . --target install
You can then open MyApplication.html
in your browser (through a webserver, e.g. http:/
Detailed information about deployment for Emscripten and all needed boilerplate together with a troubleshooting guide is available in JavaScript, HTML5 and WebGL.
General usage
This application library is built if MAGNUM_WITH_EMSCRIPTENAPPLICATION
is enabled when building Magnum. To use this library with CMake, request the EmscriptenApplication
component of the Magnum
package and link to the Magnum::EmscriptenApplication
target:
find_package(Magnum REQUIRED) if(CORRADE_TARGET_EMSCRIPTEN) find_package(Magnum REQUIRED EmscriptenApplication) endif() # ... if(CORRADE_TARGET_EMSCRIPTEN) target_link_libraries(your-app PRIVATE Magnum::EmscriptenApplication) endif()
Additionally, if you're using Magnum as a CMake subproject, do the following before calling find_package()
to ensure it's enabled, as the library is not built by default:
set(MAGNUM_WITH_EMSCRIPTENAPPLICATION ON CACHE BOOL "" FORCE) add_subdirectory(magnum EXCLUDE_FROM_ALL)
If no other application is requested, you can also use the generic Magnum::Application
alias to simplify porting. See Downloading and building and Usage with CMake for more information.
In C++ code you need to implement at least drawEvent() to be able to draw on the screen.
class MyApplication: public Platform::EmscriptenApplication { // implement required methods... }; MAGNUM_EMSCRIPTENAPPLICATION_MAIN(MyApplication)
If no other application header is included, this class is also aliased to Platform::Application
and the macro is aliased to MAGNUM_APPLICATION_MAIN()
to simplify porting.
Browser-specific behavior
Leaving a default (zero) size in Configuration will cause the app to use a size that corresponds to CSS pixel size of the <canvas>
element. The size is then multiplied by DPI scaling value, see DPI awareness below for details.
If you enable Configuration::
Unlike desktop platforms, the browser has no concept of application exit code, so the return value of exec() is always 0
and whatever is passed to exit(int) is ignored.
Main loop implementation
Magnum application implementations default to redrawing only when needed to save power and while this is simple to implement efficiently on desktop apps where the application has the full control over the main loop, it's harder in the callback-based browser environment.
Sdl2Application makes use of emscripten_
EmscriptenApplication instead makes use of requestAnimationFrame()
directly — on initialization and on redraw(), an animation frame will be requested and the callback set up. The callback will immediately schedule another animation frame, but cancel that request after drawEvent() if redraw() was not requested. Note that due to the way Emscripten internals work, this also requires the class instance to be stored as a global variable instead of a local variable in main()
. The MAGNUM_
For testing purposes or for more predictable behavior for example when the application has to redraw all the time anyway this can be disabled using Configuration::
WebGL-specific behavior
While WebGL itself requires all extensions to be enabled explicitly, by default Emscripten enables all supported extensions that don't have a negative effect on performance to simplify porting. This is controlled by GLConfiguration::
DPI awareness
Since this application targets only web browsers, DPI handling isn't as general as in case of Sdl2Application or GlfwApplication. See Sdl2Application DPI awareness documentation for a guide covering all platform differences.
For this application in particular, windowSize() can be different than framebufferSize() on HiDPI displays — which is different from Sdl2Application behavior on Emscripten. By default, dpiScaling() is 1.0f
in both dimensions but it can be overridden using custom DPI scaling — the --magnum-dpi-scaling
command-line options are supported the same way as in Sdl2Application, only in the form of URL GET parameters, similarly to all other command-line options.
Having dpiScaling() set to 1.0f
is done in order to have consistent behavior with other platforms — platforms have either windowSize() equivalent to framebufferSize() and then dpiScaling() specifies the UI scale (Windows/Linux/Android-like) or windowSize() different from framebufferSize() (which defines the UI scale) and then dpiScaling() is 1.0f
(macOS/iOS-like), so this is the second case. The actual device pixel ratio is expressed in the ratio of windowSize() and framebufferSize() so crossplatform code shouldn't have a need to query it, however for completeness it's exposed in devicePixelRatio() and ViewportEvent::
Setting custom DPI scaling will affect framebufferSize() (larger values making the canvas backing framebuffer larger and vice versa), windowSize() will stay unaffected as it's controlled by the CSS, and devicePixelRatio() will stay the same as well as it's defined by the browser.
To avoid confusion, documentation of all EmscriptenApplication APIs always mentions only the web case, consult equivalent APIs in Sdl2Application or GlfwApplication for behavior in those implementations.
Public types
- struct Arguments
- Application arguments.
- class Configuration
- Configuration.
- class GLConfiguration
- WebGL context configuration.
- class InputEvent
- Base for input events.
- class KeyEvent
- Key event.
- class MouseEvent
- Mouse event.
- class MouseMoveEvent
- Mouse move event.
- class MouseScrollEvent
- Mouse scroll event.
- class TextInputEvent
- Text input event.
- class ViewportEvent
- Viewport event.
Constructors, destructors, conversion operators
- EmscriptenApplication(const Arguments& arguments, const Configuration& configuration, const GLConfiguration& glConfiguration) explicit
- Construct with a WebGL context.
- EmscriptenApplication(const Arguments& arguments, const Configuration& configuration = Configuration{}) explicit
- Construct without explicit GPU context configuration.
- EmscriptenApplication(const Arguments& arguments, NoCreateT) explicit
- Construct without setting up a canvas.
- EmscriptenApplication(const EmscriptenApplication&) deleted
- Copying is not allowed.
- EmscriptenApplication(EmscriptenApplication&&) deleted
- Moving is not allowed.
Public functions
- auto operator=(const EmscriptenApplication&) -> EmscriptenApplication& deleted
- Copying is not allowed.
- auto operator=(EmscriptenApplication&&) -> EmscriptenApplication& deleted
- Moving is not allowed.
- auto exec() -> int
- Execute the application.
- void exit(int exitCode = 0)
- Exit application main loop.
- auto glContext() -> EMSCRIPTEN_WEBGL_CONTEXT_HANDLE
- Underlying WebGL context.
Protected functions
- void create(const Configuration& configuration, const GLConfiguration& glConfiguration)
- Set up a canvas with given configuration for WebGL context.
- void create(const Configuration& configuration)
- Set up a canvas with given configuration and WebGL context.
- void create()
- Set up a canvas with default configuration and WebGL context.
- auto tryCreate(const Configuration& configuration, const GLConfiguration& glConfiguration) -> bool
- Try to create context with given configuration for WebGL context.
- auto tryCreate(const Configuration& configuration) -> bool
- Try to create context with given configuration.
Screen handling
- auto windowSize() const -> Vector2i
- Canvas size.
- auto framebufferSize() const -> Vector2i
- Framebuffer size.
- auto dpiScaling() const -> Vector2
- DPI scaling.
- auto dpiScaling(const Configuration& configuration) const -> Vector2
- DPI scaling for given configuration.
- auto devicePixelRatio() const -> Vector2
- Device pixel ratio.
-
void setWindowTitle(Containers::
StringView title) - Set window title.
-
void setContainerCssClass(Containers::
StringView cssClass) - Set container CSS class.
- void swapBuffers()
- Swap buffers.
- void redraw()
- Redraw immediately.
- void viewportEvent(ViewportEvent& event) private virtual
- Viewport event.
- void drawEvent() private pure virtual
- Draw event.
Keyboard handling
- void keyPressEvent(KeyEvent& event) private virtual
- Key press event.
- void keyReleaseEvent(KeyEvent& event) private virtual
- Key release event.
Mouse handling
- enum class Cursor: UnsignedInt { Auto, Arrow, Hidden, ContextMenu, Help, Hand, WaitArrow, Wait, Cell, Crosshair, TextInput, VerticalTextInput, Alias, Copy, ResizeAll, NoDrop, No, Grab, Grabbing, AllScroll, ColResize, RowResize, ResizeN, ResizeE, ResizeS, ResizeW, ResizeNE, ResizeNW, ResizeSE, ResizeSW, ResizeWE, ResizeNS, ResizeNESW, ResizeNWSE, ZoomIn, ZoomOut } new in 2020.06
- Cursor type.
- void setCursor(Cursor cursor) new in 2020.06
- Set cursor type.
- auto cursor() -> Cursor new in 2020.06
- Get current cursor type.
- void mousePressEvent(MouseEvent& event) private virtual
- Mouse press event.
- void mouseReleaseEvent(MouseEvent& event) private virtual
- Mouse release event.
- void mouseMoveEvent(MouseMoveEvent& event) private virtual
- Mouse move event.
- void mouseScrollEvent(MouseScrollEvent& event) private virtual
- Mouse scroll event.
Text input handling
- auto isTextInputActive() const -> bool
- Whether text input is active.
- void startTextInput()
- Start text input.
- void stopTextInput()
- Stop text input.
- void setTextInputRect(const Range2Di& rect)
- Set text input rectangle.
- void textInputEvent(TextInputEvent& event) private virtual
- Text input event.
Enum documentation
enum class Magnum:: Platform:: EmscriptenApplication:: Cursor: UnsignedInt new in 2020.06
Cursor type.
Value names in this enum don't necessarily match the CSS names in order to be compatible with Sdl2Application and GlfwApplication.
Enumerators | |
---|---|
Auto |
The browser determines the cursor depending on the context. Since this affects the cursor when hovering the |
Arrow |
Arrow. Matches |
Hidden |
Hidden. Matches |
ContextMenu |
Context menu. Matches |
Help |
Help. Matches |
Hand |
Hand. Matches |
WaitArrow |
Small wait cursor. Matches |
Wait |
Wait. Matches |
Cell |
Cell. Matches |
Crosshair |
Crosshair. Matches |
TextInput |
Text input. Matches |
VerticalTextInput |
Vertical text input. Matches |
Alias |
Alias. Matches |
Copy |
Copy. Matches |
ResizeAll |
Four pointed arrow pointing north, south, east, and west. Matches |
NoDrop |
Drop not allowed. Matches |
No |
Slashed circle or crossbones. Matches |
Grab |
Grab. Matches |
Grabbing |
Grabbing. Matches |
AllScroll |
Scroll in any direction. Matches |
ColResize |
Column resize. Matches |
RowResize |
Row resize. Matches |
ResizeN |
Resize arrow pointing north. Matches |
ResizeE |
Resize arrow pointing east. Matches |
ResizeS |
Resize arrow pointing south. Matches |
ResizeW |
Resize arrow pointing west. Matches |
ResizeNE |
Resize arrow pointing northeast. Matches |
ResizeNW |
Resize arrow pointing northwest. Matches |
ResizeSE |
Resize arrow pointing southeast. Matches |
ResizeSW |
Resize arrow pointing southwest. Matches |
ResizeWE |
Double resize arrow pointing west and east. Matches |
ResizeNS |
Double resize arrow pointing north and south. Matches |
ResizeNESW |
Double resize arrow pointing northeast and southwest. Matches |
ResizeNWSE |
Double resize arrow pointing northwest and southeast. Matches |
ZoomIn |
Zoom in. Matches |
ZoomOut |
Zoom out. Matches |
Function documentation
Magnum:: Platform:: EmscriptenApplication:: EmscriptenApplication(const Arguments& arguments,
const Configuration& configuration,
const GLConfiguration& glConfiguration) explicit
Construct with a WebGL context.
Parameters | |
---|---|
arguments | Application arguments |
configuration | Application configuration |
glConfiguration | WebGL context configuration |
Creates application with default or user-specified configuration. See Configuration for more information. The program exits if the context cannot be created, see tryCreate() for an alternative.
Magnum:: Platform:: EmscriptenApplication:: EmscriptenApplication(const Arguments& arguments,
const Configuration& configuration = Configuration{}) explicit
Construct without explicit GPU context configuration.
If Configuration::
If none of the flags is present and Magnum was built with MAGNUM_
See also Enabling or disabling features for more information.
Magnum:: Platform:: EmscriptenApplication:: EmscriptenApplication(const Arguments& arguments,
NoCreateT) explicit
Construct without setting up a canvas.
Parameters | |
---|---|
arguments | Application arguments |
Unlike above, the canvas is not set up and must be created later with create() or tryCreate().
int Magnum:: Platform:: EmscriptenApplication:: exec()
Execute the application.
Sets up Emscripten to execute event handlers until exit() is called. See MAGNUM_
void Magnum:: Platform:: EmscriptenApplication:: exit(int exitCode = 0)
Exit application main loop.
Parameters | |
---|---|
exitCode | Ignored, present only for API compatibility with other app implementations. |
When called from application constructor, it will cause the application to exit immediately after constructor ends, without any events being processed. Calling this function is recommended over std::return
after calling it, as it can't exit the constructor on its own:
MyApplication::MyApplication(const Arguments& arguments): Platform::Application{arguments, NoCreate} { // … if(!everythingGoingAsExpected) { exit(1); return; } // … }
When called from the main loop, the application exits cleanly before next main loop iteration is executed.
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE Magnum:: Platform:: EmscriptenApplication:: glContext()
Underlying WebGL context.
Use in case you need to call Emscripten functionality directly. Returns 0
in case the context was not created yet.
void Magnum:: Platform:: EmscriptenApplication:: create(const Configuration& configuration,
const GLConfiguration& glConfiguration) protected
Set up a canvas with given configuration for WebGL context.
Parameters | |
---|---|
configuration | Application configuration |
glConfiguration | WebGL context configuration |
Must be called only if the context wasn't created by the constructor itself, i.e. when passing NoCreate to it. Error message is printed and the program exits if the context cannot be created, see tryCreate() for an alternative.
void Magnum:: Platform:: EmscriptenApplication:: create(const Configuration& configuration) protected
Set up a canvas with given configuration and WebGL context.
Equivalent to calling create(const Configuration&, const GLConfiguration&) with default-constructed GLConfiguration.
void Magnum:: Platform:: EmscriptenApplication:: create() protected
Set up a canvas with default configuration and WebGL context.
Equivalent to calling create(const Configuration&) with default-constructed Configuration.
bool Magnum:: Platform:: EmscriptenApplication:: tryCreate(const Configuration& configuration,
const GLConfiguration& glConfiguration) protected
Try to create context with given configuration for WebGL context.
Unlike create(const Configuration&, const GLConfiguration&) returns false
if the context cannot be created, true
otherwise.
bool Magnum:: Platform:: EmscriptenApplication:: tryCreate(const Configuration& configuration) protected
Try to create context with given configuration.
Unlike create(const Configuration&) returns false
if the context cannot be created, true
otherwise.
Vector2i Magnum:: Platform:: EmscriptenApplication:: windowSize() const
Canvas size.
Canvas size to which all input event coordinates can be related. On HiDPI displays, canvas size can be different from framebufferSize(). See DPI awareness for more information. Note that this method is named "window size" to be API-compatible with Application implementations on other platforms.
Vector2i Magnum:: Platform:: EmscriptenApplication:: framebufferSize() const
Framebuffer size.
On HiDPI displays, framebuffer size can be different from windowSize(). See DPI awareness for more information.
Vector2 Magnum:: Platform:: EmscriptenApplication:: dpiScaling() const
DPI scaling.
How the content should be scaled relative to system defaults for given windowSize(). If a window is not created yet, returns zero vector, use dpiScaling(const Configuration&) const for calculating a value depending on user configuration. By default set to 1.0
, see DPI awareness for more information.
Vector2 Magnum:: Platform:: EmscriptenApplication:: dpiScaling(const Configuration& configuration) const
DPI scaling for given configuration.
Calculates DPI scaling that would be used when creating a window with given configuration
. Takes into account DPI scaling policy and custom scaling specified via URL GET parameters. See DPI awareness for more information. devicePixelRatio()
Vector2 Magnum:: Platform:: EmscriptenApplication:: devicePixelRatio() const
Device pixel ratio.
Crossplatform code shouldn't need to query this value because the pixel ratio is already expressed in the ratio of windowSize() and framebufferSize() values.
void Magnum:: Platform:: EmscriptenApplication:: setWindowTitle(Containers:: StringView title)
Set window title.
The title
is expected to be encoded in UTF-8.
void Magnum:: Platform:: EmscriptenApplication:: setContainerCssClass(Containers:: StringView cssClass)
Set container CSS class.
Assigns given CSS class to the <div class="mn-container">
enclosing the application <canvas>
. Useful for example to change aspect ratio of the view or stretch it to cover the full page. See Modifying page style, canvas size and aspect ratio for more information about possible values. Note that this replaces any existing class (except for .mn-container
, which is kept), to set multiple classes separate them with whitespace.
void Magnum:: Platform:: EmscriptenApplication:: swapBuffers()
Swap buffers.
Paints currently rendered framebuffer on screen.
void Magnum:: Platform:: EmscriptenApplication:: redraw()
Redraw immediately.
Marks the window for redrawing, resulting in call to drawEvent() in the next iteration. You can call it from drawEvent() itself to redraw immediately without waiting for user input.
void Magnum:: Platform:: EmscriptenApplication:: viewportEvent(ViewportEvent& event) virtual private
Viewport event.
Called when window size changes. The default implementation does nothing. If you want to respond to size changes, you should pass the new size to GL::
Note that this function might not get called at all if the window size doesn't change. You should configure the initial state of your cameras, framebuffers etc. in application constructor rather than relying on this function to be called. Size of the window can be retrieved using windowSize(), size of the backing framebuffer via framebufferSize() and DPI scaling using dpiScaling(). See DPI awareness for detailed info about these values.
void Magnum:: Platform:: EmscriptenApplication:: drawEvent() pure virtual private
Draw event.
Called when the screen is redrawn. You should clean the framebuffer using GL::
void Magnum:: Platform:: EmscriptenApplication:: keyPressEvent(KeyEvent& event) virtual private
Key press event.
Called when an key is pressed. Default implementation does nothing.
void Magnum:: Platform:: EmscriptenApplication:: keyReleaseEvent(KeyEvent& event) virtual private
Key release event.
Called when an key is released. Default implementation does nothing.
void Magnum:: Platform:: EmscriptenApplication:: setCursor(Cursor cursor) new in 2020.06
Set cursor type.
Default is Cursor::
void Magnum:: Platform:: EmscriptenApplication:: mousePressEvent(MouseEvent& event) virtual private
Mouse press event.
Called when mouse button is pressed. Default implementation does nothing.
void Magnum:: Platform:: EmscriptenApplication:: mouseReleaseEvent(MouseEvent& event) virtual private
Mouse release event.
Called when mouse button is released. Default implementation does nothing.
void Magnum:: Platform:: EmscriptenApplication:: mouseMoveEvent(MouseMoveEvent& event) virtual private
Mouse move event.
Called when mouse is moved. Default implementation does nothing.
void Magnum:: Platform:: EmscriptenApplication:: mouseScrollEvent(MouseScrollEvent& event) virtual private
Mouse scroll event.
Called when a scrolling device is used (mouse wheel or scrolling area on a touchpad). Default implementation does nothing.
bool Magnum:: Platform:: EmscriptenApplication:: isTextInputActive() const
Whether text input is active.
If text input is active, text input events go to textInputEvent().
void Magnum:: Platform:: EmscriptenApplication:: startTextInput()
Start text input.
Starts text input that will go to textInputEvent().
void Magnum:: Platform:: EmscriptenApplication:: stopTextInput()
Stop text input.
Stops text input that went to textInputEvent().
void Magnum:: Platform:: EmscriptenApplication:: setTextInputRect(const Range2Di& rect)
Set text input rectangle.
The rect
defines an area where the text is being displayed, for example to hint the system where to place on-screen keyboard.
void Magnum:: Platform:: EmscriptenApplication:: textInputEvent(TextInputEvent& event) virtual private
Text input event.
Called when text input is active and the text is being input.