This is a snapshot of a work-in-progress documentation theme. If you feel lost, miss something, or want to see the original Doxygen docs instead, head over to the archived version of this documentation page.

Magnum::Platform::Sdl2Application class

SDL2 application.

Application using Simple DirectMedia Layer toolkit. Supports keyboard and mouse handling.

This application library is in theory available for all platforms for which SDL2 is ported (thus also Emscripten, see respective sections in Corrade's and Magnum's building documentation). It depends on the SDL2 library (Emscripten has it built in) and is built if WITH_SDL2APPLICATION is enabled in CMake.

Bootstrap application

Fully contained base application using Sdl2Application along with CMake setup is available in base branch of Magnum Bootstrap repository, download it as tar.gz or zip file. After extracting the downloaded archive you can build and run the application with these four commands:

mkdir build && cd build
cmake ..
cmake --build .
./src/MyApplication # or ./src/Debug/MyApplication

See Usage with CMake for more information.

Bootstrap application for Emscripten

Fully contained base application using Sdl2Application for both desktop and Emscripten build along with full HTML markup and CMake setup is available in base-emscripten branch of 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 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).

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

You can then open MyApplication.html in your browser (through webserver, e.g. http://localhost/emscripten/MyApplication.html).

Bootstrap application for iOS

Fully contained base application using Sdl2Application for both desktop and iOS build along with pre-filled *.plist is available in base-ios branch of 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 above. For the iOS build you also need to put the contents of toolchains repository from https://github.com/mosra/toolchains in toolchains/ subdirectory.

Then create build directory and run cmake to generate the Xcode project. Set CMAKE_OSX_ROOT to SDK you want to target and enable all desired architectures in CMAKE_OSX_ARCHITECTURES. Set CMAKE_PREFIX_PATH to the directory where you have all the dependencies.

mkdir build-ios && cd build-ios
cmake .. \
    -DCMAKE_TOOLCHAIN_FILE=../toolchains/generic/iOS.cmake \
    -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk \
    -DCMAKE_OSX_ARCHITECTURES="arm64;armv7;armv7s" \
    -DCMAKE_PREFIX_PATH=~/ios-libs \
    -G Xcode

You can then open the generated project file in Xcode and build/deploy it from there.

Bootstrap application for Windows RT

Fully contained base application using Sdl2Application for both desktop and Windows Phone / Windows Store build along with all required plumbing is available in base-winrt branch of Magnum Bootstrap repository, download it as zip file. After extracting the downloaded archive, you can do the desktop build in the same way as above.

For the Windows RT build you need to provide your own *.pfx certificate file and pass it to CMake in a SIGNING_CERTIFICATE variable. The bootstrap application assumes that SDL2 and ANGLE is built as DLL and both Corrade and Magnum are built statically. Assuming the native Corrade installation is in C:/Sys and all WinRT dependencies are in C:/Sys-winrt, the build can be done similarly to the following:

mkdir build-winrt && cd build-winrt
cmake .. ^
    -DCORRADE_RC_EXECUTABLE="C:/Sys/bin/corrade-rc.exe" ^
    -DCMAKE_PREFIX_PATH="C:/Sys-winrt" ^
    -DCMAKE_SYSTEM_NAME=WindowsStore ^
    -DCMAKE_SYSTEM_VERSION=8.1 ^
    -G "Visual Studio 14 2015" ^
    -DSIGNING_CERTIFICATE=<path-to-your-pfx-file>
cmake --build .

Change WindowsStore to WindowsPhone if you want to build for Windows Phone instead. The build-winrt/src/AppPackages directory will then contain the final package along with a PowerShell script for easy local installation.

General usage

In order to use this library from CMake, you need to copy FindSDL2.cmake from the modules/ directory in Magnum source to the modules/ dir in your project (so it is able to find the SDL2 library). In case of Emscripten you need also FindOpenGLES2.cmake / FindOpenGLES3.cmake. Request the Sdl2Application component of the Magnum package and link to the Magnum::Sdl2Application target:

find_package(Magnum REQUIRED Sdl2Application)

# ...
target_link_libraries(your-app Magnum::Sdl2Application)

If no other application is requested, you can also use the generic Magnum::Application alias to simplify porting. Again, 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. The subclass can be then used directly in main() — see convenience macro MAGNUM_SDL2APPLICATION_MAIN(). See Platform support for more information.

class MyApplication: public Platform::Sdl2Application {
    // implement required methods...
};
MAGNUM_SDL2APPLICATION_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.

Usage with Emscripten

If you are targetting Emscripten, you need to provide HTML markup for your application. Template one is below or in the bootstrap application, you can modify it to your liking. The markup references two files, EmscriptenApplication.js and WebApplication.css, both are in Platform/ directory in the source tree and are also installed into share/magnum/ inside your Emscripten toolchain. Change {{application}} to name of your executable.

<!DOCTYPE html>
<html>
  <head>
    <title>Magnum Emscripten Application</title>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="WebApplication.css" />
  </head>
  <body>
    <h1>Magnum Emscripten Application</h1>
    <div id="listener">
      <canvas id="module"></canvas>
      <div id="status">Initialization...</div>
      <div id="statusDescription"></div>
      <script src="EmscriptenApplication.js"></script>
      <script async="async" src="{{application}}.js"></script>
    </div>
  </body>
</html>

You can modify all the files to your liking, but the HTML file must contain at least the <canvas> enclosed in listener <div>. The JavaScript file contains event listeners which print loading status on the page. The status displayed in the remaining two <div> s, if they are available. The CSS file contains rudimentary style to avoid eye bleeding.

The application redirects all output (thus also Debug, Warning and Error) to JavaScript console. It's possible to pass command-line arguments to main() using GET URL parameters. For example, /app/?foo=bar&fizz&buzz=3 will go to the app as ['--foo', 'bar', '--fizz', '--buzz', '3'].

Usage with iOS

A lot of options for iOS build (such as HiDPI/Retina support, supported display orientation, icons, splash screen...) is specified through the *.plist file. CMake uses its own template that can be configured using various MACOSX_BUNDLE_* variables, but many options are missing from there and you are much better off rolling your own template and passing abosolute path to it to CMake using the MACOSX_BUNDLE_INFO_PLIST property. Below are contents of the *.plist file used in the bootstrap application, requesting OpenGL ES 2.0 and advertising Retina support:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>CFBundleDevelopmentRegion</key>
  <string>en-US</string>
  <key>CFBundleExecutable</key>
  <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
  <key>CFBundleIdentifier</key>
  <string>cz.mosra.magnum.MyApplication</string>
  <key>CFBundleInfoDictionaryVersion</key>
  <string>6.0</string>
  <key>CFBundleName</key>
  <string>My Application</string>
  <key>CFBundlePackageType</key>
  <string>APPL</string>

  <key>UIRequiredDeviceCapabilities</key>
  <array>
    <string>opengles-2</string>
  </array>
  <key>NSHighResolutionCapable</key>
  <true/>
</dict>
</plist>

Some other options can be configured from runtime when creating the SDL2 application window, see documentation of particular value for details:

Usage with Windows RT

For Windows RT you need to provide logo images and splash screen, all referenced from the *.appxmanifest file. The file is slightly different for different targets, template for Windows Store and MSVC 2013 is below, others are in the bootstrap application.

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
  <Identity Name="MyApplication" Publisher="CN=A Publisher" Version="1.1.0.0" />
  <Properties>
    <DisplayName>My Application</DisplayName>
    <PublisherDisplayName>A Publisher</PublisherDisplayName>
    <Logo>assets/logo-store.png</Logo>
  </Properties>
  <Resources>
    <Resource Language="x-generate" />
  </Resources>
  <Applications>
    <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="MyApplication.App">
      <m2:VisualElements
        DisplayName="Magnum Windows Store Application"
        Description="My Application"
        BackgroundColor="#202020"
        ForegroundText="light"
        Square150x150Logo="assets/logo.png"
        Square30x30Logo="assets/logo-small.png">
        <m2:SplashScreen Image="assets/splash.png" />
      </m2:VisualElements>
    </Application>
  </Applications>
</Package>

The assets are referenced also from the main CMakeLists.txt file. You have to mark all non-source files (except for the *.pfx key) with VS_DEPLOYMENT_CONTENT property and optionally set their location with VS_DEPLOYMENT_LOCATION. If you are using *.resw files, these need to have the VS_TOOL_OVERRIDE property set to PRIResource.

Public types

struct Arguments
Application arguments.
class Configuration
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 MultiGestureEvent
Multi gesture event.
class TextEditingEvent
Text editing event.
class TextInputEvent
Text input event.

Constructors, destructors, conversion operators

Sdl2Application(const Arguments& arguments, const Configuration& configuration = Configuration()) explicit
Default constructor.
Sdl2Application(const Arguments& arguments, NoCreateT) explicit
Constructor.
Sdl2Application(const Arguments& arguments, std::nullptr_t) explicit
Sdl2Application(const Sdl2Application&) deleted
Copying is not allowed.
Sdl2Application(Sdl2Application&&) deleted
Moving is not allowed.

Public functions

auto operator=(const Sdl2Application&) -> Sdl2Application& deleted
Copying is not allowed.
auto operator=(Sdl2Application&&) -> Sdl2Application& deleted
Moving is not allowed.
auto exec() -> int
Execute main loop.
void exit()
Exit application main loop.
void mainLoopIteration()
Run one iteration of application main loop.
auto window() -> SDL_Window*
Underlying window handle.

Protected functions

void createContext(const Configuration& configuration = Configuration())
Create context with given configuration.
auto tryCreateContext(const Configuration& configuration) -> bool
Try to create context with given configuration.

Screen handling

auto windowSize() -> Vector2i protected
Window size.
void swapBuffers() protected
Swap buffers.
auto swapInterval() const -> Int protected
Swap interval.
auto setSwapInterval(Int interval) -> bool protected
Set swap interval.
void setMinimalLoopPeriod(UnsignedInt milliseconds) protected
Set minimal loop period.
void redraw() protected
Redraw immediately.
void tickEvent() protected virtual
Tick event.
void viewportEvent(const Vector2i& size) protected virtual
Viewport event.
void drawEvent() protected pure virtual
Draw event.

Keyboard handling

void keyPressEvent(KeyEvent& event) protected virtual
Key press event.
void keyReleaseEvent(KeyEvent& event) protected virtual
Key release event.

Mouse handling

auto isMouseLocked() const -> bool
Whether mouse is locked.
void setMouseLocked(bool enabled)
Enable or disable mouse locking.
void mousePressEvent(MouseEvent& event) protected virtual
Mouse press event.
void mouseReleaseEvent(MouseEvent& event) protected virtual
Mouse release event.
void mouseMoveEvent(MouseMoveEvent& event) protected virtual
Mouse move event.
void mouseScrollEvent(MouseScrollEvent& event) protected virtual
Mouse scroll event.

Touch gesture handling

void multiGestureEvent(MultiGestureEvent& event) protected virtual
Multi gesture event.

Text input handling

auto isTextInputActive() -> 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) protected virtual
Text input event.
void textEditingEvent(TextEditingEvent& event) protected virtual
Text editing event.

Function documentation

Magnum::Platform::Sdl2Application::Sdl2Application(const Arguments& arguments, const Configuration& configuration = Configuration()) explicit

Default constructor.

Parameters
arguments Application arguments
configuration Configuration

Creates application with default or user-specified configuration. See Configuration for more information. The program exits if the context cannot be created, see tryCreateContext() for an alternative.

Magnum::Platform::Sdl2Application::Sdl2Application(const Arguments& arguments, NoCreateT) explicit

Constructor.

Parameters
arguments Application arguments

Unlike above, the context is not created and must be created later with createContext() or tryCreateContext().

Magnum::Platform::Sdl2Application::Sdl2Application(const Arguments& arguments, std::nullptr_t) explicit

Constructor.

int Magnum::Platform::Sdl2Application::exec()

Execute main loop.

Returns Value for returning from main()

Calls mainLoopIteration() in a loop until exit() is called. See MAGNUM_SDL2APPLICATION_MAIN() for usage information.

void Magnum::Platform::Sdl2Application::exit()

Exit application main loop.

Stops main loop started by exec().

void Magnum::Platform::Sdl2Application::mainLoopIteration()

Run one iteration of application main loop.

Called internally from exec(). If you want to have better control over how the main loop behaves, you can call this function yourself from your own main() function instead of it being called automatically from exec() / MAGNUM_SDL2APPLICATION_MAIN().

SDL_Window* Magnum::Platform::Sdl2Application::window()

Underlying window handle.

Use in case you need to call SDL functionality directly.

void Magnum::Platform::Sdl2Application::createContext(const Configuration& configuration = Configuration()) protected

Create context with given configuration.

Must be called if and only if the context wasn't created by the constructor itself. Error message is printed and the program exits if the context cannot be created, see tryCreateContext() for an alternative.

On desktop GL, if version is not specified in configuration, the application first tries to create core context (OpenGL 3.2+ on macOS, OpenGL 3.1+ elsewhere) and if that fails, falls back to compatibility OpenGL 2.1 context.

bool Magnum::Platform::Sdl2Application::tryCreateContext(const Configuration& configuration) protected

Try to create context with given configuration.

Unlike createContext() returns false if the context cannot be created, true otherwise.

Vector2i Magnum::Platform::Sdl2Application::windowSize() protected

Window size.

Window size to which all input event coordinates can be related. Note that especially on HiDPI systems the reported window size might not be the same as framebuffer size.

void Magnum::Platform::Sdl2Application::swapBuffers() protected

Swap buffers.

Paints currently rendered framebuffer on screen.

bool Magnum::Platform::Sdl2Application::setSwapInterval(Int interval) protected

Set swap interval.

Set 0 for no VSync, 1 for enabled VSync. Some platforms support -1 for late swap tearing. Prints error message and returns false if swap interval cannot be set, true otherwise. Default is driver-dependent, you can query the value with swapInterval().

void Magnum::Platform::Sdl2Application::setMinimalLoopPeriod(UnsignedInt milliseconds) protected

Set minimal loop period.

This setting reduces the main loop frequency in case VSync is not/cannot be enabled or no drawing is done. Default is 0 (i.e. looping at maximum frequency).

void Magnum::Platform::Sdl2Application::redraw() protected

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::Sdl2Application::tickEvent() virtual protected

Tick event.

If implemented, this function is called periodically after processing all input events and before draw event even though there might be no input events and redraw is not requested. Useful e.g. for asynchronous task polling. Use setMinimalLoopPeriod()/ setSwapInterval() to control main loop frequency.

void Magnum::Platform::Sdl2Application::viewportEvent(const Vector2i& size) virtual protected

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 DefaultFramebuffer::setViewport() and possibly elsewhere (to SceneGraph::Camera::setViewport(), other framebuffers...).

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. Viewport of default framebuffer can be retrieved via DefaultFramebuffer::viewport().

void Magnum::Platform::Sdl2Application::drawEvent() pure virtual protected

Draw event.

Called when the screen is redrawn. You should clean the framebuffer using DefaultFramebuffer::clear() and then add your own drawing functions. After drawing is finished, call swapBuffers(). If you want to draw immediately again, call also redraw().

void Magnum::Platform::Sdl2Application::keyPressEvent(KeyEvent& event) virtual protected

Key press event.

Called when an key is pressed. Default implementation does nothing.

void Magnum::Platform::Sdl2Application::keyReleaseEvent(KeyEvent& event) virtual protected

Key release event.

Called when an key is released. Default implementation does nothing.

void Magnum::Platform::Sdl2Application::setMouseLocked(bool enabled)

Enable or disable mouse locking.

When mouse is locked, the cursor is hidden and only MouseMoveEvent::relativePosition() is changing, absolute position stays the same.

void Magnum::Platform::Sdl2Application::mousePressEvent(MouseEvent& event) virtual protected

Mouse press event.

Called when mouse button is pressed. Default implementation does nothing.

void Magnum::Platform::Sdl2Application::mouseReleaseEvent(MouseEvent& event) virtual protected

Mouse release event.

Called when mouse button is released. Default implementation does nothing.

void Magnum::Platform::Sdl2Application::mouseMoveEvent(MouseMoveEvent& event) virtual protected

Mouse move event.

Called when mouse is moved. Default implementation does nothing.

void Magnum::Platform::Sdl2Application::mouseScrollEvent(MouseScrollEvent& event) virtual protected

Mouse scroll event.

Called when a scrolling device is used (mouse wheel or scrolling area on a touchpad). Default implementation does nothing.

void Magnum::Platform::Sdl2Application::multiGestureEvent(MultiGestureEvent& event) virtual protected

Multi gesture event.

Called when the user performs a gesture using multiple fingers. Default implementation does nothing.

bool Magnum::Platform::Sdl2Application::isTextInputActive()

Whether text input is active.

If text input is active, text input events go to textInputEvent() and textEditingEvent().

void Magnum::Platform::Sdl2Application::startTextInput()

Start text input.

Starts text input that will go to textInputEvent() and textEditingEvent().

void Magnum::Platform::Sdl2Application::stopTextInput()

Stop text input.

Stops text input that went to textInputEvent() and textEditingEvent().

void Magnum::Platform::Sdl2Application::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::Sdl2Application::textInputEvent(TextInputEvent& event) virtual protected

Text input event.

Called when text input is active and the text is being input.

void Magnum::Platform::Sdl2Application::textEditingEvent(TextEditingEvent& event) virtual protected

Text editing event.

Called when text input is active and the text is being edited.