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:
@@ -24,6 +24,7 @@ find_package(OpenGL REQUIRED)
|
|||||||
find_package(GLUT REQUIRED)
|
find_package(GLUT REQUIRED)
|
||||||
find_package(Boost REQUIRED COMPONENTS filesystem program_options)
|
find_package(Boost REQUIRED COMPONENTS filesystem program_options)
|
||||||
find_package(OpenCV 3 REQUIRED COMPONENTS core imgproc imgcodecs)
|
find_package(OpenCV 3 REQUIRED COMPONENTS core imgproc imgcodecs)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
target_link_libraries(fmri PUBLIC
|
target_link_libraries(fmri PUBLIC
|
||||||
Caffe::Caffe
|
Caffe::Caffe
|
||||||
@@ -33,6 +34,7 @@ target_link_libraries(fmri PUBLIC
|
|||||||
opencv_core
|
opencv_core
|
||||||
opencv_imgproc
|
opencv_imgproc
|
||||||
opencv_imgcodecs
|
opencv_imgcodecs
|
||||||
|
Threads::Threads
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(fmri PUBLIC
|
target_include_directories(fmri PUBLIC
|
||||||
|
|||||||
@@ -217,7 +217,17 @@ void RenderingState::loadSimulationData(const std::map<string, LayerInfo> &info,
|
|||||||
layerData = std::move(data);
|
layerData = std::move(data);
|
||||||
currentData = layerData.begin();
|
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()
|
void RenderingState::updateVisualisers()
|
||||||
@@ -249,34 +259,60 @@ void RenderingState::render(float time) const
|
|||||||
// Clear Color and Depth Buffers
|
// Clear Color and Depth Buffers
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
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();
|
glPushMatrix();
|
||||||
|
|
||||||
// Ensure we render back-to-front for transparency
|
// Ensure we render back-to-front for transparency
|
||||||
if (angle[0] <= 0) {
|
if (angle[0] <= 0) {
|
||||||
// Render from the first to the last layer.
|
// Render from the first to the last layer.
|
||||||
glTranslatef(-LAYER_X_OFFSET / 2 * currentData->size(), 0, 0);
|
glTranslatef(-LAYER_X_OFFSET / 2 * currentData->size(), 0, 0);
|
||||||
for (auto i : Range(currentData->size())) {
|
for (auto i : Range(currentData->size())) {
|
||||||
drawLayer(time, i);
|
drawLayer(time, i);
|
||||||
glTranslatef(LAYER_X_OFFSET, 0, 0);
|
glTranslatef(LAYER_X_OFFSET, 0, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Render from the last layer to the first layer.
|
// Render from the last layer to the first layer.
|
||||||
glTranslatef(LAYER_X_OFFSET / 2 * (currentData->size() - 2), 0, 0);
|
glTranslatef(LAYER_X_OFFSET / 2 * (currentData->size() - 2), 0, 0);
|
||||||
for (auto i = currentData->size(); i--;) {
|
for (auto i = currentData->size(); i--;) {
|
||||||
drawLayer(time, i);
|
drawLayer(time, i);
|
||||||
|
|
||||||
glTranslatef(-LAYER_X_OFFSET, 0, 0);
|
glTranslatef(-LAYER_X_OFFSET, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
renderOverlayText();
|
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
|
void RenderingState::drawLayer(float time, unsigned long i) const
|
||||||
@@ -341,7 +377,7 @@ void RenderingState::handleSpecialKey(int key)
|
|||||||
currentData = layerData.end();
|
currentData = layerData.end();
|
||||||
}
|
}
|
||||||
--currentData;
|
--currentData;
|
||||||
updateVisualisers();
|
queueUpdate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLUT_KEY_RIGHT:
|
case GLUT_KEY_RIGHT:
|
||||||
@@ -349,7 +385,7 @@ void RenderingState::handleSpecialKey(int key)
|
|||||||
if (currentData == layerData.end()) {
|
if (currentData == layerData.end()) {
|
||||||
currentData = layerData.begin();
|
currentData = layerData.begin();
|
||||||
}
|
}
|
||||||
updateVisualisers();
|
queueUpdate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLUT_KEY_F1:
|
case GLUT_KEY_F1:
|
||||||
@@ -419,14 +455,32 @@ float RenderingState::layerAlpha() const
|
|||||||
|
|
||||||
void RenderingState::idleFunc()
|
void RenderingState::idleFunc()
|
||||||
{
|
{
|
||||||
if (options.mouse_1_pressed) {
|
if (isLoading && loadingFuture.valid()) {
|
||||||
move('w', false);
|
auto result = loadingFuture.wait_for(std::chrono::milliseconds(40));
|
||||||
}
|
switch (result) {
|
||||||
if (options.mouse_2_pressed) {
|
case std::future_status::deferred:
|
||||||
move('s', false);
|
LOG(ERROR) << "loading status was deferred, invalid state!";
|
||||||
}
|
abort();
|
||||||
|
|
||||||
checkGLErrors();
|
case std::future_status::timeout:
|
||||||
throttleIdleFunc();
|
// Still loading
|
||||||
|
break;
|
||||||
|
|
||||||
|
case std::future_status::ready:
|
||||||
|
loadingFuture.get();
|
||||||
|
//isLoading = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (options.mouse_1_pressed) {
|
||||||
|
move('w', false);
|
||||||
|
}
|
||||||
|
if (options.mouse_2_pressed) {
|
||||||
|
move('s', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkGLErrors();
|
||||||
|
throttleIdleFunc();
|
||||||
|
}
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <future>
|
||||||
#include "LayerInfo.hpp"
|
#include "LayerInfo.hpp"
|
||||||
#include "LayerData.hpp"
|
#include "LayerData.hpp"
|
||||||
#include "LayerVisualisation.hpp"
|
#include "LayerVisualisation.hpp"
|
||||||
@@ -78,6 +79,9 @@ namespace fmri
|
|||||||
std::vector<std::vector<LayerData>>::iterator currentData;
|
std::vector<std::vector<LayerData>>::iterator currentData;
|
||||||
std::vector<std::unique_ptr<LayerVisualisation>> layerVisualisations;
|
std::vector<std::unique_ptr<LayerVisualisation>> layerVisualisations;
|
||||||
std::vector<std::unique_ptr<Animation>> interactionAnimations;
|
std::vector<std::unique_ptr<Animation>> interactionAnimations;
|
||||||
|
bool isLoading = false;
|
||||||
|
std::future<void> loadingFuture;
|
||||||
|
|
||||||
|
|
||||||
RenderingState() noexcept;
|
RenderingState() noexcept;
|
||||||
|
|
||||||
@@ -92,5 +96,11 @@ namespace fmri
|
|||||||
void renderLayerName(const std::string& name) const;
|
void renderLayerName(const std::string& name) const;
|
||||||
|
|
||||||
void drawLayer(float time, unsigned long i) const;
|
void drawLayer(float time, unsigned long i) const;
|
||||||
|
|
||||||
|
void queueUpdate();
|
||||||
|
|
||||||
|
void renderLoadingScreen() const;
|
||||||
|
|
||||||
|
void renderVisualisation(float time) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user