SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
AppCommon.cpp
Go to the documentation of this file.
1 /**
2  * \file AppCommon.cpp
3  * \brief The AppCommon class holds the top-level instances for SLProject apps
4  * \details For more info on how to create a new app with SLProject see:
5  * https://github.com/cpvrlab/SLProject4/wiki/Creating-a-New-App
6  * For more info about App framework see:
7  * https://cpvrlab.github.io/SLProject4/app-framework.html
8  * \date Februar 2014
9  * \authors Marcus Hudritsch
10  * \copyright http://opensource.org/licenses/GPL-3.0
11  * \remarks Please use clangformat to format the code. See more code style on
12  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
13  */
14 
15 #include <App.h>
16 #include <AppCommon.h>
17 #include <SL.h>
18 #include <SLAssetManager.h>
19 #include <SLScene.h>
20 #include <SLSceneView.h>
21 #include <SLUiInterface.h>
22 #include <SLImGui.h>
23 #include <utility>
24 #include <GlobalTimer.h>
25 #include <SLGLProgramManager.h>
26 #include <SLOptix.h>
27 #include <SLAssetLoader.h>
28 
29 //-----------------------------------------------------------------------------
30 //! Global static objects
34 SLScene* AppCommon::scene = nullptr;
35 vector<SLSceneView*> AppCommon::sceneViews;
36 SLUiInterface* AppCommon::gui = nullptr;
39 std::optional<SLSceneID> AppCommon::sceneToLoad;
40 SLstring AppCommon::name = "SLProjectApp";
41 SLstring AppCommon::appTag = "SLProject";
42 SLstring AppCommon::version = "4.2.001"; // 7.10.2024
43 
44 //! ASCII Label: https://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=SLProject%204.2
46  ______ ___ _ __ ____ ___
47  / __/ / / _ \_______ (_)__ ____/ /_ / / / |_ |
48  _\ \/ /__/ ___/ __/ _ \ / / -_) __/ __/ /_ _/ / __/
49 /___/____/_/ /_/ \___/_/ /\__/\__/\__/ /_/(_)____/
50  |___/
51 )";
52 
53 #ifdef _DEBUG
55 #else
57 #endif
58 SLstring AppCommon::gitBranch = SL_GIT_BRANCH;
59 SLstring AppCommon::gitCommit = SL_GIT_COMMIT;
60 SLstring AppCommon::gitDate = SL_GIT_DATE;
61 map<string, string> AppCommon::deviceParameter;
62 
67 
70 
80 
82 deque<function<void(void)>> AppCommon::jobsToBeThreaded;
83 deque<function<void(void)>> AppCommon::jobsToFollowInMain;
84 atomic<bool> AppCommon::jobIsRunning(false);
85 string AppCommon::_jobProgressMsg = "";
86 atomic<int> AppCommon::_jobProgressNum(0);
87 atomic<int> AppCommon::_jobProgressMax(0);
89 
90 const string AppCommon::CALIB_FTP_HOST = "pallas.ti.bfh.ch:21";
91 const string AppCommon::CALIB_FTP_USER = "upload";
92 const string AppCommon::CALIB_FTP_PWD = "FaAdbD3F2a";
93 const string AppCommon::CALIB_FTP_DIR = "calibrations";
94 const string AppCommon::PROFILE_FTP_DIR = "profiles";
95 
96 //-----------------------------------------------------------------------------
97 //! Application creation function
98 /*! Writes and inits the static application information and create the single
99 instances of SLGLState, SLAssetManager and SLAssetLoader. Gets called by the
100 C-interface function slCreateApp.
101 <br>
102 <br>
103 See examples usages in:
104  - platforms/android/AppAndroid.cpp in the App::run function
105  - platforms/emscripten/AppEmscripten.cpp in the App::run function
106  - platforms/glfw/AppGLFW.cpp in the App::run function
107  - platforms/ios/ViewController.mm in the viewDidLoad function
108 <br>
109 /param applicationName The apps name
110 */
112 {
113  assert(AppCommon::scene == nullptr &&
114  "You can create only one AppCommon");
115 
116  // Initialize the global SLGLState instance
118 
119  name = std::move(appName);
121 
123 
128 
130 
131 #ifdef SL_HAS_OPTIX
132  SLOptix::exePath = AppCommon::exePath;
133  SLOptix::createStreamAndContext();
134 #endif
135 }
136 //-----------------------------------------------------------------------------
137 /*! Registers core assets to load async by all apps. Scene specific assets have
138 to be loaded async by overriding SLScene::registerAssetsToLoad and
139 SLScene::assemble. Async loading and assembling means that it happens in a
140 parallel thread and that inthere are no OpenGL calls allowed. OpenGL calls are
141 only allowed in the main thread.
142 */
144 {
147 
148  // FIXME: There are dependencies between these load tasks, how do we express this?
149 
150  // Load all core shader programs.
151  al.addLoadTask([am]
153 
154  // Generate static fonts.
157 
158  // Load data for ImGUI fonts.
160  AppCommon::fontPath + "DroidSans.ttf",
161  IOK_font);
163  AppCommon::fontPath + "ProggyClean.ttf",
164  IOK_font);
165 }
166 //-----------------------------------------------------------------------------
167 /*!
168  * Deletes the current scene and creates a new one identified by the sceneID.
169  * All assets get registered for async loading while Imgui shows a progress
170  * spinner in the UI. After the parallel loading the scene gets assembled back
171  * in the main thread.
172  * \param sv Pointer to the sceneview
173  * \param sceneID Scene identifier defined in SLEnum
174  */
176 {
179 
180  SLfloat startLoadMS = GlobalTimer::timeMS();
181 
182  //////////////////////
183  // Delete old scene //
184  //////////////////////
185 
188 
189  if (AppCommon::scene)
190  {
191  delete AppCommon::scene;
192  AppCommon::scene = nullptr;
193  }
194 
195  // Deactivate in general the device sensors
198 
199  // reset existing sceneviews
200  for (auto* sceneView : AppCommon::sceneViews)
201  sceneView->unInit();
202 
203  // Clear all data in the asset manager
204  am->clear();
205 
206  ////////////////////
207  // Init new scene //
208  ////////////////////
209 
212  SL_LOG("Scene name : %s (SceneID: %d)",
213  s->name().c_str(),
215 
216  // Initialize all preloaded stuff from SLScene
217  s->init(am);
218 
219 #ifndef SL_EMSCRIPTEN
220  s->initOculus(AppCommon::dataPath + "shaders/");
221 #endif
222 
223  // Reset the global SLGLState state
225 
226  ///////////////////////////////
227  // Prepare for async loading //
228  ///////////////////////////////
229 
230  // Register assets on the loader that have to be loaded before assembly.
231  al->scene(s);
232  s->registerAssetsToLoad(*al);
233 
234  // `onDone` is a wrapper around `onDoneLoading` that will be called
235  // in the main thread after loading.
236  auto onDone = std::bind(onDoneLoading, sv, s, startLoadMS);
237 
238  // Start loading assets asynchronously.
239  al->loadAssetsAsync(onDone);
240 
243 }
244 //-----------------------------------------------------------------------------
245 /*! OnDoneLoading is called when the asyn asset loading is finished and the
246 async scene assembly can be started.
247 */
249 {
252 
253  // Register a task to assemble the scene.
254  al->addLoadTask(std::bind(&SLScene::assemble, s, am, sv));
255 
256  // `onDone` is a wrapper around `onDoneAssembling` that will be called
257  // in the main thread after loading.
258  auto onDone = std::bind(onDoneAssembling, sv, s, startLoadMS);
259 
260  // Start assembling the scene asynchronously.
261  al->loadAssetsAsync(onDone);
262 
265 }
266 //-----------------------------------------------------------------------------
268 {
269  /* Assign the scene to the sceneview. The sceneview exists and is used
270  * before it knows its scene. This is new since we do async loading and
271  * show a spinner in the sceneview. */
272  sv->scene(s);
273  sv->postSceneLoad();
274 
275  // Make sure the scene view has a camera
276  if (!sv->camera())
278 
279  // call onInitialize on all scene views to init the scenegraph and stats
280  for (auto* sceneView : AppCommon::sceneViews)
281  if (sceneView != nullptr)
282  sceneView->onInitialize();
283 
285 
288 
289  s->loadTimeMS(GlobalTimer::timeMS() - startLoadMS);
290 }
291 //-----------------------------------------------------------------------------
292 //! Calls the destructor of the single scene instance.
293 /*! Destroys all data by calling the destructor of the single scene instance.
294 All other date gets destroyed from there. This function gets called by the
295 SLProject C-Interface function slTerminate that should be called at the end of
296 any SLProject application.
297 */
299 {
300  // The WebGL context is apparently already destroyed when we call this function
301 #ifndef SL_EMSCRIPTEN
302  assert(AppCommon::scene != nullptr &&
303  "You can delete a scene only once");
304 
305  for (auto* sv : sceneViews)
306  delete sv;
307  sceneViews.clear();
308 
309  delete scene;
310  scene = nullptr;
311 
312  delete assetManager;
313  assetManager = nullptr;
314 
315  delete assetLoader;
316  assetLoader = nullptr;
317 #endif
318 
319  if (gui)
320  {
321  delete gui;
322  gui = nullptr;
323  }
324 
325  // Deallocate global font data.
328 
329  // The WebGL context is apparently already destroyed when we call this function
330 #ifndef SL_EMSCRIPTEN
331  // delete default stuff:
334 #endif
335 
336  // Delete the default materials
339 
340  // Delete the global SLGLState instance
342 }
343 //-----------------------------------------------------------------------------
344 //! Starts parallel job if one is queued.
345 /*!
346 Parallel executed job can be queued in jobsToBeThreaded. Only functions are
347 allowed that do not call any OpenGL functions. So no scenegraph changes are
348 allowed because they involve mostly OpenGL state and context changes.
349 Only one parallel job is executed at once parallel to the main rendering thread.
350 The function in jobsToFollowInMain will be executed in the main tread after the
351 parallel are finished.<br>
352 The handleParallelJob function gets called in slUpdateAndPaint before a new
353 frame gets started. See an example parallel job definition in AppDemoGui.
354 If a parallel job is running the jobProgressMsg can be shown during execution.
355 If jobProgressMax is 0 the jobProgressNum value can be shown an number.
356 If jobProgressMax is not 0 the fraction of jobProgressNum/jobProgressMax can
357 be shown within a progress bar. See the example in AppDemoGui::build.
358 */
360 {
361  // Execute queued jobs in a parallel thread
364  {
365  function<void(void)> job = AppCommon::jobsToBeThreaded.front();
366  thread jobThread(job);
368  AppCommon::jobsToBeThreaded.pop_front();
369  jobThread.detach();
370  }
371 
372  // Execute the jobs to follow in the this (the main) thread
374  AppCommon::jobsToBeThreaded.empty() &&
376  {
377  for (const auto& jobToFollow : AppCommon::jobsToFollowInMain)
378  jobToFollow();
380  }
381 }
382 //-----------------------------------------------------------------------------
383 //! Thread-safe setter of the progress message
385 {
386  AppCommon::_jobMutex.lock();
387  AppCommon::_jobProgressMsg = std::move(msg);
388  AppCommon::_jobMutex.unlock();
389 }
390 //-----------------------------------------------------------------------------
391 //! Thread-safe getter of the progress message
393 {
394  lock_guard<mutex> guard(_jobMutex);
395  return _jobProgressMsg;
396 }
397 //-----------------------------------------------------------------------------
The App namespace declares the App::Config struct and the App::run function.
The AppCommon class holds the top-level instances of the app-demo.
static void onBeforeSceneAssembly(SLSceneView *sv, SLScene *s)
static void onAfterSceneAssembly(SLSceneView *sv, SLScene *s)
static void onBeforeSceneDelete(SLSceneView *sv, SLScene *s)
static void onBeforeSceneLoad(SLSceneView *sv, SLScene *s)
float SLfloat
Definition: SL.h:173
#define SL_LOG(...)
Definition: SL.h:233
string SLstring
Definition: SL.h:158
int SLSceneID
Scene identifier.
Definition: SLEnums.h:91
constexpr SLSceneID SL_EMPTY_SCENE_ID
SLSceneID for an empty scene.
Definition: SLEnums.h:94
@ IOK_font
Definition: SLFileStorage.h:43
typedef void(SL_STDCALL *cbOnImGuiBuild)(SLScene *s
Callback function typedef for ImGui build function.
SLSceneView * sv
Definition: SLGLImGui.h:28
Wrapper Class around the external ImGui GUI-framework.
SLScene * s
Definition: SLScene.h:31
SLScene SLSceneView SLint sceneID
Definition: SLScene.h:33
static void handleParallelJob()
Starts parallel job if one is queued.
Definition: AppCommon.cpp:359
static SLstring asciiLabel
SLProject ascii label string.
Definition: AppCommon.h:75
static const string CALIB_FTP_HOST
ftp host for calibration up and download
Definition: AppCommon.h:114
static CVCalibrationEstimator * calibrationEstimator
Definition: AppCommon.h:107
static SLstring version
SLProject version string.
Definition: AppCommon.h:74
static SLDeviceRotation devRot
Mobile device rotation from IMU.
Definition: AppCommon.h:64
static SLstring name
Application name.
Definition: AppCommon.h:72
static void registerCoreAssetsLoad()
Definition: AppCommon.cpp:143
static SLIOBuffer fontDataProp
Definition: AppCommon.h:111
static const string CALIB_FTP_USER
ftp login user for calibration up and download
Definition: AppCommon.h:115
static SLstring fontPath
Path to font images.
Definition: AppCommon.h:87
static atomic< int > _jobProgressMax
Max. integer progress value.
Definition: AppCommon.h:126
static deque< function< void(void)> > jobsToBeThreaded
Queue of functions to be executed in a thread.
Definition: AppCommon.h:102
static const string CALIB_FTP_DIR
ftp directory for calibration up and download
Definition: AppCommon.h:117
static SLstring configPath
Default path for calibration files.
Definition: AppCommon.h:81
static SLstring calibIniPath
That's where data/calibrations folder is located.
Definition: AppCommon.h:108
static optional< SLSceneID > sceneToLoad
Scene id to load at start up.
Definition: AppCommon.h:90
static string jobProgressMsg()
Thread-safe getter of the progress message.
Definition: AppCommon.cpp:392
static string _jobProgressMsg
Text message to show during progress.
Definition: AppCommon.h:124
static SLAssetManager * assetManager
asset manager is the owner of all assets
Definition: AppCommon.h:59
static SLstring exePath
executable root path
Definition: AppCommon.h:80
static const string CALIB_FTP_PWD
ftp login pwd for calibration up and download
Definition: AppCommon.h:116
static SLstring gitCommit
Current GIT commit short hash id.
Definition: AppCommon.h:78
static atomic< bool > jobIsRunning
True if a parallel job is running.
Definition: AppCommon.h:104
static SLDeviceLocation devLoc
Mobile device location from GPS.
Definition: AppCommon.h:65
static SLUiInterface * gui
Pointer to the GUI.
Definition: AppCommon.h:63
static const string PROFILE_FTP_DIR
ftp directory for profiles upload
Definition: AppCommon.h:118
static SLstring modelPath
Path to 3D models.
Definition: AppCommon.h:85
static SLstring gitBranch
Current GIT branch.
Definition: AppCommon.h:77
static atomic< int > _jobProgressNum
Integer value to show progress.
Definition: AppCommon.h:125
static SLVSceneView sceneViews
Vector of sceneview pointers.
Definition: AppCommon.h:62
static SLIOBuffer fontDataFixed
Definition: AppCommon.h:112
static SLstring texturePath
Path to texture images.
Definition: AppCommon.h:86
static deque< function< void(void)> > jobsToFollowInMain
Queue of function to follow in the main thread.
Definition: AppCommon.h:103
static void onDoneLoading(SLSceneView *sv, SLScene *s, SLfloat startLoadMS)
Definition: AppCommon.cpp:248
static void switchScene(SLSceneView *sv, SLSceneID sceneID)
Definition: AppCommon.cpp:175
static CVCalibrationEstimatorParams calibrationEstimatorParams
Definition: AppCommon.h:106
static SLstring videoPath
Path to video files.
Definition: AppCommon.h:88
static SLstring gitDate
Current GIT commit date.
Definition: AppCommon.h:79
static SLstring configuration
Debug or Release configuration.
Definition: AppCommon.h:76
static void createApp(SLstring appName)
Application creation function.
Definition: AppCommon.cpp:111
static SLstring shaderPath
Path to GLSL shader programs.
Definition: AppCommon.h:84
static SLAssetLoader * assetLoader
Asset-loader for async asset loading.
Definition: AppCommon.h:60
static SLInputManager inputManager
Input events manager.
Definition: AppCommon.h:58
static void onDoneAssembling(SLSceneView *sv, SLScene *s, SLfloat startLoadMS)
Definition: AppCommon.cpp:267
static mutex _jobMutex
Mutex to protect parallel access.
Definition: AppCommon.h:127
static SLstring appTag
Tag string used in logging.
Definition: AppCommon.h:73
static SLstring externalPath
Default path for external file storage.
Definition: AppCommon.h:82
static SLSceneID sceneID
ID of currently loaded scene.
Definition: AppCommon.h:89
static SLScene * scene
Pointer to the one and only SLScene instance.
Definition: AppCommon.h:61
static map< string, string > deviceParameter
Generic device parameter.
Definition: AppCommon.h:101
static SLstring calibFilePath
That's where calibrations are stored and loaded from.
Definition: AppCommon.h:109
static SLstring dataPath
Path to data directory (it is set platform dependent)
Definition: AppCommon.h:83
static void deleteApp()
Calls the destructor of the single scene instance.
Definition: AppCommon.cpp:298
static void timerStart()
Definition: GlobalTimer.cpp:15
static float timeMS()
Definition: GlobalTimer.cpp:25
void scene(SLScene *scene)
Definition: SLAssetLoader.h:65
void loadAssetsAsync(function< void()> onDone)
void addLoadTask(SLAssetLoadTask task)
Add generic task.
void addRawDataToLoad(SLIOBuffer &buffer, SLstring filename, SLIOStreamKind kind)
Toplevel holder of the assets meshes, materials, textures and shaders.
void clear()
for all assets, clear gpu data
void generateStaticFonts(SLstring fontPath)
Encapsulation of a mobile device location set by the device's GPS sensor.
Encapsulation of a mobile device rotation set by the device's IMU sensor.
static void init(string shaderPath, string configPath)
Init by providing path to standard shader files.
static void deletePrograms()
Delete all instantiated programs.
static void loadPrograms()
Instantiate and load all programs.
static void deleteInstance()
global destruction
Definition: SLGLState.cpp:27
static SLGLState * instance()
Public static instance getter for singleton pattern.
Definition: SLGLState.h:74
void initAll()
Definition: SLGLState.cpp:42
SLInputManager. manages system input and custom input devices.
static void deleteInstance()
Definition: SLMaterial.h:292
void name(const SLstring &Name)
Definition: SLObject.h:34
The SLScene class represents the top level instance holding the scene structure.
Definition: SLScene.h:47
virtual void registerAssetsToLoad(SLAssetLoader &al)
All assets the should be loaded in parallel must be registered in here.
Definition: SLScene.h:63
virtual void assemble(SLAssetManager *am, SLSceneView *sv)
After parallel loading of the assets the scene gets assembled in here.
Definition: SLScene.h:75
void initOculus(SLstring shaderDir)
Definition: SLScene.cpp:391
void loadTimeMS(SLfloat loadTimeMS)
Definition: SLScene.h:94
void init(SLAssetManager *am)
Definition: SLScene.cpp:72
SceneView class represents a dynamic real time 3D view onto the scene.
Definition: SLSceneView.h:69
virtual void postSceneLoad()
Definition: SLSceneView.h:97
void camera(SLCamera *camera)
Definition: SLSceneView.h:145
void scene(SLScene *scene)
Definition: SLSceneView.h:146
SLCamera * sceneViewCamera()
Definition: SLSceneView.h:169
Interface for ui integration in SLSceneView.
Definition: SLUiInterface.h:24
Config config
The configuration set in App::run.
Definition: AppAndroid.cpp:34
OnAfterSceneAssemblyCallback onAfterSceneAssembly
Definition: App.h:70
OnBeforeSceneAssemblyCallback onBeforeSceneAssembly
Definition: App.h:69
OnNewSceneCallback onNewScene
Definition: App.h:66
OnBeforeSceneLoadCallback onBeforeSceneLoad
Definition: App.h:68
OnBeforeSceneDeleteCallback onBeforeSceneDelete
Definition: App.h:67
Utility struct that holds a pointer and its length.
Definition: SLFileStorage.h:28
void deallocate()
Deallocates the data owned by the buffer.