Browse Source

Platform: give the docs the love they deserve.

pull/300/head
Vladimír Vondruš 7 years ago
parent
commit
fc4860e30a
  1. 21
      doc/platforms-html5.dox
  2. 41
      src/Magnum/Platform/EmscriptenApplication.cpp
  3. 244
      src/Magnum/Platform/EmscriptenApplication.h
  4. 42
      src/Magnum/Platform/Sdl2Application.h

21
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;
</script>
@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.

41
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);

244
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<Flag> 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} <canvas> @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<class T> 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 */

42
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

Loading…
Cancel
Save