Implement a simple loading animation.

Loading currently doesn't happen, because loading tries to do some GL
actions which cannot happen in a background thread (in GLUT anyway).

TODO: move all GL options to the main thread, and leave the rest of the
loading to the background.
This commit is contained in:
2018-04-12 14:25:01 +02:00
parent 2bd84abe94
commit 30aa25a09e
3 changed files with 92 additions and 26 deletions

View File

@@ -24,6 +24,7 @@ find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
find_package(Boost REQUIRED COMPONENTS filesystem program_options)
find_package(OpenCV 3 REQUIRED COMPONENTS core imgproc imgcodecs)
find_package(Threads REQUIRED)
target_link_libraries(fmri PUBLIC
Caffe::Caffe
@@ -33,6 +34,7 @@ target_link_libraries(fmri PUBLIC
opencv_core
opencv_imgproc
opencv_imgcodecs
Threads::Threads
)
target_include_directories(fmri PUBLIC

View File

@@ -217,7 +217,17 @@ void RenderingState::loadSimulationData(const std::map<string, LayerInfo> &info,
layerData = std::move(data);
currentData = layerData.begin();
updateVisualisers();
queueUpdate();
}
void RenderingState::queueUpdate()
{
loadingFuture = std::async(std::launch::async, []() {
// Currently causes a segfault, due to threaded OpenGL.
// Possible solution: don't do GL things while loading.
//RenderingState::instance().updateVisualisers();
});
isLoading = true;
}
void RenderingState::updateVisualisers()
@@ -249,8 +259,18 @@ void RenderingState::render(float time) const
// Clear Color and Depth Buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
configureRenderingContext();
if (!isLoading) {
renderVisualisation(time);
} else {
renderLoadingScreen();
}
glutSwapBuffers();
}
void RenderingState::renderVisualisation(float time) const
{
configureRenderingContext();
glPushMatrix();
@@ -275,8 +295,24 @@ void RenderingState::render(float time) const
glPopMatrix();
renderOverlayText();
}
glutSwapBuffers();
void RenderingState::renderLoadingScreen() const
{
glLoadIdentity();
glTranslatef(0, 0, -4);
glRotatef(360 * getAnimationStep(std::chrono::seconds(4)), 0, 1, 0);
glColor3f(1, 1, 1);
glutWireTeapot(1);
auto pulse = std::cos(2 * M_PI * getAnimationStep(std::chrono::seconds(3)));
pulse *= pulse;
glColor3d(pulse, pulse, 0);
glLoadIdentity();
setOrthographicProjection();
renderText("Loading...", 5, 15);
restorePerspectiveProjection();
}
void RenderingState::drawLayer(float time, unsigned long i) const
@@ -341,7 +377,7 @@ void RenderingState::handleSpecialKey(int key)
currentData = layerData.end();
}
--currentData;
updateVisualisers();
queueUpdate();
break;
case GLUT_KEY_RIGHT:
@@ -349,7 +385,7 @@ void RenderingState::handleSpecialKey(int key)
if (currentData == layerData.end()) {
currentData = layerData.begin();
}
updateVisualisers();
queueUpdate();
break;
case GLUT_KEY_F1:
@@ -419,6 +455,23 @@ float RenderingState::layerAlpha() const
void RenderingState::idleFunc()
{
if (isLoading && loadingFuture.valid()) {
auto result = loadingFuture.wait_for(std::chrono::milliseconds(40));
switch (result) {
case std::future_status::deferred:
LOG(ERROR) << "loading status was deferred, invalid state!";
abort();
case std::future_status::timeout:
// Still loading
break;
case std::future_status::ready:
loadingFuture.get();
//isLoading = false;
break;
}
} else {
if (options.mouse_1_pressed) {
move('w', false);
}
@@ -428,5 +481,6 @@ void RenderingState::idleFunc()
checkGLErrors();
throttleIdleFunc();
}
glutPostRedisplay();
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include <string>
#include <future>
#include "LayerInfo.hpp"
#include "LayerData.hpp"
#include "LayerVisualisation.hpp"
@@ -78,6 +79,9 @@ namespace fmri
std::vector<std::vector<LayerData>>::iterator currentData;
std::vector<std::unique_ptr<LayerVisualisation>> layerVisualisations;
std::vector<std::unique_ptr<Animation>> interactionAnimations;
bool isLoading = false;
std::future<void> loadingFuture;
RenderingState() noexcept;
@@ -92,5 +96,11 @@ namespace fmri
void renderLayerName(const std::string& name) const;
void drawLayer(float time, unsigned long i) const;
void queueUpdate();
void renderLoadingScreen() const;
void renderVisualisation(float time) const;
};
}