Merge pull request #415 from OpenSpace/feature/loadingscreen-refactor

Feature/loadingscreen refactor
This commit is contained in:
Alexander Bock
2017-11-12 13:24:48 -06:00
committed by GitHub
104 changed files with 1753 additions and 407 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

@@ -156,6 +156,20 @@ public:
/// The part of the key storing whether each OpenGL call should be logged
static const std::string KeyLogEachOpenGLCall;
/// This key determines whether the scene graph nodes should initialized multithreaded
static const std::string KeyUseMultithreadedInitialization;
/// The key under which all of the loading settings are grouped
static const std::string KeyLoadingScreen;
/// The part of the key storing whether the loading screen should display the message
/// about current status
static const std::string PartShowMessage;
/// The part of the key storing whether the loading screen should display node names
static const std::string PartShowNodeNames;
/// The part of the key storing whether the loading screen should contain a progress
/// bar
static const std::string PartShowProgressbar;
/**
* Iteratively walks the directory structure starting with \p filename to find the
@@ -45,6 +45,7 @@ namespace openspace {
class ConfigurationManager;
class DownloadManager;
class GUI;
class LoadingScreen;
class LuaConsole;
class ModuleEngine;
class NetworkEngine;
@@ -110,6 +111,7 @@ public:
LuaConsole& console();
DownloadManager& downloadManager();
ModuleEngine& moduleEngine();
LoadingScreen& loadingScreen();
NetworkEngine& networkEngine();
ParallelConnection& parallelConnection();
RenderEngine& renderEngine();
@@ -202,6 +204,8 @@ private:
// Others
std::unique_ptr<properties::PropertyOwner> _globalPropertyNamespace;
std::unique_ptr<LoadingScreen> _loadingScreen;
struct {
properties::StringProperty versionString;
properties::StringProperty sourceControlInformation;
@@ -79,6 +79,8 @@ public:
void takeScreenshot(bool applyWarping = false) const override;
void swapBuffer() const override;
private:
properties::FloatProperty _eyeSeparation;
properties::BoolProperty _showStatsGraph;
@@ -271,6 +271,8 @@ public:
*/
virtual void takeScreenshot(bool applyWarping = false) const;
virtual void swapBuffer() const;
struct WindowWrapperException : public ghoul::RuntimeError {
explicit WindowWrapperException(const std::string& msg);
};
+138
View File
@@ -0,0 +1,138 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___LOADINGSCREEN___H__
#define __OPENSPACE_CORE___LOADINGSCREEN___H__
#include <ghoul/glm.h>
#include <ghoul/misc/boolean.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <memory>
#include <mutex>
#include <random>
// #define LOADINGSCREEN_DEBUGGING
namespace ghoul::fontrendering {
class Font;
} // namespace ghoul::fontrendering
namespace ghoul::opengl {
class ProgramObject;
class Texture;
} // namespace ghoul::opengl
namespace openspace {
class LoadingScreen {
public:
using ShowMessage = ghoul::Boolean;
using ShowNodeNames = ghoul::Boolean;
using ShowProgressbar = ghoul::Boolean;
LoadingScreen(ShowMessage showMessage, ShowNodeNames showNodeNames,
ShowProgressbar showProgressbar);
~LoadingScreen();
void render();
void postMessage(std::string message);
void finalize();
void setItemNumber(int nItems);
void tickItem();
enum class Phase {
Construction,
Initialization
};
void setPhase(Phase phase);
enum class ItemStatus {
Started,
Initializing,
Finished,
Failed
};
void updateItem(const std::string& itemName, ItemStatus newStatus);
private:
bool _showMessage;
bool _showNodeNames;
bool _showProgressbar;
Phase _phase;
int _iProgress;
int _nItems;
std::unique_ptr<ghoul::opengl::ProgramObject> _program;
std::unique_ptr<ghoul::opengl::Texture> _logoTexture;
std::shared_ptr<ghoul::fontrendering::Font> _loadingFont;
std::shared_ptr<ghoul::fontrendering::Font> _messageFont;
std::shared_ptr<ghoul::fontrendering::Font> _itemFont;
struct {
GLuint vao;
GLuint vbo;
} _logo;
struct {
GLuint vaoFill;
GLuint vboFill;
GLuint vaoBox;
GLuint vboBox;
} _progressbar;
std::string _message;
std::mutex _messageMutex;
struct Item {
std::string name;
ItemStatus status;
bool hasLocation;
#ifdef LOADINGSCREEN_DEBUGGING
bool exhaustedSearch;
#endif // LOADINGSCREEN_DEBUGGING
glm::vec2 ll;
glm::vec2 ur;
std::chrono::system_clock::time_point finishedTime;
};
std::vector<Item> _items;
std::mutex _itemsMutex;
std::random_device _randomDevice;
std::default_random_engine _randomEngine;
};
} // namespace openspace
#endif // __OPENSPACE_CORE___LOADINGSCREEN___H__
+2
View File
@@ -66,7 +66,9 @@ public:
virtual ~Renderable();
virtual void initialize();
virtual void initializeGL();
virtual void deinitialize();
virtual void deinitializeGL();
virtual bool isReady() const = 0;
bool isEnabled() const;
@@ -60,7 +60,10 @@ public:
virtual void render();
virtual bool initialize();
virtual bool initializeGL();
virtual bool deinitialize();
virtual bool deinitializeGL();
virtual void update() = 0;
virtual bool isReady() const;
bool isEnabled() const;
+6
View File
@@ -73,6 +73,12 @@ public:
* Initalizes the SceneGraph
*/
void initialize();
/**
* Initializes the OpenGL part of the SceneGraph
*/
void initializeGL();
/**
* Clear the scene graph,
+2
View File
@@ -77,7 +77,9 @@ public:
const ghoul::Dictionary& dictionary);
void initialize();
void initializeGL();
void deinitialize();
void deinitializeGL();
void traversePreOrder(std::function<void(SceneGraphNode*)> fn);
void traversePostOrder(std::function<void(SceneGraphNode*)> fn);
+2 -2
View File
@@ -156,7 +156,7 @@ bool RenderableModel::isReady() const {
return _programObject && _texture;
}
void RenderableModel::initialize() {
void RenderableModel::initializeGL() {
_programObject = OsEng.renderEngine().buildRenderProgram(
"ModelProgram",
"${MODULE_BASE}/shaders/model_vs.glsl",
@@ -168,7 +168,7 @@ void RenderableModel::initialize() {
_geometry->initialize(this);
}
void RenderableModel::deinitialize() {
void RenderableModel::deinitializeGL() {
if (_geometry) {
_geometry->deinitialize();
_geometry = nullptr;
+2 -2
View File
@@ -51,8 +51,8 @@ class RenderableModel : public Renderable {
public:
RenderableModel(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
+2 -2
View File
@@ -178,7 +178,7 @@ bool RenderablePlane::isReady() const {
return _shader && _texture;
}
void RenderablePlane::initialize() {
void RenderablePlane::initializeGL() {
glGenVertexArrays(1, &_quad); // generate array
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
createPlane();
@@ -191,7 +191,7 @@ void RenderablePlane::initialize() {
loadTexture();
}
void RenderablePlane::deinitialize() {
void RenderablePlane::deinitializeGL() {
glDeleteVertexArrays(1, &_quad);
_quad = 0;
+2 -2
View File
@@ -54,8 +54,8 @@ class RenderablePlane : public Renderable {
public:
RenderablePlane(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
+2 -2
View File
@@ -220,7 +220,7 @@ bool RenderableSphere::isReady() const {
return _shader && _texture;
}
void RenderableSphere::initialize() {
void RenderableSphere::initializeGL() {
_sphere = std::make_unique<PowerScaledSphere>(
PowerScaledScalar::CreatePSS(_size), _segments
);
@@ -234,7 +234,7 @@ void RenderableSphere::initialize() {
loadTexture();
}
void RenderableSphere::deinitialize() {
void RenderableSphere::deinitializeGL() {
_texture = nullptr;
if (_shader) {
+2 -2
View File
@@ -49,8 +49,8 @@ class RenderableSphere : public Renderable {
public:
RenderableSphere(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -177,18 +177,7 @@ bool RenderableSphericalGrid::isReady() const {
return ready;
}
void RenderableSphericalGrid::deinitialize() {
glDeleteVertexArrays(1,&_vaoID);
_vaoID = 0;
glDeleteBuffers(1,&_vBufferID);
_vBufferID = 0;
glDeleteBuffers(1,&_iBufferID);
_iBufferID = 0;
}
void RenderableSphericalGrid::initialize() {
void RenderableSphericalGrid::initializeGL() {
_gridProgram = OsEng.renderEngine().buildRenderProgram(
"GridProgram",
"${MODULE_BASE}/shaders/grid_vs.glsl",
@@ -206,6 +195,17 @@ void RenderableSphericalGrid::initialize() {
glBindVertexArray(0);
}
void RenderableSphericalGrid::deinitializeGL() {
glDeleteVertexArrays(1, &_vaoID);
_vaoID = 0;
glDeleteBuffers(1, &_vBufferID);
_vBufferID = 0;
glDeleteBuffers(1, &_iBufferID);
_iBufferID = 0;
}
void RenderableSphericalGrid::render(const RenderData& data, RendererTasks&){
_gridProgram->activate();
@@ -48,8 +48,8 @@ public:
RenderableSphericalGrid(const ghoul::Dictionary& dictionary);
~RenderableSphericalGrid();
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
+2 -2
View File
@@ -217,7 +217,7 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary)
addProperty(_renderingModes);
}
void RenderableTrail::initialize() {
void RenderableTrail::initializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
_programObject = renderEngine.buildRenderProgram(
"EphemerisProgram",
@@ -228,7 +228,7 @@ void RenderableTrail::initialize() {
setRenderBin(Renderable::RenderBin::Overlay);
}
void RenderableTrail::deinitialize() {
void RenderableTrail::deinitializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
if (_programObject) {
renderEngine.removeRenderProgram(_programObject);
+2 -2
View File
@@ -73,8 +73,8 @@ class RenderableTrail : public Renderable {
public:
~RenderableTrail() = default;
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -169,20 +169,20 @@ RenderableTrailOrbit::RenderableTrailOrbit(const ghoul::Dictionary& dictionary)
_primaryRenderInformation.sorting = RenderInformation::VertexSorting::NewestFirst;
}
void RenderableTrailOrbit::initialize() {
RenderableTrail::initialize();
void RenderableTrailOrbit::initializeGL() {
RenderableTrail::initializeGL();
glGenVertexArrays(1, &_primaryRenderInformation._vaoID);
glGenBuffers(1, &_primaryRenderInformation._vBufferID);
glGenBuffers(1, &_primaryRenderInformation._iBufferID);
}
void RenderableTrailOrbit::deinitialize() {
void RenderableTrailOrbit::deinitializeGL() {
glDeleteVertexArrays(1, &_primaryRenderInformation._vaoID);
glDeleteBuffers(1, &_primaryRenderInformation._vBufferID);
glDeleteBuffers(1, &_primaryRenderInformation._iBufferID);
RenderableTrail::deinitialize();
RenderableTrail::deinitializeGL();
}
void RenderableTrailOrbit::update(const UpdateData& data) {
@@ -47,12 +47,12 @@ namespace documentation { struct Documentation; }
class RenderableTrailOrbit : public RenderableTrail {
public:
explicit RenderableTrailOrbit(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
void update(const UpdateData& data) override;
static documentation::Documentation Documentation();
private:
@@ -187,8 +187,8 @@ RenderableTrailTrajectory::RenderableTrailTrajectory(const ghoul::Dictionary& di
_primaryRenderInformation.sorting = RenderInformation::VertexSorting::OldestFirst;
}
void RenderableTrailTrajectory::initialize() {
RenderableTrail::initialize();
void RenderableTrailTrajectory::initializeGL() {
RenderableTrail::initializeGL();
// We don't need an index buffer, so we keep it at the default value of 0
glGenVertexArrays(1, &_primaryRenderInformation._vaoID);
@@ -201,14 +201,14 @@ void RenderableTrailTrajectory::initialize() {
_floatingRenderInformation.sorting = RenderInformation::VertexSorting::OldestFirst;
}
void RenderableTrailTrajectory::deinitialize() {
void RenderableTrailTrajectory::deinitializeGL() {
glDeleteVertexArrays(1, &_primaryRenderInformation._vaoID);
glDeleteBuffers(1, &_primaryRenderInformation._vBufferID);
glDeleteVertexArrays(1, &_floatingRenderInformation._vaoID);
glDeleteBuffers(1, &_floatingRenderInformation._vBufferID);
RenderableTrail::deinitialize();
RenderableTrail::deinitializeGL();
}
void RenderableTrailTrajectory::update(const UpdateData& data) {
@@ -53,8 +53,8 @@ class RenderableTrailTrajectory : public RenderableTrail {
public:
explicit RenderableTrailTrajectory(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
void update(const UpdateData& data) override;
@@ -75,15 +75,15 @@ ScreenSpaceFramebuffer::ScreenSpaceFramebuffer(const ghoul::Dictionary& dictiona
ScreenSpaceFramebuffer::~ScreenSpaceFramebuffer() {}
bool ScreenSpaceFramebuffer::initialize() {
ScreenSpaceRenderable::initialize();
bool ScreenSpaceFramebuffer::initializeGL() {
ScreenSpaceRenderable::initializeGL();
createFragmentbuffer();
return isReady();
}
bool ScreenSpaceFramebuffer::deinitialize() {
ScreenSpaceRenderable::deinitialize();
bool ScreenSpaceFramebuffer::deinitializeGL() {
ScreenSpaceRenderable::deinitializeGL();
_framebuffer->detachAll();
removeAllRenderFunctions();
@@ -48,8 +48,8 @@ public:
ScreenSpaceFramebuffer(const ghoul::Dictionary& dictionary = ghoul::Dictionary());
~ScreenSpaceFramebuffer();
bool initialize() override;
bool deinitialize() override;
bool initializeGL() override;
bool deinitializeGL() override;
void render() override;
void update() override;
bool isReady() const override;
@@ -190,7 +190,7 @@ bool RenderableDebugPlane::isReady() const {
return ready;
}
void RenderableDebugPlane::initialize() {
void RenderableDebugPlane::initializeGL() {
glGenVertexArrays(1, &_quad); // generate array
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
createPlane();
@@ -204,7 +204,7 @@ void RenderableDebugPlane::initialize() {
}
}
void RenderableDebugPlane::deinitialize() {
void RenderableDebugPlane::deinitializeGL() {
glDeleteVertexArrays(1, &_quad);
_quad = 0;
@@ -49,8 +49,8 @@ public:
RenderableDebugPlane(const ghoul::Dictionary& dictionary);
~RenderableDebugPlane();
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -40,7 +40,7 @@
#include <ghoul/font/fontrenderer.h>
#include <glm/gtx/string_cast.hpp>
#include <ghoul/glm.h>
#include <glm/glm.hpp>
#include <array>
#include <fstream>
@@ -69,7 +69,7 @@ namespace {
"Point Sprite Texture",
"The path to the texture that should be used as the point sprite."
};
static const openspace::properties::Property::PropertyInfo TransparencyInfo = {
"Transparency",
"Transparency",
@@ -324,7 +324,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
_hasSpeckFile = _hasSpeckFile == true? false : true; });
addProperty(_drawElements);
}
// DEBUG:
_renderOption.addOption(0, "Camera View Direction");
_renderOption.addOption(1, "Camera Position Normal");
@@ -386,7 +386,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
ghoul::Dictionary colorOptionDataDic = dictionary.value<ghoul::Dictionary>(
ColorOptionInfo.identifier
);
for (int i = 0; i < static_cast<int>(colorOptionDataDic.size()); ++i) {
for (int i = 0; i < colorOptionDataDic.size(); ++i) {
std::string colorMapInUseName(
colorOptionDataDic.value<std::string>(std::to_string(i + 1)));
_colorOption.addOption(i, colorMapInUseName);
@@ -405,17 +405,17 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
ghoul::Dictionary rangeDataDic = dictionary.value<ghoul::Dictionary>(
ColorRangeInfo.identifier
);
for (int i = 0; i < static_cast<int>(rangeDataDic.size()); ++i) {
for (int i = 0; i < rangeDataDic.size(); ++i) {
_colorRangeData.push_back(
rangeDataDic.value<glm::vec2>(std::to_string(i+1)));
}
}
} else if (dictionary.hasKey(keyColor)) {
_pointColor = dictionary.value<glm::vec3>(keyColor);
addProperty(_pointColor);
}
}
if (dictionary.hasKey(TransparencyInfo.identifier)) {
_alphaValue = static_cast<float>(
@@ -446,7 +446,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
_labelFile = absPath(dictionary.value<std::string>(
LabelFileInfo.identifier
));
));
_hasLabel = true;
if (dictionary.hasKey(TextColorInfo.identifier)) {
@@ -465,7 +465,7 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di
if (dictionary.hasKey(LabelMinSizeInfo.identifier)) {
_textMinSize = static_cast<int>(dictionary.value<float>(LabelMinSizeInfo.identifier));
}
}
addProperty(_textMinSize);
}
}
@@ -475,13 +475,6 @@ bool RenderableBillboardsCloud::isReady() const {
}
void RenderableBillboardsCloud::initialize() {
RenderEngine& renderEngine = OsEng.renderEngine();
_program = renderEngine.buildRenderProgram("RenderableBillboardsCloud",
"${MODULE_DIGITALUNIVERSE}/shaders/billboard2_vs.glsl",
"${MODULE_DIGITALUNIVERSE}/shaders/billboard2_fs.glsl",
"${MODULE_DIGITALUNIVERSE}/shaders/billboard2_gs.glsl");
bool success = loadData();
if (!success) {
throw ghoul::RuntimeError("Error loading data");
@@ -490,8 +483,17 @@ void RenderableBillboardsCloud::initialize() {
if (!_colorOptionString.empty()) {
// Following DU behavior here. The last colormap variable
// entry is the one selected by default.
_colorOption = static_cast<int>(_colorRangeData.size() - 1);
_colorOption.setValue(_colorRangeData.size() - 1);
}
}
void RenderableBillboardsCloud::initializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
_program = renderEngine.buildRenderProgram("RenderableBillboardsCloud",
"${MODULE_DIGITALUNIVERSE}/shaders/billboard2_vs.glsl",
"${MODULE_DIGITALUNIVERSE}/shaders/billboard2_fs.glsl",
"${MODULE_DIGITALUNIVERSE}/shaders/billboard2_gs.glsl");
if (_hasPolygon) {
createPolygonTexture();
@@ -504,14 +506,12 @@ void RenderableBillboardsCloud::initialize() {
if (_font == nullptr) {
size_t _fontSize = 30;
_font = OsEng.fontManager().font("Mono", static_cast<float>(_fontSize),
ghoul::fontrendering::FontManager::Outline::Yes,
ghoul::fontrendering::FontManager::LoadGlyphs::No
);
ghoul::fontrendering::FontManager::Outline::Yes, ghoul::fontrendering::FontManager::LoadGlyphs::No);
}
}
}
void RenderableBillboardsCloud::deinitialize() {
void RenderableBillboardsCloud::deinitializeGL() {
glDeleteBuffers(1, &_vbo);
_vbo = 0;
glDeleteVertexArrays(1, &_vao);
@@ -572,7 +572,7 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data, const g
_program->setUniform("renderOption", _renderOption.value());
glm::dvec4 centerScreenWorld = glm::inverse(data.camera.combinedViewMatrix()) * glm::dvec4(0.0, 0.0, 0.0, 1.0);
_program->setUniform("centerScreenInWorldPosition", centerScreenWorld);
_program->setUniform("minBillboardSize", 1.f); // in pixels
_program->setUniform("color", _pointColor);
_program->setUniform("sides", 4);
@@ -631,7 +631,7 @@ void RenderableBillboardsCloud::renderLabels(const RenderData& data, const glm::
RenderEngine& renderEngine = OsEng.renderEngine();
_fontRenderer->setFramebufferSize(renderEngine.renderingResolution());
float scale = 0.0;
switch (_unit) {
case Meter:
@@ -685,7 +685,7 @@ void RenderableBillboardsCloud::render(const RenderData& data, RendererTasks&) {
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale));
glm::dmat4 modelViewMatrix = data.camera.combinedViewMatrix() * modelMatrix;
// glm::mat4 viewMatrix = data.camera.viewMatrix();
glm::mat4 viewMatrix = data.camera.viewMatrix();
glm::mat4 projectionMatrix = data.camera.projectionMatrix();
glm::dmat4 modelViewProjectionMatrix = glm::dmat4(projectionMatrix) * modelViewMatrix;
@@ -698,14 +698,14 @@ void RenderableBillboardsCloud::render(const RenderData& data, RendererTasks&) {
glm::vec3 orthoRight = glm::normalize(glm::vec3(worldToModelTransform * glm::vec4(right, 0.0)));
glm::vec3 orthoUp = glm::normalize(glm::vec3(worldToModelTransform * glm::vec4(up, 0.0)));
if (_hasSpeckFile) {
renderBillboards(data, modelViewMatrix, projectionMatrix, orthoRight, orthoUp);
}
if (_drawLabels && _hasLabel) {
renderLabels(data, modelViewProjectionMatrix, orthoRight, orthoUp);
}
}
}
void RenderableBillboardsCloud::update(const UpdateData&) {
@@ -734,13 +734,13 @@ void RenderableBillboardsCloud::update(const UpdateData&) {
GL_STATIC_DRAW
);
GLint positionAttrib = _program->attributeLocation("in_position");
if (_hasColorMapFile) {
/*const size_t nAstronomicalObjects = _fullData.size() / _nValuesPerAstronomicalObject;
const size_t nValues = _slicedData.size() / nAstronomicalObjects;
GLsizei stride = static_cast<GLsizei>(sizeof(float) * nValues);*/
glEnableVertexAttribArray(positionAttrib);
glVertexAttribPointer(
positionAttrib,
@@ -762,7 +762,7 @@ void RenderableBillboardsCloud::update(const UpdateData&) {
reinterpret_cast<void*>(sizeof(float)*4)
);
}
else {
else {
glEnableVertexAttribArray(positionAttrib);
glVertexAttribPointer(
positionAttrib,
@@ -796,10 +796,11 @@ void RenderableBillboardsCloud::update(const UpdateData&) {
[&](const ghoul::filesystem::File&) { _spriteTextureIsDirty = true; }
);
}
_spriteTextureIsDirty = false;
_spriteTextureIsDirty = false;
}
if (_hasLabel && _labelDataIsDirty) {
_labelDataIsDirty = false;
}
}
@@ -879,7 +880,7 @@ bool RenderableBillboardsCloud::loadData() {
// }
}
return success;
}
@@ -940,7 +941,7 @@ bool RenderableBillboardsCloud::readSpeckFile() {
_variableDataPositionMap.insert({ dummy, _nValuesPerAstronomicalObject });
_nValuesPerAstronomicalObject += 1; // We want the number, but the index is 0 based
}
}
}
_nValuesPerAstronomicalObject += 3; // X Y Z are not counted in the Speck file indices
@@ -963,7 +964,7 @@ bool RenderableBillboardsCloud::readSpeckFile() {
std::stringstream str(line);
for (int i = 0; i < _nValuesPerAstronomicalObject; ++i) {
str >> values[i];
str >> values[i];
}
_fullData.insert(_fullData.end(), values.begin(), values.end());
@@ -979,15 +980,15 @@ bool RenderableBillboardsCloud::readColorMapFile() {
LERROR("Failed to open Color Map file '" << _file << "'");
return false;
}
int numberOfColors = 0;
std::size_t numberOfColors = 0;
// The beginning of the speck file has a header that either contains comments
// (signaled by a preceding '#') or information about the structure of the file
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
std::string line = "";
while (true) {
// std::streampos position = file.tellg();
std::streampos position = file.tellg();
std::getline(file, line);
if (line[0] == '#' || line.empty()) {
@@ -998,18 +999,18 @@ bool RenderableBillboardsCloud::readColorMapFile() {
std::locale loc;
if (std::isdigit(line[0], loc)) {
std::string::size_type sz;
numberOfColors = static_cast<int>(std::stoi(line, &sz));
numberOfColors = std::stoi(line, &sz);
break;
}
else if (file.eof()) {
return false;
}
}
}
for (int i = 0; i < numberOfColors; ++i) {
for (auto i = 0; i < numberOfColors; ++i) {
std::getline(file, line);
std::stringstream str(line);
glm::vec4 color;
for (auto j = 0; j < 4; ++j) {
str >> color[j];
@@ -1017,7 +1018,7 @@ bool RenderableBillboardsCloud::readColorMapFile() {
_colorMapData.push_back(color);
}
return true;
}
@@ -1028,7 +1029,7 @@ bool RenderableBillboardsCloud::readLabelFile() {
LERROR("Failed to open Label file '" << _file << "'");
return false;
}
// The beginning of the speck file has a header that either contains comments
// (signaled by a preceding '#') or information about the structure of the file
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
@@ -1090,7 +1091,7 @@ bool RenderableBillboardsCloud::readLabelFile() {
std::string dummy;
str >> dummy; // text keyword
std::string label;
str >> label;
dummy.clear();
@@ -1101,7 +1102,7 @@ bool RenderableBillboardsCloud::readLabelFile() {
}
_labelData.push_back(std::make_pair(position, label));
} while (!file.eof());
return true;
@@ -1134,7 +1135,7 @@ bool RenderableBillboardsCloud::loadCachedFile(const std::string& file) {
for (int i = 0; i < nItems; ++i) {
int32_t keySize = 0;
fileStream.read(reinterpret_cast<char*>(&keySize), sizeof(int32_t));
std::string key;
std::string key;
for (int c = 0; c < keySize; ++c) {
char t[2];
t[1] = '\0';
@@ -1172,7 +1173,7 @@ bool RenderableBillboardsCloud::saveCachedFile(const std::string& file) const {
int32_t nValuesPerAstronomicalObject = static_cast<int32_t>(_nValuesPerAstronomicalObject);
fileStream.write(reinterpret_cast<const char*>(&nValuesPerAstronomicalObject), sizeof(int32_t));
size_t nBytes = nValues * sizeof(_fullData[0]);
fileStream.write(reinterpret_cast<const char*>(&_fullData[0]), nBytes);
@@ -1183,7 +1184,7 @@ bool RenderableBillboardsCloud::saveCachedFile(const std::string& file) const {
for (auto pair : _variableDataPositionMap) {
int32_t keySize = static_cast<int32_t>(pair.first.size());
fileStream.write(reinterpret_cast<const char*>(&keySize), sizeof(int32_t));
for (int c = 0; c < static_cast<int>(pair.first.size()); ++c) {
for (int c = 0; c < pair.first.size(); ++c) {
int32_t keyChar = static_cast<int32_t>(pair.first[c]);
fileStream.write(reinterpret_cast<const char*>(&keyChar), sizeof(int32_t));
}
@@ -1200,7 +1201,7 @@ bool RenderableBillboardsCloud::saveCachedFile(const std::string& file) const {
return false;
}
}
void RenderableBillboardsCloud::createDataSlice() {
_slicedData.clear();
if (_hasColorMapFile) {
@@ -1218,38 +1219,34 @@ void RenderableBillboardsCloud::createDataSlice() {
glm::vec2 currentColorRange = _colorRangeData[_colorOption.value()];
float colorMapBinSize = (currentColorRange.y - currentColorRange.x) / static_cast<float>(_colorMapData.size());
float bin = colorMapBinSize;
for (int i = 0; i < static_cast<int>(_colorMapData.size()); ++i) {
for (int i = 0; i < _colorMapData.size(); ++i) {
colorBins.push_back(bin);
bin += colorMapBinSize;
}
}
}
for (size_t i = 0; i < _fullData.size(); i += _nValuesPerAstronomicalObject) {
glm::dvec4 transformedPos = glm::dvec4(_fullData[i + 0], _fullData[i + 1], _fullData[i + 2], 1.0);
glm::vec4 position(glm::vec3(transformedPos), static_cast<float>(_unit));
if (_hasColorMapFile) {
for (int j = 0; j < 4; ++j) {
for (auto j = 0; j < 4; ++j) {
_slicedData.push_back(position[j]);
}
// Finds from which bin to get the color.
// Note: the first color in the colormap file
// is the outliers color.
glm::vec4 itemColor;
glm::vec4 itemColor;
float variableColor = _fullData[i + 3 + colorMapInUse];
int c = static_cast<int>(colorBins.size() - 1);
// Float vs int comparison?
int c = colorBins.size()-1;
while (variableColor < colorBins[c]) {
--c;
if (c == 0)
break;
}
int colorIndex = 0;
if (c != static_cast<int>(colorBins.size() - 1)) {
colorIndex = c + 1;
}
int colorIndex = c == colorBins.size() - 1 ? 0 : c + 1;
for (auto j = 0; j < 4; ++j) {
_slicedData.push_back(_colorMapData[colorIndex][j]);
}
@@ -1258,7 +1255,7 @@ void RenderableBillboardsCloud::createDataSlice() {
for (auto j = 0; j < 4; ++j) {
_slicedData.push_back(position[j]);
}
}
}
}
}
@@ -1280,7 +1277,7 @@ void RenderableBillboardsCloud::createPolygonTexture() {
this),
std::bind(&openspace::RenderableBillboardsCloud::renderPolygonGeometry,
this, std::placeholders::_1),
_pTexture, 256, 256);
_pTexture, 256, 256);
}
void RenderableBillboardsCloud::renderToTexture(
@@ -1288,7 +1285,7 @@ void RenderableBillboardsCloud::renderToTexture(
std::function<void(GLuint)> renderFunction,
GLuint textureToRenderTo, GLuint textureWidth, GLuint textureHeight) {
LDEBUG("Rendering to Texture");
// Saves initial Application's OpenGL State
GLint defaultFBO;
GLint viewport[4];
@@ -1302,12 +1299,12 @@ void RenderableBillboardsCloud::renderToTexture(
glDrawBuffers(1, drawBuffers);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureToRenderTo, 0);
glViewport(0, 0, textureWidth, textureHeight);
geometryLoadingFunction();
renderFunction(_polygonVao);
// Restores Applications' OpenGL State
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
@@ -1319,7 +1316,7 @@ void RenderableBillboardsCloud::renderToTexture(
if (_polygonVao) {
glDeleteVertexArrays(1, &_polygonVao);
}
glDeleteFramebuffers(1, &textureFBO);
glDeleteFramebuffers(1, &textureFBO);
}
void RenderableBillboardsCloud::loadPolygonGeometryForRendering() {
@@ -59,7 +59,8 @@ public:
~RenderableBillboardsCloud() = default;
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -371,7 +371,7 @@ bool RenderableDUMeshes::isReady() const {
return (_program != nullptr) && (!_renderingMeshesMap.empty() || (!_labelData.empty()));
}
void RenderableDUMeshes::initialize() {
void RenderableDUMeshes::initializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
_program = renderEngine.buildRenderProgram("RenderableDUMeshes",
"${MODULE_DIGITALUNIVERSE}/shaders/dumesh_vs.glsl",
@@ -396,7 +396,7 @@ void RenderableDUMeshes::initialize() {
}
}
void RenderableDUMeshes::deinitialize() {
void RenderableDUMeshes::deinitializeGL() {
for (const std::pair<int, RenderingMesh>& pair : _renderingMeshesMap) {
for (int i = 0; i < pair.second.numU; ++i) {
glDeleteVertexArrays(1, &pair.second.vaoArray[i]);
@@ -56,8 +56,8 @@ public:
explicit RenderableDUMeshes(const ghoul::Dictionary& dictionary);
~RenderableDUMeshes() = default;
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -40,7 +40,7 @@
#include <ghoul/font/fontrenderer.h>
#include <glm/gtx/string_cast.hpp>
#include <ghoul/glm.h>
#include <glm/glm.hpp>
#include <array>
#include <fstream>
@@ -291,7 +291,7 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary
_hasSpeckFile = _hasSpeckFile == true? false : true; });
addProperty(_drawElements);
}
// DEBUG:
_renderOption.addOption(0, "Camera View Direction");
_renderOption.addOption(1, "Camera Position Normal");
@@ -347,11 +347,11 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary
_scaleFactor.onChange([&]() {
_dataIsDirty = true;
});
if (dictionary.hasKey(LabelFileInfo.identifier)) {
_labelFile = absPath(dictionary.value<std::string>(
LabelFileInfo.identifier
));
));
_hasLabel = true;
if (dictionary.hasKey(TextColorInfo.identifier)) {
@@ -370,7 +370,7 @@ RenderablePlanesCloud::RenderablePlanesCloud(const ghoul::Dictionary& dictionary
if (dictionary.hasKey(LabelMinSizeInfo.identifier)) {
_textMinSize = static_cast<int>(dictionary.value<float>(LabelMinSizeInfo.identifier));
}
}
}
if (dictionary.hasKey(TransformationMatrixInfo.identifier)) {
@@ -420,17 +420,19 @@ bool RenderablePlanesCloud::isReady() const {
}
void RenderablePlanesCloud::initialize() {
RenderEngine& renderEngine = OsEng.renderEngine();
_program = renderEngine.buildRenderProgram("RenderablePlanesCloud",
"${MODULE_DIGITALUNIVERSE}/shaders/plane2_vs.glsl",
"${MODULE_DIGITALUNIVERSE}/shaders/plane2_fs.glsl");
bool success = loadData();
if (!success) {
throw ghoul::RuntimeError("Error loading data");
}
}
void RenderablePlanesCloud::initializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
_program = renderEngine.buildRenderProgram("RenderablePlanesCloud",
"${MODULE_DIGITALUNIVERSE}/shaders/plane2_vs.glsl",
"${MODULE_DIGITALUNIVERSE}/shaders/plane2_fs.glsl");
createPlanes();
loadTextures();
@@ -455,14 +457,14 @@ void RenderablePlanesCloud::deleteDataGPU() {
}
}
void RenderablePlanesCloud::deinitialize() {
void RenderablePlanesCloud::deinitializeGL() {
deleteDataGPU();
RenderEngine& renderEngine = OsEng.renderEngine();
if (_program) {
renderEngine.removeRenderProgram(_program);
_program = nullptr;
}
}
}
void RenderablePlanesCloud::renderPlanes(const RenderData&,
@@ -499,7 +501,7 @@ void RenderablePlanesCloud::renderPlanes(const RenderData&,
_program->setUniform("alphaValue", _alphaValue);
_program->setUniform("scaleFactor", _scaleFactor);
//_program->setUniform("minPlaneSize", 1.f); // in pixels
//bool usingFramebufferRenderer =
// OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::Framebuffer;
@@ -515,7 +517,7 @@ void RenderablePlanesCloud::renderPlanes(const RenderData&,
// //glDepthMask(false);
// glBlendFunc(GL_SRC_ALPHA, GL_ONE);
//}
for (auto pair : _renderingPlanesMap) {
ghoul::opengl::TextureUnit unit;
unit.activate();
@@ -523,14 +525,14 @@ void RenderablePlanesCloud::renderPlanes(const RenderData&,
_program->setUniform("galaxyTexture", unit);
glBindVertexArray(pair.second.vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
glDrawArrays(GL_TRIANGLES, 0, 6);
}
//if (additiveBlending) {
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// //glDepthMask(true);
//}
glBindVertexArray(0);
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
@@ -545,7 +547,7 @@ void RenderablePlanesCloud::renderPlanes(const RenderData&,
if (!blendEnabled) {
glDisable(GL_BLEND);
}
}
}
void RenderablePlanesCloud::renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix,
@@ -553,7 +555,7 @@ void RenderablePlanesCloud::renderLabels(const RenderData& data, const glm::dmat
RenderEngine& renderEngine = OsEng.renderEngine();
_fontRenderer->setFramebufferSize(renderEngine.renderingResolution());
float scale = 0.0;
switch (_unit) {
case Meter:
@@ -578,14 +580,14 @@ void RenderablePlanesCloud::renderLabels(const RenderData& data, const glm::dmat
scale = 306391534.73091 * PARSEC;
break;
}
for (const std::pair<glm::vec3, std::string>& pair : _labelData) {
//glm::vec3 scaledPos(_transformationMatrix * glm::dvec4(pair.first, 1.0));
glm::vec3 scaledPos(pair.first);
scaledPos *= scale;
_fontRenderer->render(
*_font,
scaledPos,
scaledPos,
_textColor,
pow(10.0, _textSize.value()),
_textMinSize,
@@ -597,7 +599,8 @@ void RenderablePlanesCloud::renderLabels(const RenderData& data, const glm::dmat
_renderOption.value(),
"%s",
pair.second.c_str());
}
}
}
void RenderablePlanesCloud::render(const RenderData& data, RendererTasks&) {
@@ -619,14 +622,14 @@ void RenderablePlanesCloud::render(const RenderData& data, RendererTasks&) {
glm::vec3 orthoRight = glm::normalize(glm::vec3(worldToModelTransform * glm::vec4(right, 0.0)));
glm::vec3 orthoUp = glm::normalize(glm::vec3(worldToModelTransform * glm::vec4(up, 0.0)));
if (_hasSpeckFile) {
renderPlanes(data, modelViewMatrix, projectionMatrix);
renderPlanes(data, modelViewMatrix, projectionMatrix);
}
if (_hasLabel) {
renderLabels(data, modelViewProjectionMatrix, orthoRight, orthoUp);
}
}
}
void RenderablePlanesCloud::update(const UpdateData&) {
@@ -638,7 +641,7 @@ void RenderablePlanesCloud::update(const UpdateData&) {
}
bool RenderablePlanesCloud::loadData() {
bool success = false;
bool success = false;
if (_hasSpeckFile) {
std::string _file = _speckFile;
// I disabled the cache as it didn't work on Mac --- abock
@@ -672,7 +675,7 @@ bool RenderablePlanesCloud::loadData() {
//success &= saveCachedFile(cachedFile);
// }
}
std::string labelFile = _labelFile;
if (!labelFile.empty()) {
// I disabled the cache as it didn't work on Mac --- abock
@@ -703,7 +706,7 @@ bool RenderablePlanesCloud::loadData() {
// }
}
return success;
}
@@ -721,7 +724,7 @@ bool RenderablePlanesCloud::loadTextures() {
it->second->uploadTexture();
it->second->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
}
}
}
}
else {
return false;
@@ -791,7 +794,7 @@ bool RenderablePlanesCloud::readSpeckFile() {
}
else {
_nValuesPerAstronomicalObject += 1; // We want the number, but the index is 0 based
}
}
}
if (line.substr(0, 10) == "polyorivar") {
@@ -816,9 +819,9 @@ bool RenderablePlanesCloud::readSpeckFile() {
if (line.substr(0, 8) == "texture ") {
std::stringstream str(line);
int textureIndex = 0;
std::string dummy;
str >> dummy; // command
str >> textureIndex;
@@ -846,7 +849,7 @@ bool RenderablePlanesCloud::readSpeckFile() {
if (line.empty()) {
continue;
}
std::stringstream str(line);
glm::vec3 u(0.0f), v(0.0f);
@@ -897,7 +900,7 @@ bool RenderablePlanesCloud::readLabelFile() {
LERROR("Failed to open Label file '" << _file << "'");
return false;
}
// The beginning of the speck file has a header that either contains comments
// (signaled by a preceding '#') or information about the structure of the file
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
@@ -934,7 +937,7 @@ bool RenderablePlanesCloud::readLabelFile() {
}
}
do {
std::vector<float> values(_nValuesPerAstronomicalObject);
@@ -959,7 +962,7 @@ bool RenderablePlanesCloud::readLabelFile() {
std::string dummy;
str >> dummy; // text keyword
std::string label;
str >> label;
dummy.clear();
@@ -1039,9 +1042,9 @@ void RenderablePlanesCloud::createPlanes() {
LDEBUG("Creating planes");
int planeNumber = 0;
for (int p = 0; p < static_cast<int>(_fullData.size()); p += _nValuesPerAstronomicalObject) {
for (int p = 0; p < _fullData.size(); p += _nValuesPerAstronomicalObject) {
glm::vec4 transformedPos = glm::vec4(_transformationMatrix *
glm::dvec4(_fullData[p + 0], _fullData[p + 1], _fullData[p + 2], 1.0));
glm::dvec4(_fullData[p + 0], _fullData[p + 1], _fullData[p + 2], 1.0));
// Plane vectors u and v
glm::vec4 u = glm::vec4(_transformationMatrix *
@@ -1072,21 +1075,21 @@ void RenderablePlanesCloud::createPlanes() {
RenderingPlane plane;
plane.planeIndex = _fullData[p + _textureVariableIndex];
// JCC: Ask Abbott about these points refeering to a non-existing texture.
if (plane.planeIndex == 30) {
//std::cout << "--- Creating planes - index: " << plane.planeIndex << std::endl;
plane.planeIndex = 0;
}
glGenVertexArrays(1, &plane.vao);
glGenBuffers(1, &plane.vbo);
glm::vec4 vertex0 = transformedPos - u - v; // same as 3
glm::vec4 vertex1 = transformedPos + u + v; // same as 5
glm::vec4 vertex2 = transformedPos - u + v;
glm::vec4 vertex4 = transformedPos + u - v;
float scale = 0.0;
switch (_unit) {
case Meter:
@@ -1142,7 +1145,7 @@ void RenderablePlanesCloud::createPlanes() {
sizeof(GLfloat) * 6,
nullptr
);
// texture coords
glEnableVertexAttribArray(1);
glVertexAttribPointer(
@@ -1152,7 +1155,7 @@ void RenderablePlanesCloud::createPlanes() {
GL_FALSE,
sizeof(GLfloat) * 6,
reinterpret_cast<GLvoid*>(sizeof(GLfloat) * 4)
);
);
_renderingPlanesMap.insert({planeNumber++, plane});
}
@@ -1163,6 +1166,7 @@ void RenderablePlanesCloud::createPlanes() {
}
if (_hasLabel && _labelDataIsDirty) {
_labelDataIsDirty = false;
}
}
@@ -61,7 +61,8 @@ namespace openspace {
~RenderablePlanesCloud() = default;
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -64,7 +64,7 @@ namespace {
"Point Sprite Texture",
"The path to the texture that should be used as the point sprite."
};
static const openspace::properties::Property::PropertyInfo TransparencyInfo = {
"Transparency",
"Transparency",
@@ -174,9 +174,9 @@ namespace openspace {
dictionary,
"RenderablePoints"
);
_speckFile = absPath(dictionary.value<std::string>(KeyFile));
if (dictionary.hasKey(keyUnit)) {
std::string unit = dictionary.value<std::string>(keyUnit);
if (unit == MeterUnit) {
@@ -254,6 +254,13 @@ namespace openspace {
}
void RenderablePoints::initialize() {
bool success = loadData();
if (!success) {
throw ghoul::RuntimeError("Error loading data");
}
}
void RenderablePoints::initializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
if (_hasSpriteTexture) {
_program = renderEngine.buildRenderProgram("RenderablePoints",
@@ -266,14 +273,9 @@ namespace openspace {
"${MODULE_DIGITALUNIVERSE}/shaders/points_fs.glsl");// ,
//"${MODULE_DIGITALUNIVERSE}/shaders/points_gs.glsl");
}
bool success = loadData();
if (!success) {
throw ghoul::RuntimeError("Error loading data");
}
}
void RenderablePoints::deinitialize() {
void RenderablePoints::deinitializeGL() {
glDeleteBuffers(1, &_vbo);
_vbo = 0;
glDeleteVertexArrays(1, &_vao);
@@ -295,7 +297,7 @@ namespace openspace {
_program->activate();
glm::dmat4 modelMatrix = glm::dmat4(1.0);
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
_program->setIgnoreUniformLocationError(IgnoreError::Yes);
_program->setUniform("modelViewProjectionTransform", glm::dmat4(data.camera.projectionMatrix()) *
@@ -305,7 +307,7 @@ namespace openspace {
_program->setUniform("sides", 4);
_program->setUniform("alphaValue", _alphaValue);
_program->setUniform("scaleFactor", _scaleFactor);
if (_hasSpriteTexture) {
ghoul::opengl::TextureUnit spriteTextureUnit;
spriteTextureUnit.activate();
@@ -319,12 +321,12 @@ namespace openspace {
else {
_program->setUniform("hasColorMap", false);
}
glEnable(GL_PROGRAM_POINT_SIZE);
glBindVertexArray(_vao);
const GLsizei nAstronomicalObjects = static_cast<GLsizei>(_fullData.size() / _nValuesPerAstronomicalObject);
glDrawArrays(GL_POINTS, 0, nAstronomicalObjects);
glDisable(GL_PROGRAM_POINT_SIZE);
glBindVertexArray(0);
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
@@ -362,10 +364,11 @@ namespace openspace {
GLint positionAttrib = _program->attributeLocation("in_position");
if (_hasColorMapFile) {
const size_t nAstronomicalObjects = _fullData.size() / _nValuesPerAstronomicalObject;
// const size_t nValues = _slicedData.size() / nAstronomicalObjects;
// GLsizei stride = static_cast<GLsizei>(sizeof(double) * nValues);
const size_t nValues = _slicedData.size() / nAstronomicalObjects;
GLsizei stride = static_cast<GLsizei>(sizeof(double) * nValues);
glEnableVertexAttribArray(positionAttrib);
glVertexAttribLPointer(
positionAttrib,
@@ -385,7 +388,7 @@ namespace openspace {
reinterpret_cast<void*>(sizeof(double)*4)
);
}
else {
else {
glEnableVertexAttribArray(positionAttrib);
glVertexAttribLPointer(
positionAttrib,
@@ -418,7 +421,7 @@ namespace openspace {
[&](const ghoul::filesystem::File&) { _spriteTextureIsDirty = true; }
);
}
_spriteTextureIsDirty = false;
_spriteTextureIsDirty = false;
}
}
@@ -483,7 +486,7 @@ namespace openspace {
while (true) {
std::streampos position = file.tellg();
std::getline(file, line);
if (line[0] == '#' || line.empty()) {
continue;
}
@@ -538,15 +541,15 @@ namespace openspace {
LERROR("Failed to open Color Map file '" << _file << "'");
return false;
}
int numberOfColors = 0;
std::size_t numberOfColors = 0;
// The beginning of the speck file has a header that either contains comments
// (signaled by a preceding '#') or information about the structure of the file
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
std::string line = "";
while (true) {
// std::streampos position = file.tellg();
std::streampos position = file.tellg();
std::getline(file, line);
if (line[0] == '#' || line.empty()) {
@@ -557,18 +560,18 @@ namespace openspace {
std::locale loc;
if (std::isdigit(line[0], loc)) {
std::string::size_type sz;
numberOfColors = static_cast<int>(std::stoi(line, &sz));
numberOfColors = std::stoi(line, &sz);
break;
}
else if (file.eof()) {
return false;
}
}
}
for (int i = 0; i < numberOfColors; ++i) {
for (auto i = 0; i < numberOfColors; ++i) {
std::getline(file, line);
std::stringstream str(line);
glm::vec4 color;
for (auto j = 0; j < 4; ++j) {
str >> color[j];
@@ -576,7 +579,7 @@ namespace openspace {
_colorMapData.push_back(color);
}
return true;
}
@@ -636,7 +639,7 @@ namespace openspace {
return false;
}
}
void RenderablePoints::createDataSlice() {
_slicedData.clear();
if (_hasColorMapFile) {
@@ -673,24 +676,22 @@ namespace openspace {
glm::dvec4 position(p, 1.0);
if (_hasColorMapFile) {
for (int j = 0; j < 4; ++j) {
for (auto j = 0; j < 4; ++j) {
_slicedData.push_back(position[j]);
}
for (int j = 0; j < 4; ++j) {
for (auto j = 0; j < 4; ++j) {
_slicedData.push_back(_colorMapData[colorIndex][j]);
}
}
else {
for (int j = 0; j < 4; ++j) {
for (auto j = 0; j < 4; ++j) {
_slicedData.push_back(position[j]);
}
}
colorIndex =
(colorIndex == (static_cast<int>(_colorMapData.size()) - 1)) ?
0 :
colorIndex + 1;
colorIndex = (colorIndex == (_colorMapData.size() - 1)) ? 0 : colorIndex + 1;
}
}
} // namespace openspace
@@ -54,7 +54,8 @@ namespace openspace {
~RenderablePoints() = default;
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -235,7 +235,7 @@ bool RenderableFieldlines::isReady() const {
return programReady && vectorFieldReady && fieldlineReady && seedPointsReady;
}
void RenderableFieldlines::initialize() {
void RenderableFieldlines::initializeGL() {
if (_vectorFieldInfo.empty() || _fieldlineInfo.empty() || _seedPointsInfo.empty()) {
throw ghoul::RuntimeError("Error initializing");
}
@@ -248,7 +248,7 @@ void RenderableFieldlines::initialize() {
);
}
void RenderableFieldlines::deinitialize() {
void RenderableFieldlines::deinitializeGL() {
glDeleteVertexArrays(1, &_fieldlineVAO);
_fieldlineVAO = 0;
glDeleteBuffers(1, &_vertexPositionBuffer);
@@ -45,8 +45,8 @@ class RenderableFieldlines : public Renderable {
public:
RenderableFieldlines(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
+16 -14
View File
@@ -150,10 +150,10 @@ namespace openspace {
}
}
RenderableGalaxy::~RenderableGalaxy() {}
void RenderableGalaxy::initialize() {
void RenderableGalaxy::initializeGL() {
// Aspect is currently hardcoded to cubic voxels.
_aspect = static_cast<glm::vec3>(_volumeDimensions);
_aspect = _aspect / std::max(std::max(_aspect.x, _aspect.y), _aspect.z);
@@ -163,7 +163,7 @@ void RenderableGalaxy::initialize() {
_volumeDimensions
);
_volume = reader.read();
_texture = std::make_unique<ghoul::opengl::Texture>(
_volumeDimensions,
ghoul::opengl::Texture::Format::RGBA,
@@ -176,6 +176,7 @@ void RenderableGalaxy::initialize() {
_volume->data()),
ghoul::opengl::Texture::TakeOwnership::No
);
_texture->setDimensions(_volume->dimensions());
_texture->uploadTexture();
@@ -200,7 +201,7 @@ void RenderableGalaxy::initialize() {
addProperty(_translation);
addProperty(_rotation);
addProperty(_enabledPointsRatio);
// initialize points.
std::ifstream pointFile(_pointsFilename, std::ios::in | std::ios::binary);
@@ -221,7 +222,7 @@ void RenderableGalaxy::initialize() {
pointFile.close();
float maxdist = 0;
for (size_t i = 0; i < _nPoints; ++i) {
float x = pointData[i * 7 + 0];
float y = pointData[i * 7 + 1];
@@ -231,9 +232,9 @@ void RenderableGalaxy::initialize() {
float b = pointData[i * 7 + 5];
maxdist = std::max(maxdist, glm::length(glm::vec3(x, y, z)));
//float a = pointData[i * 7 + 6]; alpha is not used.
pointPositions.push_back(glm::vec3(x, y, z));
pointColors.push_back(glm::vec3(r, g, b));
pointColors.push_back(glm::vec3(r, g, b));
}
std::cout << maxdist << std::endl;
@@ -278,22 +279,22 @@ void RenderableGalaxy::initialize() {
glBindBuffer(GL_ARRAY_BUFFER, _colorVbo);
glEnableVertexAttribArray(colorAttrib);
glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void RenderableGalaxy::deinitialize() {
void RenderableGalaxy::deinitializeGL() {
if (_raycaster) {
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
_raycaster = nullptr;
}
}
bool RenderableGalaxy::isReady() const {
return true;
}
void RenderableGalaxy::update(const UpdateData& data) {
if (_raycaster) {
@@ -312,7 +313,7 @@ void RenderableGalaxy::update(const UpdateData& data) {
static_cast<glm::vec3>(_volumeSize)
);
_pointTransform = glm::scale(transform, static_cast<glm::vec3>(_pointScaling));
glm::vec4 translation = glm::vec4(static_cast<glm::vec3>(_translation), 0.0);
// Todo: handle floating point overflow, to actually support translation.
@@ -337,6 +338,7 @@ void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) {
glm::vec3 galaxySize = static_cast<glm::vec3>(_volumeSize);
float maxDim = std::max(std::max(galaxySize.x, galaxySize.y), galaxySize.z);
float lowerRampStart = maxDim * 0.02;
float lowerRampEnd = maxDim * 0.5;
@@ -409,5 +411,5 @@ float RenderableGalaxy::safeLength(const glm::vec3& vector) {
OsEng.ref().renderEngine().postRaycast(*_pointsProgram);
}*/
}
+4 -4
View File
@@ -35,14 +35,14 @@
namespace openspace {
struct RenderData;
class RenderableGalaxy : public Renderable {
public:
RenderableGalaxy(const ghoul::Dictionary& dictionary);
~RenderableGalaxy();
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& tasks) override;
void update(const UpdateData& data) override;
@@ -84,7 +84,10 @@ int addLayer(lua_State* L) {
return 0;
}
globe->layerManager()->addLayer(groupID, d);
std::shared_ptr<Layer> layer = globe->layerManager()->addLayer(groupID, d);
if (layer) {
layer->initialize();
}
return 0;
}
@@ -259,17 +259,24 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
addPropertySubOwner(_layerManager.get());
//addPropertySubOwner(_pointGlobe.get());
}
void RenderableGlobe::initializeGL() {
_layerManager->initialize();
_layerManager->update();
_distanceSwitch.initializeGL();
// Recompile the shaders directly so that it is not done the first time the render
// function is called.
_chunkedLodGlobe->recompileShaders();
}
void RenderableGlobe::initialize() {
_distanceSwitch.initialize();
}
void RenderableGlobe::deinitializeGL() {
_distanceSwitch.deinitializeGL();
void RenderableGlobe::deinitialize() {
_distanceSwitch.deinitialize();
_layerManager->deinitialize();
}
bool RenderableGlobe::isReady() const {
@@ -81,8 +81,8 @@ public:
RenderableGlobe(const ghoul::Dictionary& dictionary);
~RenderableGlobe() = default;
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& rendererTask) override;
@@ -37,6 +37,13 @@ bool DistanceSwitch::initialize() {
return true;
}
bool DistanceSwitch::initializeGL() {
for (unsigned int i = 0; i < _renderables.size(); ++i) {
_renderables[i]->initializeGL();
}
return true;
}
bool DistanceSwitch::deinitialize() {
for (unsigned int i = 0; i < _renderables.size(); ++i) {
_renderables[i]->deinitialize();
@@ -44,6 +51,13 @@ bool DistanceSwitch::deinitialize() {
return true;
}
bool DistanceSwitch::deinitializeGL() {
for (unsigned int i = 0; i < _renderables.size(); ++i) {
_renderables[i]->deinitializeGL();
}
return true;
}
void DistanceSwitch::render(const RenderData& data, RendererTasks& tasks) {
const double distanceToCamera =
distance(data.camera.positionVec3(), data.modelTransform.translation);
@@ -46,7 +46,9 @@ public:
~DistanceSwitch();
bool initialize();
bool initializeGL();
bool deinitialize();
bool deinitializeGL();
/**
* Picks the first Renderable with the associated maxDistance greater than the
@@ -38,7 +38,7 @@ namespace openspace::globebrowsing {
ChunkRenderer::ChunkRenderer(std::shared_ptr<Grid> grid,
std::shared_ptr<LayerManager> layerManager)
: _grid(grid)
,_layerManager(layerManager)
, _layerManager(layerManager)
{
_globalLayerShaderManager = std::make_shared<LayerShaderManager>(
"GlobalChunkedLodPatch",
@@ -173,12 +173,16 @@ Layer::Layer(layergroupid::GroupID id, const ghoul::Dictionary& layerDict,
}
});
_remove.onChange([&](){
if (_tileProvider) {
_tileProvider->reset();
_remove.onChange([&]() {
try {
if (_tileProvider) {
_tileProvider->reset();
}
}
catch (...) {
_parent.deleteLayer(name());
throw;
}
_parent.deleteLayer(name());
});
_typeOption.onChange([&](){
@@ -221,6 +225,18 @@ Layer::Layer(layergroupid::GroupID id, const ghoul::Dictionary& layerDict,
addPropertySubOwner(_layerAdjustment);
}
void Layer::initialize() {
if (_tileProvider) {
_tileProvider->initialize();
}
}
void Layer::deinitialize() {
if (_tileProvider) {
_tileProvider->deinitialize();
}
}
ChunkTilePile Layer::getChunkTilePile(const TileIndex& tileIndex, int pileSize) const {
if (_tileProvider) {
return _tileProvider->getChunkTilePile(tileIndex, pileSize);
@@ -56,6 +56,9 @@ public:
Layer(layergroupid::GroupID id, const ghoul::Dictionary& layerDict,
LayerGroup& parent);
void initialize();
void deinitialize();
ChunkTilePile getChunkTilePile(const TileIndex& tileIndex, int pileSize) const;
Tile::Status getTileStatus(const TileIndex& index) const;
@@ -79,6 +79,18 @@ LayerGroup::LayerGroup(layergroupid::GroupID id, const ghoul::Dictionary& dict)
}
}
void LayerGroup::initialize() {
for (const std::shared_ptr<Layer>& l : _layers) {
l->initialize();
}
}
void LayerGroup::deinitialize() {
for (const std::shared_ptr<Layer>& l : _layers) {
l->deinitialize();
}
}
void LayerGroup::update() {
_activeLayers.clear();
@@ -90,26 +102,28 @@ void LayerGroup::update() {
}
}
void LayerGroup::addLayer(const ghoul::Dictionary& layerDict) {
std::shared_ptr<Layer> LayerGroup::addLayer(const ghoul::Dictionary& layerDict) {
if (!layerDict.hasKeyAndValue<std::string>("Name")) {
LERROR("'Name' must be specified for layer.");
return;
return nullptr;
}
auto layer = std::make_shared<Layer>(_groupId, layerDict, *this);
layer->onChange(_onChangeCallback);
if (hasPropertySubOwner(layer->name())) {
LINFO("Layer with name " + layer->name() + " already exists.");
_levelBlendingEnabled.setVisibility(properties::Property::Visibility::User);
return nullptr;
}
else {
_layers.push_back(layer);
update();
//update();
if (_onChangeCallback) {
_onChangeCallback();
}
addPropertySubOwner(layer.get());
_levelBlendingEnabled.setVisibility(properties::Property::Visibility::User);
return layer;
}
_levelBlendingEnabled.setVisibility(properties::Property::Visibility::User);
}
void LayerGroup::deleteLayer(const std::string& layerName) {
@@ -119,6 +133,7 @@ void LayerGroup::deleteLayer(const std::string& layerName) {
{
if (it->get()->name() == layerName) {
removePropertySubOwner(it->get());
(*it)->deinitialize();
_layers.erase(it);
update();
if (_onChangeCallback) {
@@ -46,10 +46,13 @@ struct LayerGroup : public properties::PropertyOwner {
LayerGroup(layergroupid::GroupID id);
LayerGroup(layergroupid::GroupID id, const ghoul::Dictionary& dict);
void initialize();
void deinitialize();
/// Updates all layers tile providers within this group
void update();
void addLayer(const ghoul::Dictionary& layerDict);
std::shared_ptr<Layer> addLayer(const ghoul::Dictionary& layerDict);
void deleteLayer(const std::string& layerName);
/// @returns const vector of all layers
@@ -68,9 +68,23 @@ LayerManager::LayerManager(const ghoul::Dictionary& layerGroupsDict)
}
}
void LayerManager::addLayer(layergroupid::GroupID groupId, ghoul::Dictionary layerDict) {
void LayerManager::initialize() {
for (const std::shared_ptr<LayerGroup>& lg : _layerGroups) {
lg->initialize();
}
}
void LayerManager::deinitialize() {
for (const std::shared_ptr<LayerGroup>& lg : _layerGroups) {
lg->deinitialize();
}
}
std::shared_ptr<Layer> LayerManager::addLayer(layergroupid::GroupID groupId,
ghoul::Dictionary layerDict)
{
ghoul_assert(groupId != layergroupid::Unknown, "Layer group ID must be known");
_layerGroups[groupId]->addLayer(layerDict);
return _layerGroups[groupId]->addLayer(layerDict);
}
void LayerManager::deleteLayer(layergroupid::GroupID groupId, std::string layerName) {
@@ -45,7 +45,10 @@ class LayerManager : public properties::PropertyOwner {
public:
LayerManager(const ghoul::Dictionary& textureCategoriesDictionary);
void addLayer(layergroupid::GroupID groupId, ghoul::Dictionary layerDict);
void initialize();
void deinitialize();
std::shared_ptr<Layer> addLayer(layergroupid::GroupID groupId, ghoul::Dictionary layerDict);
void deleteLayer(layergroupid::GroupID groupId, std::string layerName);
const LayerGroup& layerGroup(size_t groupId);
@@ -86,15 +86,10 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary)
if (hasStart && hasEnd) {
const std::string start = dictionary.value<std::string>(KeyPreCacheStartTime);
const std::string end = dictionary.value<std::string>(KeyPreCacheEndTime);
std::vector<Time> preCacheTimes = _timeQuantizer.quantized(
_preCacheTimes = _timeQuantizer.quantized(
Time(Time::convertTime(start)),
Time(Time::convertTime(end))
);
LINFO("Preloading: " << _filePath.value());
for (const Time& t : preCacheTimes) {
getTileProvider(t);
}
}
_successfulInitialization = true;
}
@@ -104,6 +99,21 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary)
}
}
bool TemporalTileProvider::initialize() {
bool success = TileProvider::initialize();
if (!_preCacheTimes.empty()) {
LINFO("Preloading: " << _filePath.value());
for (const Time& t : _preCacheTimes) {
getTileProvider(t);
}
_preCacheTimes.clear();
}
return success;
}
bool TemporalTileProvider::readFilePath() {
std::ifstream in(_filePath.value().c_str());
std::string xml;
@@ -298,6 +308,7 @@ std::shared_ptr<TileProvider> TemporalTileProvider::getTileProvider(
}
else {
std::shared_ptr<TileProvider> tileProvider = initTileProvider(timekey);
tileProvider->initialize();
_tileProviderMap[timekey] = tileProvider;
return tileProvider;
@@ -202,6 +202,8 @@ public:
*/
TemporalTileProvider(const ghoul::Dictionary& dictionary);
bool initialize() override;
// These methods implements the TileProvider interface
virtual Tile getTile(const TileIndex& tileIndex) override;
@@ -330,6 +332,9 @@ private:
TimeFormat* _timeFormat;
TimeQuantizer _timeQuantizer;
std::vector<Time> _preCacheTimes;
bool _successfulInitialization;
};
@@ -47,16 +47,27 @@ TextTileProvider::TextTileProvider(const TileTextureInitData& initData, size_t f
, _fontSize(fontSize)
{
_tileCache = OsEng.moduleEngine().module<GlobeBrowsingModule>()->tileCache();
}
TextTileProvider::~TextTileProvider() {}
bool TextTileProvider::initialize() {
bool res = TileProvider::initialize();
_font = OsEng.fontManager().font("Mono", static_cast<float>(_fontSize));
_fontRenderer = std::unique_ptr<FontRenderer>(FontRenderer::createDefault());
_fontRenderer->setFramebufferSize(glm::vec2(_initData.dimensions()));
glGenFramebuffers(1, &_fbo);
return res;
}
TextTileProvider::~TextTileProvider() {
bool TextTileProvider::deinitialize() {
glDeleteFramebuffers(1, &_fbo);
return TileProvider::deinitialize();
}
Tile TextTileProvider::getTile(const TileIndex& tileIndex) {
@@ -53,6 +53,9 @@ public:
TextTileProvider(const TileTextureInitData& initData, size_t fontSize = 48);
virtual ~TextTileProvider() override;
bool initialize() override;
bool deinitialize() override;
// The TileProvider interface below is implemented in this class
virtual Tile getTile(const TileIndex& tileIndex) override;
virtual Tile::Status getTileStatus(const TileIndex& index) override;
@@ -55,17 +55,13 @@ TileProvider::TileProvider()
: properties::PropertyOwner({ "tileProvider" })
, _initialized(false)
, _defaultTile(nullptr, nullptr, Tile::Status::Unavailable)
{
initialize();
}
{}
TileProvider::TileProvider(const ghoul::Dictionary&)
: properties::PropertyOwner({ "tileProvider" })
, _initialized(false)
, _defaultTile(nullptr, nullptr, Tile::Status::Unavailable)
{
initialize();
}
{}
float TileProvider::noDataValueAsFloat() {
ghoul_assert(_initialized, "TileProvider was not initialized.");
@@ -115,6 +115,24 @@ TileProviderByLevel::TileProviderByLevel(const ghoul::Dictionary& dictionary) {
}
}
bool TileProviderByLevel::initialize() {
bool success = TileProvider::initialize();
for (const std::shared_ptr<TileProvider>& tp : _levelTileProviders) {
success &= tp->initialize();
}
return success;
}
bool TileProviderByLevel::deinitialize() {
bool success = true;
for (const std::shared_ptr<TileProvider>& tp : _levelTileProviders) {
success &= tp->deinitialize();
}
return TileProvider::deinitialize() && success;
}
Tile TileProviderByLevel::getTile(const TileIndex& tileIndex) {
TileProvider* provider = levelProvider(tileIndex.level);
if (provider) {
@@ -37,6 +37,9 @@ public:
TileProviderByLevel(const std::string& imagePath);
virtual ~TileProviderByLevel() = default;
bool initialize() override;
bool deinitialize() override;
virtual Tile getTile(const TileIndex& tileIndex) override;
virtual Tile::Status getTileStatus(const TileIndex& index) override;
virtual TileDepthTransform depthTransform() override;
@@ -132,7 +132,8 @@ namespace {
};
} // namespace
namespace openspace::kameleonvolume {
namespace openspace {
namespace kameleonvolume {
RenderableKameleonVolume::RenderableKameleonVolume(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
@@ -181,7 +182,7 @@ RenderableKameleonVolume::RenderableKameleonVolume(const ghoul::Dictionary& dict
if (dictionary.getValue(KeySource, sourcePath)) {
_sourcePath = absPath(sourcePath);
}
std::string variable;
if (dictionary.getValue(KeyVariable, variable)) {
_variable = variable;
@@ -255,12 +256,12 @@ RenderableKameleonVolume::RenderableKameleonVolume(const ghoul::Dictionary& dict
}
}
}
RenderableKameleonVolume::~RenderableKameleonVolume() {}
void RenderableKameleonVolume::initialize() {
void RenderableKameleonVolume::initializeGL() {
load();
_volumeTexture->uploadTexture();
_transferFunction->update();
@@ -322,7 +323,7 @@ void RenderableKameleonVolume::initialize() {
void RenderableKameleonVolume::updateRaycasterModelTransform() {
glm::vec3 lowerBoundingBoxBound = _domainScale.value() * _lowerDomainBound.value();
glm::vec3 upperBoundingBoxBound = _domainScale.value() * _upperDomainBound.value();
glm::vec3 scale = upperBoundingBoxBound - lowerBoundingBoxBound;
glm::vec3 translation = (lowerBoundingBoxBound + upperBoundingBoxBound) * 0.5f;
@@ -398,7 +399,7 @@ void RenderableKameleonVolume::loadCdf(const std::string& path) {
}
std::vector<std::string> variables = reader.gridVariableNames();
if (variables.size() == 3 && _autoDomainBounds) {
_lowerDomainBound = glm::vec3(
reader.minValue(variables[0]),
@@ -458,18 +459,18 @@ void RenderableKameleonVolume::storeRaw(const std::string& path) {
volume::RawVolumeWriter<float> writer(path);
writer.write(*_rawVolume);
}
void RenderableKameleonVolume::deinitialize() {
void RenderableKameleonVolume::deinitializeGL() {
if (_raycaster) {
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
_raycaster = nullptr;
}
}
bool RenderableKameleonVolume::isReady() const {
return true;
}
void RenderableKameleonVolume::update(const UpdateData&) {
if (_raycaster) {
_raycaster->setStepSize(_stepSize);
@@ -479,5 +480,6 @@ void RenderableKameleonVolume::update(const UpdateData&) {
void RenderableKameleonVolume::render(const RenderData& data, RendererTasks& tasks) {
tasks.raycasterTasks.push_back({ _raycaster.get(), data });
}
} // namespace openspace::kameleonvolume
}
}
@@ -48,9 +48,9 @@ class RenderableKameleonVolume : public Renderable {
public:
RenderableKameleonVolume(const ghoul::Dictionary& dictionary);
~RenderableKameleonVolume();
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& tasks) override;
void update(const UpdateData& data) override;
@@ -415,7 +415,7 @@ bool RenderableMultiresVolume::setSelectorType(Selector selector) {
return false;
}
void RenderableMultiresVolume::initialize() {
void RenderableMultiresVolume::initializeGL() {
bool success = _tsp && _tsp->load();
unsigned int maxNumBricks = _tsp->header().xNumBricks_ * _tsp->header().yNumBricks_ * _tsp->header().zNumBricks_;
@@ -477,7 +477,7 @@ void RenderableMultiresVolume::initialize() {
}
}
void RenderableMultiresVolume::deinitialize() {
void RenderableMultiresVolume::deinitializeGL() {
_tsp = nullptr;
_transferFunction = nullptr;
}
@@ -68,8 +68,8 @@ public:
bool setSelectorType(Selector selector);
bool initializeSelector();
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -195,7 +195,7 @@ RenderableConstellationBounds::RenderableConstellationBounds(
}
}
void RenderableConstellationBounds::initialize() {
void RenderableConstellationBounds::initializeGL() {
_program = OsEng.renderEngine().buildRenderProgram(
"ConstellationBounds",
"${MODULE_SPACE}/shaders/constellationbounds_vs.glsl",
@@ -222,7 +222,7 @@ void RenderableConstellationBounds::initialize() {
glBindVertexArray(0);
}
void RenderableConstellationBounds::deinitialize() {
void RenderableConstellationBounds::deinitializeGL() {
glDeleteBuffers(1, &_vbo);
_vbo = 0;
glDeleteVertexArrays(1, &_vao);
@@ -51,8 +51,8 @@ class RenderableConstellationBounds : public Renderable {
public:
RenderableConstellationBounds(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
+2 -2
View File
@@ -335,7 +335,7 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
}
}
void RenderablePlanet::initialize() {
void RenderablePlanet::initializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
if (_programObject == nullptr && _shadowEnabled && _hasNightTexture) {
@@ -377,7 +377,7 @@ void RenderablePlanet::initialize() {
loadTexture();
}
void RenderablePlanet::deinitialize() {
void RenderablePlanet::deinitializeGL() {
if (_geometry) {
_geometry->deinitialize();
_geometry = nullptr;
+2 -2
View File
@@ -68,8 +68,8 @@ public:
public:
RenderablePlanet(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& rendererTask) override;
+2 -2
View File
@@ -183,7 +183,7 @@ bool RenderableRings::isReady() const {
return _shader && _texture;
}
void RenderableRings::initialize() {
void RenderableRings::initializeGL() {
if (!_shader) {
RenderEngine& renderEngine = OsEng.renderEngine();
_shader = renderEngine.buildRenderProgram("RingProgram",
@@ -201,7 +201,7 @@ void RenderableRings::initialize() {
loadTexture();
}
void RenderableRings::deinitialize() {
void RenderableRings::deinitializeGL() {
glDeleteVertexArrays(1, &_quad);
_quad = 0;
+2 -2
View File
@@ -46,8 +46,8 @@ class RenderableRings : public Renderable {
public:
RenderableRings(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
+2 -2
View File
@@ -286,7 +286,7 @@ bool RenderableStars::isReady() const {
return (_program != nullptr) && (!_fullData.empty());
}
void RenderableStars::initialize() {
void RenderableStars::initializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
_program = renderEngine.buildRenderProgram("Star",
"${MODULE_SPACE}/shaders/star_vs.glsl",
@@ -299,7 +299,7 @@ void RenderableStars::initialize() {
}
}
void RenderableStars::deinitialize() {
void RenderableStars::deinitializeGL() {
glDeleteBuffers(1, &_vbo);
_vbo = 0;
glDeleteVertexArrays(1, &_vao);
+2 -2
View File
@@ -48,8 +48,8 @@ public:
explicit RenderableStars(const ghoul::Dictionary& dictionary);
~RenderableStars();
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -135,7 +135,7 @@ bool RenderableCrawlingLine::isReady() const {
return (_program != nullptr);
}
void RenderableCrawlingLine::initialize() {
void RenderableCrawlingLine::initializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
_program = renderEngine.buildRenderProgram(
"RenderableCrawlingLine",
@@ -166,7 +166,7 @@ void RenderableCrawlingLine::initialize() {
glBindVertexArray(0);
}
void RenderableCrawlingLine::deinitialize(){
void RenderableCrawlingLine::deinitializeGL() {
glDeleteVertexArrays(1, &_vao);
_vao = 0;
glDeleteBuffers(1, &_vbo);
@@ -38,8 +38,8 @@ class RenderableCrawlingLine : public Renderable {
public:
RenderableCrawlingLine(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -297,7 +297,7 @@ RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary)
addProperty(_colors.square);
}
void RenderableFov::initialize() {
void RenderableFov::initializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
_programObject = renderEngine.buildRenderProgram(
"FovProgram",
@@ -411,7 +411,7 @@ void RenderableFov::initialize() {
glBindVertexArray(0);
}
void RenderableFov::deinitialize() {
void RenderableFov::deinitializeGL() {
OsEng.renderEngine().removeRenderProgram(_programObject);
_programObject = nullptr;
@@ -48,15 +48,15 @@ namespace documentation { struct Documentation; }
class RenderableFov : public Renderable {
public:
RenderableFov(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& rendererTask) override;
void update(const UpdateData& data) override;
static documentation::Documentation Documentation();
private:
@@ -153,7 +153,7 @@ private:
properties::Vec4Property square; // Color for the orthogonal square
} _colors;
};
} // namespace openspace
#endif // __OPENSPACE_MODULE_SPACECRAFTINSTRUMENTS___RENDERABLEFOV___H__
@@ -180,7 +180,7 @@ bool RenderableModelProjection::isReady() const {
return ready;
}
void RenderableModelProjection::initialize() {
void RenderableModelProjection::initializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
_programObject = renderEngine.buildRenderProgram("ModelShader",
"${MODULE_SPACECRAFTINSTRUMENTS}/shaders/renderableModel_vs.glsl",
@@ -207,7 +207,7 @@ void RenderableModelProjection::initialize() {
setBoundingSphere(bs); // ignore bounding sphere set by geometry.
}
void RenderableModelProjection::deinitialize() {
void RenderableModelProjection::deinitializeGL() {
if (_geometry) {
_geometry->deinitialize();
}
@@ -55,8 +55,8 @@ public:
RenderableModelProjection(const ghoul::Dictionary& dictionary);
~RenderableModelProjection();
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -94,7 +94,7 @@ bool RenderablePlaneProjection::isReady() const {
return _shader && _texture;
}
void RenderablePlaneProjection::initialize() {
void RenderablePlaneProjection::initializeGL() {
glGenVertexArrays(1, &_quad); // generate array
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
@@ -110,7 +110,7 @@ void RenderablePlaneProjection::initialize() {
loadTexture();
}
void RenderablePlaneProjection::deinitialize() {
void RenderablePlaneProjection::deinitializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
if (_shader) {
renderEngine.removeRenderProgram(_shader);
@@ -54,9 +54,9 @@ class RenderablePlaneProjection : public Renderable {
public:
RenderablePlaneProjection(const ghoul::Dictionary& dictionary);
~RenderablePlaneProjection();
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -69,7 +69,7 @@ private:
void setTarget(std::string body);
std::string _texturePath;
bool _planeIsDirty;
glm::dmat3 _stateMatrix;
@@ -223,7 +223,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
RenderablePlanetProjection::~RenderablePlanetProjection() {}
void RenderablePlanetProjection::initialize() {
void RenderablePlanetProjection::initializeGL() {
_programObject = OsEng.renderEngine().buildRenderProgram(
"projectiveProgram",
"${MODULE_SPACECRAFTINSTRUMENTS}/shaders/renderablePlanet_vs.glsl",
@@ -273,7 +273,7 @@ void RenderablePlanetProjection::initialize() {
glBindVertexArray(0);
}
void RenderablePlanetProjection::deinitialize() {
void RenderablePlanetProjection::deinitializeGL() {
_projectionComponent.deinitialize();
_baseTexture = nullptr;
_geometry = nullptr;
@@ -44,8 +44,8 @@ public:
RenderablePlanetProjection(const ghoul::Dictionary& dictionary);
~RenderablePlanetProjection();
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& rendererTask) override;
@@ -58,7 +58,6 @@ protected:
bool loadTextures();
void attitudeParameters(double time);
private:
void imageProjectGPU(std::shared_ptr<ghoul::opengl::Texture> projectionTexture);
@@ -260,7 +260,7 @@ RenderableShadowCylinder::RenderableShadowCylinder(const ghoul::Dictionary& dict
_aberration = static_cast<int>(aberration.type);
}
void RenderableShadowCylinder::initialize() {
void RenderableShadowCylinder::initializeGL() {
glGenVertexArrays(1, &_vao);
glGenBuffers(1, &_vbo);
@@ -272,7 +272,7 @@ void RenderableShadowCylinder::initialize() {
);
}
void RenderableShadowCylinder::deinitialize() {
void RenderableShadowCylinder::deinitializeGL() {
RenderEngine& renderEngine = OsEng.renderEngine();
if (_shader) {
renderEngine.removeRenderProgram(_shader);
@@ -50,8 +50,8 @@ class RenderableShadowCylinder : public Renderable {
public:
RenderableShadowCylinder(const ghoul::Dictionary& dictionary);
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& rendererTask) override;
@@ -104,10 +104,10 @@ RenderableToyVolume::RenderableToyVolume(const ghoul::Dictionary& dictionary)
_stepSize = stepSize;
}
}
RenderableToyVolume::~RenderableToyVolume() {}
void RenderableToyVolume::initialize() {
void RenderableToyVolume::initializeGL() {
_raycaster = std::make_unique<ToyVolumeRaycaster>(_color);
_raycaster->initialize();
@@ -131,19 +131,19 @@ void RenderableToyVolume::initialize() {
addProperty(_rotation);
addProperty(_color);
}
void RenderableToyVolume::deinitialize() {
void RenderableToyVolume::deinitializeGL() {
if (_raycaster) {
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
_raycaster = nullptr;
}
}
bool RenderableToyVolume::isReady() const {
// @TODO isReady function needs to be filled
return true;
}
void RenderableToyVolume::update(const UpdateData& data) {
if (_raycaster) {
glm::mat4 transform = glm::translate(
@@ -155,12 +155,14 @@ void RenderableToyVolume::update(const UpdateData& data) {
transform = glm::rotate(transform, eulerRotation.x, glm::vec3(1, 0, 0));
transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0, 1, 0));
transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0, 0, 1));
transform = glm::scale(
transform,
static_cast<glm::vec3>(_scaling) *
std::pow(10.0f, static_cast<float>(_scalingExponent))
);
_raycaster->setColor(_color);
_raycaster->setStepSize(_stepSize);
_raycaster->setModelTransform(transform);
@@ -172,5 +174,5 @@ void RenderableToyVolume::render(const RenderData& data, RendererTasks& tasks) {
RaycasterTask task{ _raycaster.get(), data };
tasks.raycasterTasks.push_back(task);
}
} // namespace openspace
@@ -38,14 +38,14 @@ namespace openspace {
class ToyVolumeRaycaster;
struct RenderData;
class RenderableToyVolume : public Renderable {
public:
RenderableToyVolume(const ghoul::Dictionary& dictionary);
~RenderableToyVolume();
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& tasks) override;
void update(const UpdateData& data) override;
@@ -57,7 +57,7 @@ private:
properties::Vec3Property _translation;
properties::Vec3Property _rotation;
properties::Vec4Property _color;
std::unique_ptr<ToyVolumeRaycaster> _raycaster;
};
@@ -45,7 +45,9 @@
namespace {
const char* _loggerCat = "RenderableTimeVaryingVolume";
}
namespace {
const char* KeyDimensions = "Dimensions";
const char* KeyStepSize = "StepSize";
const char* KeyTransferFunction = "TransferFunction";
@@ -146,7 +148,6 @@ namespace {
"Upper value bound",
"" // @TODO Missing documentation
};
} // namespace
namespace openspace {
@@ -208,10 +209,11 @@ RenderableTimeVaryingVolume::RenderableTimeVaryingVolume(
_gridType = (gridType == VolumeGridType::Spherical) ? 1 : 0;
}
}
RenderableTimeVaryingVolume::~RenderableTimeVaryingVolume() {}
void RenderableTimeVaryingVolume::initialize() {
void RenderableTimeVaryingVolume::initializeGL() {
using RawPath = ghoul::filesystem::Directory::RawPath;
ghoul::filesystem::Directory sequenceDir(_sourceDirectory, RawPath::Yes);
@@ -232,6 +234,7 @@ void RenderableTimeVaryingVolume::initialize() {
}
}
// TODO: defer loading of data to later. (separate thread or at least not when loading)
for (auto& p : _volumeTimesteps) {
Timestep& t = p.second;
@@ -350,7 +353,7 @@ void RenderableTimeVaryingVolume::loadTimestepMetadata(const std::string& path)
t.time = Time::convertTime(timeString);
t.inRam = false;
t.onGpu = false;
_volumeTimesteps[t.time] = std::move(t);
}
@@ -473,11 +476,14 @@ void RenderableTimeVaryingVolume::render(const RenderData& data, RendererTasks&
}
}
bool RenderableTimeVaryingVolume::isReady() const {
return true;
}
void RenderableTimeVaryingVolume::deinitialize() {
void RenderableTimeVaryingVolume::deinitializeGL() {
if (_raycaster) {
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
_raycaster = nullptr;
@@ -22,8 +22,8 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_VOLUME___RENDERABLETIMEVARYINGVOLUME___H__
#define __OPENSPACE_MODULE_VOLUME___RENDERABLETIMEVARYINGVOLUME___H__
#ifndef __OPENSPACE_MODULE_VOLUME___RENDERABLEKAMELEONVOLUME___H__
#define __OPENSPACE_MODULE_VOLUME___RENDERABLEKAMELEONVOLUME___H__
#include <openspace/rendering/renderable.h>
@@ -47,9 +47,9 @@ class RenderableTimeVaryingVolume : public Renderable {
public:
RenderableTimeVaryingVolume(const ghoul::Dictionary& dictionary);
~RenderableTimeVaryingVolume();
void initialize() override;
void deinitialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& tasks) override;
void update(const UpdateData& data) override;
@@ -106,4 +106,4 @@ private:
} // namespace volume
} // namespace openspace
#endif // __OPENSPACE_MODULE_VOLUME___RENDERABLETIMEVARYINGVOLUME___H__
#endif // __OPENSPACE_MODULE_KAMELEONVOLUME___RENDERABLEKAMELEONVOLUME___H__
+8 -1
View File
@@ -53,7 +53,8 @@ return {
Fonts = {
Mono = "${FONTS}/Bitstream-Vera-Sans-Mono/VeraMono.ttf",
Light = "${FONTS}/Roboto/Roboto-Regular.ttf",
Console = "${FONTS}/Inconsolata/Inconsolata-Regular.ttf"
Console = "${FONTS}/Inconsolata/Inconsolata-Regular.ttf",
Loading = "${FONTS}/Roboto/Roboto-Regular.ttf"
},
Logging = {
LogDir = "${LOGS}",
@@ -78,6 +79,12 @@ return {
FactoryDocumentation = "${DOCUMENTATION}/FactoryDocumentation.html",
LicenseDocumentation = "${DOCUMENTATION}/License.html",
UseMultithreadedInitialization = true,
LoadingScreen = {
ShowMessage = true,
ShowNodeNames = true,
ShowProgressbar = true
},
-- CheckOpenGLState = true,
-- LogEachOpenGLCall = true,
+41
View File
@@ -0,0 +1,41 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 - 2017 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
in vec2 st;
out vec4 FragColor;
uniform bool useTexture;
uniform sampler2D logoTexture;
uniform vec4 color;
void main() {
if (useTexture) {
FragColor = texture(logoTexture, st);
}
else {
FragColor = color;
}
}
+35
View File
@@ -0,0 +1,35 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 - 2017 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
in vec2 in_position;
in vec2 in_st;
out vec2 st;
void main() {
gl_Position = vec4(in_position, 0.0, 1.0);
st = in_st;
}
+2
View File
@@ -120,6 +120,7 @@ set(OPENSPACE_SOURCE
${OPENSPACE_BASE_DIR}/src/query/query.cpp
${OPENSPACE_BASE_DIR}/src/rendering/abufferrenderer.cpp
${OPENSPACE_BASE_DIR}/src/rendering/framebufferrenderer.cpp
${OPENSPACE_BASE_DIR}/src/rendering/loadingscreen.cpp
${OPENSPACE_BASE_DIR}/src/rendering/raycastermanager.cpp
${OPENSPACE_BASE_DIR}/src/rendering/renderable.cpp
${OPENSPACE_BASE_DIR}/src/rendering/renderengine.cpp
@@ -282,6 +283,7 @@ set(OPENSPACE_HEADER
${OPENSPACE_BASE_DIR}/include/openspace/query/query.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/abufferrenderer.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/framebufferrenderer.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/loadingscreen.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/raycasterlistener.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/raycastermanager.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderable.h
+8
View File
@@ -104,6 +104,14 @@ const string ConfigurationManager::PartFilterSeverity = "PartFilterSeverity";
const string ConfigurationManager::KeyCheckOpenGLState = "CheckOpenGLState";
const string ConfigurationManager::KeyLogEachOpenGLCall = "LogEachOpenGLCall";
const string ConfigurationManager::KeyUseMultithreadedInitialization =
"UseMultithreadedInitialization";
const string ConfigurationManager::KeyLoadingScreen = "LoadingScreen";
const string ConfigurationManager::PartShowMessage = "ShowMessage";
const string ConfigurationManager::PartShowNodeNames = "ShowNodeNames";
const string ConfigurationManager::PartShowProgressbar = "ShowProgressbar";
string ConfigurationManager::findConfiguration(const string& filename) {
using ghoul::filesystem::Directory;
+39
View File
@@ -427,6 +427,45 @@ documentation::Documentation ConfigurationManager::Documentation() {
"'TRACE' loglevel. This will bring the rendering to a crawl but provides "
"useful debugging features for the order in which OpenGL calls occur. This "
"defaults to 'false'."
},
{
ConfigurationManager::KeyUseMultithreadedInitialization,
new BoolVerifier,
Optional::Yes,
"This value determines whether the initialization of the scene graph should "
"occur multithreaded, that is, whether multiple scene graph nodes should "
"initialize in parallel. The only use for this value is to disable it for "
"debugging support."
},
{
ConfigurationManager::KeyLoadingScreen,
new TableVerifier({
{
ConfigurationManager::PartShowMessage,
new BoolVerifier,
Optional::Yes,
"If this value is set to 'true', the loading screen will display a "
"message information about the current phase the loading is in."
},
{
ConfigurationManager::PartShowNodeNames,
new BoolVerifier,
Optional::Yes,
"If this value is set to 'true', the loading screen will display a "
"list of all of the nodes with their respective status (created, "
"loaded, initialized)."
},
{
ConfigurationManager::PartShowProgressbar,
new BoolVerifier,
Optional::Yes,
"If this value is set to 'true', the loading screen will contain a "
"progress bar that gives an estimate of the loading progression."
}
}),
Optional::Yes,
"Values in this table describe the behavior of the loading screen that is "
"displayed while the scene graph is created and initialized."
}
}
};
+116 -33
View File
@@ -41,6 +41,7 @@
#include <openspace/interaction/luaconsole.h>
#include <openspace/network/networkengine.h>
#include <openspace/network/parallelconnection.h>
#include <openspace/rendering/loadingscreen.h>
#include <openspace/rendering/renderable.h>
#include <openspace/scripting/scriptscheduler.h>
#include <openspace/scripting/scriptengine.h>
@@ -164,6 +165,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName,
, _scriptScheduler(new scripting::ScriptScheduler)
, _virtualPropertyManager(new VirtualPropertyManager)
, _globalPropertyNamespace(new properties::PropertyOwner({ "" }))
, _loadingScreen(nullptr)
, _versionInformation{
properties::StringProperty(VersionInfo, OPENSPACE_VERSION_STRING_FULL),
properties::StringProperty(SourceControlInfo, OPENSPACE_GIT_FULL)
@@ -581,45 +583,121 @@ void OpenSpaceEngine::loadScene(const std::string& scenePath) {
}
Scene* scene;
try {
scene = _sceneManager->loadScene(scenePath);
} catch (const ghoul::FileNotFoundError& e) {
LERRORC(e.component, e.message);
return;
} catch (const Scene::InvalidSceneError& e) {
LERRORC(e.component, e.message);
return;
} catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.message);
return;
bool showMessage = true;
std::string kMessage =
ConfigurationManager::KeyLoadingScreen + "." +
ConfigurationManager::PartShowMessage;
if (configurationManager().hasKey(kMessage)) {
showMessage = configurationManager().value<bool>(kMessage);
}
catch (const std::exception& e) {
LERROR(e.what());
return;
bool showNodeNames = true;
std::string kNames =
ConfigurationManager::KeyLoadingScreen + "." +
ConfigurationManager::PartShowNodeNames;
if (configurationManager().hasKey(kNames)) {
showNodeNames = configurationManager().value<bool>(kNames);
}
catch (...) {
LERROR("Unknown error loading the scene");
bool showProgressbar = true;
std::string kProgress =
ConfigurationManager::KeyLoadingScreen + "." +
ConfigurationManager::PartShowProgressbar;
if (configurationManager().hasKey(kProgress)) {
showProgressbar = configurationManager().value<bool>(kProgress);
}
_loadingScreen = std::make_unique<LoadingScreen>(
LoadingScreen::ShowMessage(showMessage),
LoadingScreen::ShowNodeNames(showNodeNames),
LoadingScreen::ShowProgressbar(showProgressbar)
);
// We can initialize all SceneGraphNodes in a separate thread since none of them use
// an OpenGL context
std::atomic_bool initializeFinished(false);
bool errorWhileLoading = false;
std::thread t([&scene, scenePath, &initializeFinished, &errorWhileLoading, this]() {
_loadingScreen->postMessage("Creating scene...");
_loadingScreen->setPhase(LoadingScreen::Phase::Construction);
try {
scene = _sceneManager->loadScene(scenePath);
}
catch (const ghoul::FileNotFoundError& e) {
LERRORC(e.component, e.message);
errorWhileLoading = true;
return;
}
catch (const Scene::InvalidSceneError& e) {
LERRORC(e.component, e.message);
errorWhileLoading = true;
return;
}
catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.message);
errorWhileLoading = true;
return;
}
catch (const std::exception& e) {
LERROR(e.what());
errorWhileLoading = true;
return;
}
catch (...) {
LERROR("Unknown error loading the scene");
errorWhileLoading = true;
return;
}
Scene* previousScene = _renderEngine->scene();
if (previousScene) {
_syncEngine->removeSyncables(_timeManager->getSyncables());
_syncEngine->removeSyncables(_renderEngine->getSyncables());
_syncEngine->removeSyncable(_scriptEngine.get());
_renderEngine->setScene(nullptr);
_renderEngine->setCamera(nullptr);
_sceneManager->unloadScene(*previousScene);
}
// Initialize the RenderEngine
_renderEngine->setScene(scene);
_renderEngine->setCamera(scene->camera());
_renderEngine->setGlobalBlackOutFactor(0.0);
_renderEngine->startFading(1, 3.0);
_loadingScreen->setPhase(LoadingScreen::Phase::Initialization);
scene->initialize();
_loadingScreen->postMessage("Finished initializing");
initializeFinished = true;
});
// While the SceneGraphNodes initialize themselves, we can hand over control to the
// Loading screen rendering
while (!initializeFinished) {
_loadingScreen->render();
}
_loadingScreen->postMessage("Initializing OpenGL");
_loadingScreen->finalize();
t.join();
// It's okay to delete it since the last rendered image will remain on screen
_loadingScreen = nullptr;
if (errorWhileLoading) {
return;
}
Scene* previousScene = _renderEngine->scene();
if (previousScene) {
_syncEngine->removeSyncables(_timeManager->getSyncables());
_syncEngine->removeSyncables(_renderEngine->getSyncables());
_syncEngine->removeSyncable(_scriptEngine.get());
scene->initializeGL();
_renderEngine->setScene(nullptr);
_renderEngine->setCamera(nullptr);
_sceneManager->unloadScene(*previousScene);
}
// Initialize the RenderEngine
_renderEngine->setScene(scene);
_renderEngine->setCamera(scene->camera());
_renderEngine->setGlobalBlackOutFactor(0.0);
_renderEngine->startFading(1, 3.0);
scene->initialize();
// Update the scene so that position of objects are set in case they are used in
// post sync scripts
_renderEngine->updateScene();
@@ -1533,6 +1611,11 @@ TimeManager& OpenSpaceEngine::timeManager() {
return *_timeManager;
}
LoadingScreen& OpenSpaceEngine::loadingScreen() {
ghoul_assert(_loadingScreen, "Loading Screen must not be nullptr");
return *_loadingScreen;
}
WindowWrapper& OpenSpaceEngine::windowWrapper() {
ghoul_assert(_windowWrapper, "Window Wrapper must not be nullptr");
return *_windowWrapper;
+7
View File
@@ -262,4 +262,11 @@ void SGCTWindowWrapper::takeScreenshot(bool applyWarping) const {
sgct::Engine::instance()->takeScreenshot();
}
void SGCTWindowWrapper::swapBuffer() const {
GLFWwindow* w = glfwGetCurrentContext();
glfwSwapBuffers(w);
glfwPollEvents();
}
} // namespace openspace
+2
View File
@@ -184,4 +184,6 @@ bool WindowWrapper::isSimpleRendering() const {
void WindowWrapper::takeScreenshot(bool) const {}
void WindowWrapper::swapBuffer() const {}
} // namespace openspace
+699
View File
@@ -0,0 +1,699 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <openspace/rendering/loadingscreen.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/engine/wrapper/windowwrapper.h>
#include <ghoul/font/font.h>
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
#include <random>
#include <thread>
namespace {
const float LoadingFontSize = 25.f;
const float MessageFontSize = 22.f;
const float ItemFontSize = 12.f;
const glm::vec2 LogoCenter = { 0.f, 0.4f }; // in NDC
const glm::vec2 LogoSize = { 0.35f, 0.35 }; // in NDC
const glm::vec2 ProgressbarCenter = { 0.f, -0.75f }; // in NDC
const glm::vec2 ProgressbarSize = { 0.7f, 0.0075f }; // in NDC
const float ProgressbarLineWidth = 0.0025f; // in NDC
const glm::vec4 ProgressbarOutlineColor = glm::vec4(0.9f, 0.9f, 0.9f, 1.f);
const glm::vec4 PhaseColorConstruction = glm::vec4(0.7f, 0.7f, 0.f, 1.f);
const glm::vec4 PhaseColorInitialization = glm::vec4(0.1f, 0.75f, 0.1f, 1.f);
const glm::vec4 ItemStatusColorStarted = glm::vec4(0.5f, 0.5f, 0.5f, 1.f);
const glm::vec4 ItemStatusColorInitializing = glm::vec4(0.7f, 0.7f, 0.f, 1.f);
const glm::vec4 ItemStatusColorFinished = glm::vec4(0.1f, 0.75f, 0.1f, 1.f);
const glm::vec4 ItemStatusColorFailed = glm::vec4(0.8f, 0.1f, 0.1f, 1.f);
const float ItemStandoffDistance = 5.f; // in pixels
const float LoadingTextPosition = 0.275f; // in NDC
const float StatusMessageOffset = 0.225f; // in NDC
const int MaxNumberLocationSamples = 1000;
const std::chrono::milliseconds TTL(5000);
const std::chrono::milliseconds RefreshRate(16);
bool rectOverlaps(glm::vec2 lhsLl, glm::vec2 lhsUr, glm::vec2 rhsLl, glm::vec2 rhsUr)
{
lhsLl -= glm::vec2(ItemStandoffDistance / 2.f);
lhsUr += glm::vec2(ItemStandoffDistance / 2.f);
rhsLl -= glm::vec2(ItemStandoffDistance / 2.f);
rhsUr += glm::vec2(ItemStandoffDistance / 2.f);
return !(
lhsUr.x < rhsLl.x ||
lhsLl.x > rhsUr.x ||
lhsUr.y < rhsLl.y ||
lhsLl.y > rhsUr.y
);
}
glm::vec2 ndcToScreen(glm::vec2 ndc, glm::ivec2 res) {
ndc.x = (ndc.x + 1.f) / 2.f * res.x;
ndc.y = (ndc.y + 1.f) / 2.f * res.y;
return ndc;
}
} // namespace
namespace openspace {
LoadingScreen::LoadingScreen(ShowMessage showMessage, ShowNodeNames showNodeNames,
ShowProgressbar showProgressbar)
: _showMessage(showMessage)
, _showNodeNames(showNodeNames)
, _showProgressbar(showProgressbar)
, _iProgress(0)
, _nItems(0)
, _loadingFont(nullptr)
, _messageFont(nullptr)
, _itemFont(nullptr)
, _logo{ 0, 0 }
, _progressbar{ 0, 0, 0, 0 }
, _randomEngine(_randomDevice())
{
const glm::vec2 dpiScaling = OsEng.windowWrapper().dpiScaling();
const glm::ivec2 res =
glm::vec2(OsEng.windowWrapper().currentWindowResolution()) / dpiScaling;
_program = ghoul::opengl::ProgramObject::Build(
"Loading Screen",
"${SHADERS}/loadingscreen.vert",
"${SHADERS}/loadingscreen.frag"
);
_loadingFont = OsEng.fontManager().font(
"Loading",
LoadingFontSize,
ghoul::fontrendering::FontManager::Outline::No,
ghoul::fontrendering::FontManager::LoadGlyphs::No
);
if (_showMessage) {
_messageFont = OsEng.fontManager().font(
"Loading",
MessageFontSize,
ghoul::fontrendering::FontManager::Outline::No,
ghoul::fontrendering::FontManager::LoadGlyphs::No
);
}
if (_showNodeNames) {
_itemFont = OsEng.fontManager().font(
"Loading",
ItemFontSize,
ghoul::fontrendering::FontManager::Outline::No,
ghoul::fontrendering::FontManager::LoadGlyphs::No
);
}
{
// Logo stuff
_logoTexture = ghoul::io::TextureReader::ref().loadTexture(
absPath("${OPENSPACE_DATA}/openspace-logo.png")
);
_logoTexture->uploadTexture();
glGenVertexArrays(1, &_logo.vao);
glBindVertexArray(_logo.vao);
glGenBuffers(1, &_logo.vbo);
glBindBuffer(GL_ARRAY_BUFFER, _logo.vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
2,
GL_FLOAT,
GL_FALSE,
4 * sizeof(GLfloat),
nullptr
);
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
2,
GL_FLOAT,
GL_FALSE,
4 * sizeof(GLfloat),
reinterpret_cast<void*>(2 * sizeof(GLfloat))
);
glBindVertexArray(0);
}
if (_showProgressbar) {
// Progress bar stuff
glGenVertexArrays(1, &_progressbar.vaoFill);
glBindVertexArray(_progressbar.vaoFill);
glGenBuffers(1, & _progressbar.vboFill);
glBindBuffer(GL_ARRAY_BUFFER, _progressbar.vboFill);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
2,
GL_FLOAT,
GL_FALSE,
2 * sizeof(GLfloat),
nullptr
);
glGenVertexArrays(1, &_progressbar.vaoBox);
glBindVertexArray(_progressbar.vaoBox);
glGenBuffers(1, & _progressbar.vboBox);
glBindBuffer(GL_ARRAY_BUFFER, _progressbar.vboBox);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
2,
GL_FLOAT,
GL_FALSE,
2 * sizeof(GLfloat),
nullptr
);
glBindVertexArray(0);
}
}
LoadingScreen::~LoadingScreen() {
_logoTexture = nullptr;
_loadingFont = nullptr;
_messageFont = nullptr;
_itemFont = nullptr;
glDeleteVertexArrays(1, &_logo.vao);
glDeleteBuffers(1, &_logo.vbo);
glDeleteVertexArrays(1, &_progressbar.vaoFill);
glDeleteBuffers(1, &_progressbar.vboFill);
glDeleteVertexArrays(1, &_progressbar.vaoBox);
glDeleteBuffers(1, &_progressbar.vboBox);
}
void LoadingScreen::render() {
// We have to recalculate the positions here because we will not be informed about a
// window size change
const glm::vec2 dpiScaling = OsEng.windowWrapper().dpiScaling();
const glm::ivec2 res =
glm::vec2(OsEng.windowWrapper().currentWindowResolution()) / dpiScaling;
float screenAspectRatio = static_cast<float>(res.x) / static_cast<float>(res.y);
float textureAspectRatio = static_cast<float>(_logoTexture->dimensions().x) /
static_cast<float>(_logoTexture->dimensions().y);
glm::vec2 size = {
LogoSize.x,
LogoSize.y * textureAspectRatio * screenAspectRatio
};
glm::vec2 logoLl = { LogoCenter.x - size.x, LogoCenter.y - size.y };
glm::vec2 logoUr = { LogoCenter.x + size.x, LogoCenter.y + size.y };
GLfloat data[] = {
logoLl.x, logoLl.y, 0.f, 0.f,
logoUr.x, logoUr.y, 1.f, 1.f,
logoLl.x, logoUr.y, 0.f, 1.f,
logoLl.x, logoLl.y, 0.f, 0.f,
logoUr.x, logoLl.y, 1.f, 0.f,
logoUr.x, logoUr.y, 1.f, 1.f
};
glBindVertexArray(_logo.vao);
glBindBuffer(GL_ARRAY_BUFFER, _logo.vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
//
// Clear background
//
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(ClearBufferMask::GL_COLOR_BUFFER_BIT);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);
//
// Render logo
//
_program->activate();
ghoul::opengl::TextureUnit unit;
unit.activate();
_logoTexture->bind();
_program->setUniform(
"logoTexture",
unit
);
_program->setUniform(
"useTexture",
true
);
glDrawArrays(GL_TRIANGLES, 0, 6);
//
// Render progress bar
//
glm::vec2 progressbarSize = {
ProgressbarSize.x,
ProgressbarSize.y * screenAspectRatio
};
glm::vec2 progressbarLl = {
ProgressbarCenter.x - progressbarSize.x,
ProgressbarCenter.y - progressbarSize.y
};
glm::vec2 progressbarUr = {
ProgressbarCenter.x + progressbarSize.x ,
ProgressbarCenter.y + progressbarSize.y
};
if (_showProgressbar) {
glBindVertexArray(_progressbar.vaoFill);
// Depending on the progress, we only want to draw the progress bar to a mixture
// of the lowerleft and upper right extent
float progress = _nItems != 0 ?
static_cast<float>(_iProgress) / static_cast<float>(_nItems) :
0.f;
glm::vec2 ur = progressbarUr;
ur.x = glm::mix(progressbarLl.x, progressbarUr.x, progress);
GLfloat dataFill[] = {
progressbarLl.x, progressbarLl.y,
ur.x, ur.y,
progressbarLl.x, ur.y,
progressbarLl.x, progressbarLl.y,
ur.x, progressbarLl.y,
ur.x, ur.y,
};
glBindBuffer(GL_ARRAY_BUFFER, _progressbar.vboFill);
glBufferData(GL_ARRAY_BUFFER, sizeof(dataFill), dataFill, GL_STATIC_DRAW);
_program->setUniform("useTexture", false);
switch (_phase) {
case Phase::Construction:
_program->setUniform("color", PhaseColorConstruction);
break;
case Phase::Initialization:
_program->setUniform("color", PhaseColorInitialization);
break;
}
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(_progressbar.vaoBox);
float w = ProgressbarLineWidth / screenAspectRatio;
float h = ProgressbarLineWidth;
GLfloat dataBox[] = {
// In order to avoid the deprecated glLineWidth, we split the lines into
// separate triangles instead
// Left side
progressbarLl.x - w , progressbarLl.y - h,
progressbarLl.x + w, progressbarUr.y + h,
progressbarLl.x - w, progressbarUr.y + h,
progressbarLl.x - w , progressbarLl.y - h,
progressbarLl.x + w , progressbarLl.y - h,
progressbarLl.x + w, progressbarUr.y + h,
// Top side
progressbarLl.x - w, progressbarUr.y - h,
progressbarUr.x + w, progressbarUr.y + h,
progressbarLl.x - w, progressbarUr.y + h,
progressbarLl.x - w, progressbarUr.y - h,
progressbarUr.x + w, progressbarUr.y - h,
progressbarUr.x + w, progressbarUr.y + h,
// Right side
progressbarUr.x - w, progressbarLl.y - h,
progressbarUr.x + w, progressbarUr.y + h,
progressbarUr.x - w, progressbarUr.y - h,
progressbarUr.x - w, progressbarLl.y - h,
progressbarUr.x + w, progressbarLl.y - h,
progressbarUr.x + w, progressbarUr.y + h,
// Bottom side
progressbarLl.x - w, progressbarLl.y - h,
progressbarUr.x + w, progressbarLl.y + h,
progressbarLl.x - w, progressbarLl.y + h,
progressbarLl.x - w, progressbarLl.y - h,
progressbarUr.x + w, progressbarLl.y - h,
progressbarUr.x + w, progressbarLl.y + h,
};
glBindBuffer(GL_ARRAY_BUFFER, _progressbar.vboBox);
glBufferData(GL_ARRAY_BUFFER, sizeof(dataBox), dataBox, GL_STATIC_DRAW);
_program->setUniform("useTexture", false);
_program->setUniform("color", ProgressbarOutlineColor);
glDrawArrays(GL_TRIANGLES, 0, 24);
}
glBindVertexArray(0);
_program->deactivate();
//
// "Loading" text
//
using FR = ghoul::fontrendering::FontRenderer;
FR& renderer = FR::defaultRenderer();
// We use "Loading" to center the text, but render "Loading..." to make it look more
// pleasing
FR::BoundingBoxInformation bbox = renderer.boundingBox(
*_loadingFont,
"%s",
"Loading."
);
glm::vec2 loadingLl = glm::vec2(
res.x / 2.f - bbox.boundingBox.x / 2.f,
res.y * LoadingTextPosition
);
glm::vec2 loadingUr = loadingLl + bbox.boundingBox;
renderer.render(
*_loadingFont,
loadingLl,
glm::vec4(1.f, 1.f, 1.f, 1.f),
"%s",
"Loading..."
);
glm::vec2 messageLl;
glm::vec2 messageUr;
if (_showMessage) {
std::lock_guard<std::mutex> guard(_messageMutex);
FR::BoundingBoxInformation bboxMessage = renderer.boundingBox(
*_messageFont,
"%s",
_message.c_str()
);
messageLl = glm::vec2(
res.x / 2.f - bboxMessage.boundingBox.x / 2.f,
res.y * StatusMessageOffset
);
messageUr = messageLl + bboxMessage.boundingBox;
renderer.render(
*_messageFont,
messageLl,
glm::vec4(1.f, 1.f, 1.f, 1.f),
"%s",
_message.c_str()
);
}
if (_showNodeNames) {
std::lock_guard<std::mutex> guard(_itemsMutex);
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
for (Item& item : _items) {
if (!item.hasLocation) {
// Compute a new location
FR::BoundingBoxInformation b = renderer.boundingBox(
*_itemFont,
"%s",
item.name.c_str()
);
// The maximum count is in here since we can't control the amount of
// screen estate and the number of nodes. Rather than looping forever
// we make use with an overlap in the worst case
bool foundSpace = false;
glm::vec2 ll;
glm::vec2 ur;
int i = 0;
for ( /* i */; i < MaxNumberLocationSamples && !foundSpace; ++i) {
std::uniform_int_distribution<int> distX(
15,
res.x - b.boundingBox.x - 15
);
std::uniform_int_distribution<int> distY(
15,
res.y - b.boundingBox.y - 15
);
ll = { distX(_randomEngine), distY(_randomEngine) };
ur = ll + b.boundingBox;
// Test against logo and text
bool logoOverlap = rectOverlaps(
ndcToScreen(logoLl, res), ndcToScreen(logoUr, res),
ll, ur
);
bool loadingOverlap = rectOverlaps(
loadingLl, loadingUr,
ll, ur
);
bool messageOverlap = _showMessage ?
rectOverlaps(messageLl, messageUr, ll, ur) :
false;
bool barOverlap = _showProgressbar ?
rectOverlaps(
ndcToScreen(progressbarLl, res),
ndcToScreen(progressbarUr, res),
ll,
ur
) :
false;
if (logoOverlap || loadingOverlap || messageOverlap || barOverlap) {
continue;
}
// Test against all other boxes
bool overlap = false;
for (const Item& j : _items) {
overlap |= rectOverlaps(j.ll, j.ur, ll, ur);
if (overlap) {
break;
}
}
if (!overlap) {
break;
}
}
item.ll = ll;
item.ur = ur;
item.hasLocation = true;
#ifdef LOADINGSCREEN_DEBUGGING
item.exhaustedSearch = (i == MaxNumberLocationSamples);
#endif // LOADINGSCREEN_DEBUGGING
}
glm::vec4 color = [status = item.status]() {
switch (status) {
case ItemStatus::Started:
return ItemStatusColorStarted;
case ItemStatus::Initializing:
return ItemStatusColorInitializing;
case ItemStatus::Finished:
return ItemStatusColorFinished;
case ItemStatus::Failed:
return ItemStatusColorFailed;
default:
return glm::vec4(1.f);
}
}();
if (item.status == ItemStatus::Finished) {
auto t = std::chrono::duration_cast<std::chrono::milliseconds>(now - item.finishedTime);
color.a = 1.f - static_cast<float>(t.count()) / static_cast<float>(TTL.count());
}
#ifdef LOADINGSCREEN_DEBUGGING
if (item.exhaustedSearch) {
color = glm::vec4(0.f, 1.f, 1.f, 1.f);
}
#endif // LOADINGSCREEN_DEBUGGING
renderer.render(
*_itemFont,
item.ll,
color,
"%s",
item.name.c_str()
);
}
_items.erase(
std::remove_if(
_items.begin(),
_items.end(),
[now](const Item& i) {
if (i.status == ItemStatus::Finished) {
return i.finishedTime > now + TTL;
}
else {
return false;
}
}
),
_items.end()
);
}
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
std::this_thread::sleep_for(RefreshRate);
OsEng.windowWrapper().swapBuffer();
}
void LoadingScreen::postMessage(std::string message) {
std::lock_guard<std::mutex> guard(_messageMutex);
_message = std::move(message);
}
void LoadingScreen::finalize() {
_items.erase(
std::remove_if(
_items.begin(),
_items.end(),
[](const Item& i) {
return i.status != ItemStatus::Failed;
}
),
_items.end()
);
render();
}
void LoadingScreen::setItemNumber(int nItems) {
_nItems = nItems;
}
void LoadingScreen::tickItem() {
++_iProgress;
}
void LoadingScreen::setPhase(Phase phase) {
_phase = phase;
_iProgress = 0;
}
void LoadingScreen::updateItem(const std::string& itemName, ItemStatus newStatus) {
if (!_showNodeNames) {
// If we don't want to show the node names, we can disable the updating which
// also would create any of the text information
return;
}
std::lock_guard<std::mutex> guard(_itemsMutex);
auto it = std::find_if(
_items.begin(),
_items.end(),
[&itemName](const Item& i) {
return i.name == itemName;
}
);
if (it != _items.end()) {
it->status = newStatus;
if (newStatus == ItemStatus::Finished) {
it->finishedTime = std::chrono::system_clock::now();
}
}
else {
ghoul_assert(
newStatus == ItemStatus::Started,
"Item '" + itemName + "' did not exist but first message was not Started"
);
// We are not computing the location in here since doing it this way might stall
// the main thread while trying to find a position for the new item
_items.push_back({
itemName,
ItemStatus::Started,
false,
#ifdef LOADINGSCREEN_DEBUGGING
false,
#endif // LOADINGSCREEN_DEBUGGING
{},
{},
std::chrono::system_clock::from_time_t(0)
});
}
}
} // namespace openspace
+4
View File
@@ -151,8 +151,12 @@ Renderable::~Renderable() {}
void Renderable::initialize() {}
void Renderable::initializeGL() {}
void Renderable::deinitialize() {}
void Renderable::deinitializeGL() {}
void Renderable::setBoundingSphere(float boundingSphere) {
_boundingSphere = boundingSphere;
}
+8
View File
@@ -304,6 +304,10 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary
}
bool ScreenSpaceRenderable::initialize() {
return true;
}
bool ScreenSpaceRenderable::initializeGL() {
_originalViewportSize = OsEng.windowWrapper().currentWindowResolution();
createPlane();
@@ -313,6 +317,10 @@ bool ScreenSpaceRenderable::initialize() {
}
bool ScreenSpaceRenderable::deinitialize() {
return true;
}
bool ScreenSpaceRenderable::deinitializeGL() {
glDeleteVertexArrays(1, &_quad);
_quad = 0;

Some files were not shown because too many files have changed in this diff Show More