SLProject
4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
|
SLProject provides a framework for quickly setting up platform-independent apps that run on Windows, macOS, Linux, Android, iOS, and the Web. The app framework is divided into three layers:
App.h
header, which is implemented by the platform layer.App.h
. The implementation corresponding to the target platform is selected at compile time by CMake. The platform layer uses SLInterface.h
to access SLProject modules. The platform-specific code is C/C++ for the GLFW platforms (Windows, MacOS & Linux), C/C++ and Java for Android, C/C++ and JavaScript for Emscripten (running in the web browser) and ObjectiveC for iOS. All platform-specific code is under apps/source/platforms
.The main C++ file of an app looks something like this:
The main function is defined using a macro that expands to the name of the main function on the current platform. This is usually main
, but on Android it expands to slAndroidMain
, a fake main function that is called from the JNI to initialize the application because there is no actual main
on Android.
Inside the main function, an App::Config
instance is created. This configuration specifies things like the window size, the ID of the start scene, or a callback for building the GUI. App::run
is then called with this config to start the app. Every platform implements its own version of this function. The various implementations can be found in apps/source/platforms
. Here's a list of all of them:
AppGLFW.cpp
(Windows, macOS, Linux)AppEmscripten.cpp
(Web)AppAndroid.cpp
(Android)AppIOS.mm
(iOS)An implementation of App::run
typically sets up the rendering surface, registers event handlers, loads core assets, starts the event loop, and returns when the program terminates. Only the Android version returns immediately because the event loop is handled by Java code and interacts with the app via the JNI.
For more information on creating a new app, see this wiki page.
New apps are added by calling the custom CMake function sl_add_app
. This function is defined in apps/CMakeLists.txt
and takes care of creating a new target and setting source files, headers, compile options, linked libraries, properties, etc. depending on the target platform. The function has parameters for specifying things like the name of the target, the platforms the app supports, additional source files (e.g. for scenes), the directory of the Android project, or iOS resources.
sl_add_app
uses the CMake variable SL_PLATFORM
to decide which platform is currently being targeted. This variable is set in the top-level CMakeLists.txt
based on the current target system. The possible platforms are:
GLFW
(Windows, macOS, Linux)EMSCRIPTEN
(Web)ANDROID
(Android)IOS
(iOS)A scene is loaded by setting the value of AppCommon::sceneToLoad
to the ID of the new scene. Inside the event loop of every platform, we check whether this variable has a value and switch to the new scene if so:
Scene switching is implemented inside AppLoad::switchScene
. This function calls the callback AppConfig::onNewScene
to create a new scene instance. The callback is specified by the app and returns an instance of a class derived from SLScene
(e.g. AppDemoSceneMinimal
). After creating the new scene instance, we switch to it in two stages:
SLScene::registerAssetsToLoad
so it can register tasks on the SLAssetLoader
to be executed asynchronously in a different thread. Meanwhile, the event loop on the main thread continues running so we can for example render a loading screen. Every frame, SLAssetLoader::checkIfAsyncLoadingIsDone
is called to check whether the worker thread is done. When that happens, the next stage is triggered. Note: All I/O operations have to be registered here because they cannot be executed synchronously on the main thread on the Emscripten platform.SLScene::assemble
function that uses the loaded assets to assemble the scene. After assembly, AppCommon::scene
is set to the new scene and the scene switch is completed.