Hi,
my application needs a lot of initialization stuff to be done in the setup() method (like loading graphics and even downloading something on the fly from a server). All of that takes 2-3 seconds, and in the meanwhile nothing happens from user’s perspective.
This is enough to make people nervous and even double click a second time on app icon, and should of course be avoided. After playing for a while with splash screens I couldn’t find anything satisfactory, they made the code heavily platform dependent and did not solve the problem after all.
So I tried a much simpler way that (for me at least) does the trick. Since I am not an expert at all in OF I am asking for comments and may be possible drawbacks. The idea is to delay setup() after a few frames have been drawn, so that the window can appear with a message to the user. Since the message is static it does not matter if the framerate is extremely low during the initialization.
here is a little snippet:
in ofApp.h:
void first_setup();
int framesDrawn;
ofTrueTypeFont messageFont; // this is only needed if you want to show a message while loading
and in ofApp.cpp:
const int SETUP_FRAMES = 2;
void ofApp::setup()
{
ofSetVerticalSync(true);
ofSetFrameRate(60);
messageFont.load("font/F25_Executive.otf", 32, true, true);
framesDrawn = 0;
}
void ofApp::first_setup()
{
// do all heavy initialization stuff here
}
void ofApp::update()
{
if(framesDrawn <= SETUP_FRAMES) return;
// regular update() code goes here
}
void ofApp::draw()
{
ofBackground(80);
if(framesDrawn < SETUP_FRAMES)
{
string line = "Application is loading. Please wait.";
// draw a message on screen, centered on X and Y
int lineH = messageFont.getLineHeight();
int y = (ofGetHeight()-lineH)/2 + messageFont.getAscenderHeight();
int lineW = messageFont.stringWidth(line);
int x = (ofGetWidth()-lineW)/2;
messageFont.drawString(line, x, y);
framesDrawn++;
return;
}
else if(framesDrawn == SETUP_FRAMES)
{
first_setup();
framesDrawn++;
}
// here goes all draw() code
}
Severity Code Description Project File Line Suppression State
Error C3861 'glfwShowWindow': identifier not found Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 74
Error (active) E0757 overloaded function "std::chrono::duration<_Rep, _Period>::duration [with _Rep=long long, _Period=std::nano]" is not a type name Example C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.16.27023\include\chrono 195
Error C3861 'glfwGetCurrentContext': identifier not found Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 34
Error C3861 'glfwHideWindow': identifier not found Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 36
Error C2065 'GLFW_DECORATED': undeclared identifier Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 37
Error C3861 'glfwWindowHint': identifier not found Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 37
Error C3861 'glfwCreateWindow': identifier not found Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 38
Error C3861 'glfwSetWindowPos': identifier not found Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 39
Error C2065 'GLFW_DECORATED': undeclared identifier Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 40
Error C3861 'glfwWindowHint': identifier not found Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 40
Error C3861 'glfwMakeContextCurrent': identifier not found Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 41
Error C3861 'glfwSwapBuffers': identifier not found Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 53
Error C3861 'glfwMakeContextCurrent': identifier not found Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 57
Error C3861 'glfwDestroyWindow': identifier not found Example f:\openframeworks\addons\ofxsplashscreen\src\ofxsplashscreen.cpp 71
well… I am not sure if it’s the expected behavior, but maybe the png is drawing during a single frame.
I was expecting that the window is drawn until ofApp is fully loaded and the switch from the png/splash to the running loaded ofApp.
I’ve been doing something like what you do in the original post. I combined it with a pattern I’m using to have different pages/display-states/UI-modes. So I have a class UIMode which has its own Draw() method, and I make derived classes of that, and then call the current UI Mode’s Draw() from ofApp::Draw(). Then one of the UI modes is typically a “load stuff while showing something” mode, which the program starts out in.
I.e. Yes, the pattern you first suggested makes good sense. You can even have the loading state have multiple levels of progress and show different things depending on the loading state, so users know something is continuing to happen during loading.