Merge branch 'master' into thesis/2018/exoplanets

This commit is contained in:
Emma Broman
2020-09-11 13:43:01 +02:00
318 changed files with 3222 additions and 2604 deletions
@@ -72,6 +72,7 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -150,6 +151,8 @@ namespace {
namespace openspace {
void AtmosphereDeferredcaster::initialize() {
ZoneScoped
if (!_atmosphereCalculated) {
preCalculateAtmosphereParam();
}
@@ -159,6 +162,8 @@ void AtmosphereDeferredcaster::initialize() {
}
void AtmosphereDeferredcaster::deinitialize() {
ZoneScoped
_transmittanceProgramObject = nullptr;
_irradianceProgramObject = nullptr;
_irradianceSupTermsProgramObject = nullptr;
@@ -847,24 +852,7 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO,
ghoul::opengl::TextureUnit deltaSMieTableTextureUnit;
ghoul::opengl::TextureUnit deltaJTableTextureUnit;
// Saving current OpenGL state
GLboolean blendEnabled = glIsEnabled(GL_BLEND);
GLenum blendEquationRGB;
GLenum blendEquationAlpha;
GLenum blendDestAlpha;
GLenum blendDestRGB;
GLenum blendSrcAlpha;
GLenum blendSrcRGB;
if (blendEnabled) {
glDisable(GL_BLEND);
}
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
glDisable(GL_BLEND);
// ===========================================================
// See Precomputed Atmosphere Scattering from Bruneton et al. paper, algorithm 4.1:
@@ -1210,12 +1198,7 @@ void AtmosphereDeferredcaster::executeCalculations(GLuint quadCalcVAO,
}
// Restores OpenGL blending state
if (blendEnabled) {
glEnable(GL_BLEND);
}
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
global::renderEngine.openglStateCache().resetBlendState();
}
void AtmosphereDeferredcaster::preCalculateAtmosphereParam() {
@@ -1234,7 +1217,7 @@ void AtmosphereDeferredcaster::preCalculateAtmosphereParam() {
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
GLint m_viewport[4];
glGetIntegerv(GL_VIEWPORT, m_viewport);
global::renderEngine.openglStateCache().viewport(m_viewport);
// Creates the FBO for the calculations
GLuint calcFBO;
@@ -1260,12 +1243,7 @@ void AtmosphereDeferredcaster::preCalculateAtmosphereParam() {
// Restores system state
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glViewport(
m_viewport[0],
m_viewport[1],
m_viewport[2],
m_viewport[3]
);
global::renderEngine.openglStateCache().setViewportState(m_viewport);
glDeleteBuffers(1, &quadCalcVBO);
glDeleteVertexArrays(1, &quadCalcVAO);
glDeleteFramebuffers(1, &calcFBO);
@@ -40,6 +40,7 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/assert.h>
#include <ghoul/misc/invariants.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -55,29 +56,29 @@
namespace {
static const char* _loggerCat = "RenderableAtmosphere";
const char* KeyShadowGroup = "ShadowGroup";
const char* KeyShadowSource = "Source";
const char* KeyShadowCaster = "Caster";
constexpr const char* KeyShadowGroup = "ShadowGroup";
constexpr const char* KeyShadowSource = "Source";
constexpr const char* KeyShadowCaster = "Caster";
const char* keyAtmosphere = "Atmosphere";
const char* keyAtmosphereRadius = "AtmosphereRadius";
const char* keyPlanetRadius = "PlanetRadius";
const char* keyAverageGroundReflectance = "PlanetAverageGroundReflectance";
const char* keyRayleigh = "Rayleigh";
const char* keyRayleighHeightScale = "H_R";
const char* keyOzone = "Ozone";
const char* keyOzoneHeightScale = "H_O";
const char* keyMie = "Mie";
const char* keyMieHeightScale = "H_M";
const char* keyMiePhaseConstant = "G";
const char* keyImage = "Image";
const char* keyToneMappingOp = "ToneMapping";
const char* keyATMDebug = "Debug";
const char* keyTextureScale = "PreCalculatedTextureScale";
const char* keySaveTextures = "SaveCalculatedTextures";
constexpr const char* keyAtmosphere = "Atmosphere";
constexpr const char* keyAtmosphereRadius = "AtmosphereRadius";
constexpr const char* keyPlanetRadius = "PlanetRadius";
constexpr const char* keyAverageGroundReflectance = "PlanetAverageGroundReflectance";
constexpr const char* keyRayleigh = "Rayleigh";
constexpr const char* keyRayleighHeightScale = "H_R";
constexpr const char* keyOzone = "Ozone";
constexpr const char* keyOzoneHeightScale = "H_O";
constexpr const char* keyMie = "Mie";
constexpr const char* keyMieHeightScale = "H_M";
constexpr const char* keyMiePhaseConstant = "G";
constexpr const char* keyImage = "Image";
constexpr const char* keyToneMappingOp = "ToneMapping";
constexpr const char* keyATMDebug = "Debug";
constexpr const char* keyTextureScale = "PreCalculatedTextureScale";
constexpr const char* keySaveTextures = "SaveCalculatedTextures";
constexpr openspace::properties::Property::PropertyInfo AtmosphereHeightInfo = {
"atmmosphereHeight",
"atmosphereHeight",
"Atmosphere Height (KM)",
"The thickness of the atmosphere in Km"
};
@@ -715,6 +716,8 @@ glm::dmat4 RenderableAtmosphere::computeModelTransformMatrix(
}
void RenderableAtmosphere::render(const RenderData& data, RendererTasks& renderTask) {
ZoneScoped
if (_atmosphereEnabled) {
DeferredcasterTask task{ _deferredcaster.get(), data };
renderTask.deferredcasterTasks.push_back(task);
+19 -14
View File
@@ -37,6 +37,7 @@
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
namespace {
constexpr const char* KeyFontMono = "Mono";
@@ -352,6 +353,7 @@ DashboardItemAngle::DashboardItemAngle(const ghoul::Dictionary& dictionary)
addProperty(_destination.nodeName);
_font = global::fontManager.font(_fontName, _fontSize);
_buffer.resize(128);
}
std::pair<glm::dvec3, std::string> DashboardItemAngle::positionAndLabel(
@@ -391,6 +393,8 @@ std::pair<glm::dvec3, std::string> DashboardItemAngle::positionAndLabel(
}
void DashboardItemAngle::render(glm::vec2& penPosition) {
ZoneScoped
std::pair<glm::dvec3, std::string> sourceInfo = positionAndLabel(_source);
std::pair<glm::dvec3, std::string> referenceInfo = positionAndLabel(_reference);
std::pair<glm::dvec3, std::string> destinationInfo = positionAndLabel(_destination);
@@ -398,16 +402,16 @@ void DashboardItemAngle::render(glm::vec2& penPosition) {
const glm::dvec3 a = referenceInfo.first - sourceInfo.first;
const glm::dvec3 b = destinationInfo.first - sourceInfo.first;
std::fill(_buffer.begin(), _buffer.end(), 0);
if (glm::length(a) == 0.0 || glm::length(b) == 0) {
penPosition.y -= _font->height();
RenderFont(
*_font,
penPosition,
fmt::format(
"Could not compute angle at {} between {} and {}",
sourceInfo.second, destinationInfo.second, referenceInfo.second
)
char* end = fmt::format_to(
_buffer.data(),
"Could not compute angle at {} between {} and {}",
sourceInfo.second, destinationInfo.second, referenceInfo.second
);
std::string_view text = std::string_view(_buffer.data(), end - _buffer.data());
RenderFont(*_font, penPosition, text);
}
else {
const double angle = glm::degrees(
@@ -415,18 +419,19 @@ void DashboardItemAngle::render(glm::vec2& penPosition) {
);
penPosition.y -= _font->height();
RenderFont(
*_font,
penPosition,
fmt::format(
"Angle at {} between {} and {}: {} degrees",
sourceInfo.second, destinationInfo.second, referenceInfo.second, angle
)
char* end = fmt::format_to(
_buffer.data(),
"Angle at {} between {} and {}: {} degrees",
sourceInfo.second, destinationInfo.second, referenceInfo.second, angle
);
std::string_view text = std::string_view(_buffer.data(), end - _buffer.data());
RenderFont(*_font, penPosition, text);
}
}
glm::vec2 DashboardItemAngle::size() const {
ZoneScoped
constexpr const double Angle = 120;
return _font->boundingBox("Angle: " + std::to_string(Angle));
@@ -73,6 +73,7 @@ private:
properties::StringProperty _fontName;
properties::FloatProperty _fontSize;
std::vector<char> _buffer;
std::shared_ptr<ghoul::fontrendering::Font> _font;
};
@@ -31,6 +31,7 @@
#include <ghoul/font/font.h>
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/misc/profiling.h>
namespace {
constexpr const char* KeyFontMono = "Mono";
@@ -110,6 +111,8 @@ DashboardItemDate::DashboardItemDate(const ghoul::Dictionary& dictionary)
}
void DashboardItemDate::render(glm::vec2& penPosition) {
ZoneScoped
penPosition.y -= _font->height();
RenderFont(
*_font,
@@ -119,6 +122,8 @@ void DashboardItemDate::render(glm::vec2& penPosition) {
}
glm::vec2 DashboardItemDate::size() const {
ZoneScoped
return _font->boundingBox(
fmt::format("Date: {} UTC", global::timeManager.time().UTC())
);
@@ -38,6 +38,7 @@
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
namespace {
constexpr const char* KeyFontMono = "Mono";
@@ -358,6 +359,8 @@ DashboardItemDistance::DashboardItemDistance(const ghoul::Dictionary& dictionary
addProperty(_requestedUnit);
_font = global::fontManager.font(_fontName, _fontSize);
_buffer.resize(256);
}
std::pair<glm::dvec3, std::string> DashboardItemDistance::positionAndLabel(
@@ -419,6 +422,8 @@ std::pair<glm::dvec3, std::string> DashboardItemDistance::positionAndLabel(
}
void DashboardItemDistance::render(glm::vec2& penPosition) {
ZoneScoped
std::pair<glm::dvec3, std::string> sourceInfo = positionAndLabel(
_source,
_destination
@@ -440,18 +445,20 @@ void DashboardItemDistance::render(glm::vec2& penPosition) {
}
penPosition.y -= _font->height();
RenderFont(
*_font,
penPosition,
fmt::format(
"Distance from {} to {}: {:f} {}",
sourceInfo.second, destinationInfo.second, dist.first, dist.second
)
std::fill(_buffer.begin(), _buffer.end(), 0);
char* end = fmt::format_to(
_buffer.data(),
"Distance from {} to {}: {:f} {}\0",
sourceInfo.second, destinationInfo.second, dist.first, dist.second
);
std::string_view text = std::string_view(_buffer.data(), end - _buffer.data());
RenderFont(*_font, penPosition, text);
}
glm::vec2 DashboardItemDistance::size() const {
ZoneScoped
const double d = glm::length(1e20);
std::pair<double, std::string> dist;
if (_doSimplification) {
@@ -79,6 +79,8 @@ private:
Component _source;
Component _destination;
std::vector<char> _buffer;
std::shared_ptr<ghoul::fontrendering::Font> _font;
};
@@ -31,6 +31,7 @@
#include <ghoul/font/font.h>
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/misc/profiling.h>
namespace {
constexpr const char* KeyFontMono = "Mono";
@@ -70,17 +71,22 @@ namespace {
constexpr const char* ValueFpsAvg = "Average frames per second";
constexpr const char* ValueNone = "None";
std::string formatDt() {
return fmt::format(
"Avg. Frametime: {:.2f} ms",
[[ nodiscard ]] char* formatDt(std::vector<char>& buffer) {
return fmt::format_to(
buffer.data(),
"Avg. Frametime: {:.2f} ms\0",
openspace::global::windowDelegate.averageDeltaTime() * 1000.0
);
}
std::string formatDtExtremes(double minFrametimeCache, double maxFrametimeCache) {
return fmt::format(
[[ nodiscard ]] char* formatDtExtremes(std::vector<char>& buffer,
double minFrametimeCache,
double maxFrametimeCache)
{
return fmt::format_to(
buffer.data(),
"Last frametimes between: {:.2f} and {:.2f} ms\n"
"Overall between: {:.2f} and {:.2f} ms",
"Overall between: {:.2f} and {:.2f} ms\0",
openspace::global::windowDelegate.minDeltaTime() * 1000.0,
openspace::global::windowDelegate.maxDeltaTime() * 1000.0,
minFrametimeCache,
@@ -88,54 +94,59 @@ namespace {
);
}
std::string formatDtStandardDeviation() {
return fmt::format(
"Frametime standard deviation : {:.2f} ms",
[[ nodiscard ]] char* formatDtStandardDeviation(std::vector<char>& buffer) {
return fmt::format_to(
buffer.data(),
"Frametime standard deviation : {:.2f} ms\0",
openspace::global::windowDelegate.deltaTimeStandardDeviation() * 1000.0
);
}
std::string formatDtCoefficientOfVariation() {
return fmt::format(
"Frametime coefficient of variation : {:.2f} %",
[[ nodiscard ]] char* formatDtCoefficientOfVariation(std::vector<char>& buffer) {
return fmt::format_to(
buffer.data(),
"Frametime coefficient of variation : {:.2f} %\0",
openspace::global::windowDelegate.deltaTimeStandardDeviation() /
openspace::global::windowDelegate.averageDeltaTime() * 100.0
);
}
std::string formatFps() {
return fmt::format(
"FPS: {:3.2f}",
[[ nodiscard ]] char* formatFps(std::vector<char>& buffer) {
return fmt::format_to(
buffer.data(),
"FPS: {:3.2f}\0",
1.0 / openspace::global::windowDelegate.deltaTime()
);
}
std::string formatAverageFps() {
return fmt::format(
"Avg. FPS: {:3.2f}",
[[ nodiscard ]] char* formatAverageFps(std::vector<char>& buffer) {
return fmt::format_to(
buffer.data(),
"Avg. FPS: {:3.2f}\0",
1.0 / openspace::global::windowDelegate.averageDeltaTime()
);
}
std::string format(openspace::DashboardItemFramerate::FrametimeType frametimeType,
double minFrametimeCache, double maxFrametimeCache)
[[ nodiscard ]] char* format(std::vector<char>& buffer,
openspace::DashboardItemFramerate::FrametimeType frametimeType,
double minFrametimeCache, double maxFrametimeCache)
{
using namespace openspace;
switch (frametimeType) {
case DashboardItemFramerate::FrametimeType::DtTimeAvg:
return formatDt();
return formatDt(buffer);
case DashboardItemFramerate::FrametimeType::DtTimeExtremes:
return formatDtExtremes(minFrametimeCache, maxFrametimeCache);
return formatDtExtremes(buffer, minFrametimeCache, maxFrametimeCache);
case DashboardItemFramerate::FrametimeType::DtStandardDeviation:
return formatDtStandardDeviation();
return formatDtStandardDeviation(buffer);
case DashboardItemFramerate::FrametimeType::DtCoefficientOfVariation:
return formatDtCoefficientOfVariation();
return formatDtCoefficientOfVariation(buffer);
case DashboardItemFramerate::FrametimeType::FPS:
return formatFps();
return formatFps(buffer);
case DashboardItemFramerate::FrametimeType::FPSAvg:
return formatAverageFps();
return formatAverageFps(buffer);
default:
return "";
throw ghoul::MissingCaseException();
}
}
} // namespace
@@ -262,9 +273,13 @@ DashboardItemFramerate::DashboardItemFramerate(const ghoul::Dictionary& dictiona
addProperty(_clearCache);
_font = global::fontManager.font(_fontName, _fontSize);
_buffer.resize(128);
}
void DashboardItemFramerate::render(glm::vec2& penPosition) {
ZoneScoped
if (_shouldClearCache) {
_minDeltaTimeCache = 1.0;
_maxDeltaTimeCache = -1.0;
@@ -282,11 +297,14 @@ void DashboardItemFramerate::render(glm::vec2& penPosition) {
FrametimeType frametimeType = FrametimeType(_frametimeType.value());
const std::string output = format(
std::fill(_buffer.begin(), _buffer.end(), 0);
char* end = format(
_buffer,
frametimeType,
_minDeltaTimeCache,
_maxDeltaTimeCache
);
std::string_view output = std::string_view(_buffer.data(), end - _buffer.data());
int nLines = output.empty() ? 0 :
static_cast<int>((std::count(output.begin(), output.end(), '\n') + 1));
@@ -301,8 +319,11 @@ void DashboardItemFramerate::render(glm::vec2& penPosition) {
}
glm::vec2 DashboardItemFramerate::size() const {
ZoneScoped
const FrametimeType t = FrametimeType(_frametimeType.value());
const std::string output = format(t, _minDeltaTimeCache, _maxDeltaTimeCache);
format(_buffer, t, _minDeltaTimeCache, _maxDeltaTimeCache);
std::string_view output = _buffer.data();
if (output.empty()) {
return { 0.f, 0.f };
@@ -68,6 +68,7 @@ private:
double _minDeltaTimeCache = 1.0;
double _maxDeltaTimeCache = -1.0;
bool _shouldClearCache = true;
mutable std::vector<char> _buffer;
};
} // openspace
@@ -33,6 +33,7 @@
#include <ghoul/font/font.h>
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/misc/profiling.h>
#include <stack>
namespace {
@@ -129,6 +130,8 @@ DashboardItemMission::DashboardItemMission(const ghoul::Dictionary& dictionary)
}
void DashboardItemMission::render(glm::vec2& penPosition) {
ZoneScoped
if (!global::missionManager.hasCurrentMission()) {
return;
}
@@ -245,6 +248,8 @@ void DashboardItemMission::render(glm::vec2& penPosition) {
}
glm::vec2 DashboardItemMission::size() const {
ZoneScoped
// @TODO fix this up ---abock
return { 0.f, 0.f };
}
@@ -34,6 +34,7 @@
#include <ghoul/font/font.h>
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/misc/profiling.h>
namespace {
constexpr const char* KeyFontMono = "Mono";
@@ -114,6 +115,8 @@ DashboardItemParallelConnection::DashboardItemParallelConnection(
}
void DashboardItemParallelConnection::render(glm::vec2& penPosition) {
ZoneScoped
const ParallelConnection::Status status = global::parallelPeer.status();
const size_t nConnections = global::parallelPeer.nConnections();
const std::string& hostName = global::parallelPeer.hostName();
@@ -164,6 +167,8 @@ void DashboardItemParallelConnection::render(glm::vec2& penPosition) {
}
glm::vec2 DashboardItemParallelConnection::size() const {
ZoneScoped
ParallelConnection::Status status = global::parallelPeer.status();
size_t nConnections = global::parallelPeer.nConnections();
const std::string& hostName = global::parallelPeer.hostName();
@@ -32,6 +32,7 @@
#include <ghoul/font/font.h>
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/misc/profiling.h>
namespace {
constexpr const char* KeyFontMono = "Mono";
@@ -151,6 +152,8 @@ DashboardItemPropertyValue::DashboardItemPropertyValue(
}
void DashboardItemPropertyValue::render(glm::vec2& penPosition) {
ZoneScoped
if (_propertyIsDirty) {
_property = openspace::property(_propertyUri);
_propertyIsDirty = false;
@@ -166,6 +169,8 @@ void DashboardItemPropertyValue::render(glm::vec2& penPosition) {
}
glm::vec2 DashboardItemPropertyValue::size() const {
ZoneScoped
return _font->boundingBox(_displayString.value());
}
@@ -32,6 +32,7 @@
#include <ghoul/font/font.h>
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/misc/profiling.h>
namespace {
constexpr const char* KeyFontMono = "Mono";
@@ -176,6 +177,8 @@ DashboardItemSimulationIncrement::DashboardItemSimulationIncrement(
}
void DashboardItemSimulationIncrement::render(glm::vec2& penPosition) {
ZoneScoped
const double targetDt = global::timeManager.targetDeltaTime();
const double currentDt = global::timeManager.deltaTime();
std::pair<double, std::string> targetDeltaTime;
@@ -227,6 +230,8 @@ void DashboardItemSimulationIncrement::render(glm::vec2& penPosition) {
}
glm::vec2 DashboardItemSimulationIncrement::size() const {
ZoneScoped
double t = global::timeManager.targetDeltaTime();
std::pair<double, std::string> deltaTime;
if (_doSimplification) {
@@ -38,6 +38,7 @@
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
namespace {
constexpr const char* KeyFontMono = "Mono";
@@ -187,6 +188,8 @@ DashboardItemVelocity::DashboardItemVelocity(const ghoul::Dictionary& dictionary
}
void DashboardItemVelocity::render(glm::vec2& penPosition) {
ZoneScoped
const glm::dvec3 currentPos = global::renderEngine.scene()->camera()->positionVec3();
const glm::dvec3 dt = currentPos - _prevPosition;
const double speedPerFrame = glm::length(dt);
@@ -218,6 +221,8 @@ void DashboardItemVelocity::render(glm::vec2& penPosition) {
}
glm::vec2 DashboardItemVelocity::size() const {
ZoneScoped
const double d = glm::length(1e20);
std::pair<double, std::string> dist;
if (_doSimplification) {
@@ -30,6 +30,7 @@
#include <openspace/rendering/renderengine.h>
#include <openspace/scene/scene.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/misc/profiling.h>
namespace {
constexpr openspace::properties::Property::PropertyInfo IntensityInfo = {
@@ -115,6 +116,8 @@ SceneGraphLightSource::SceneGraphLightSource(const ghoul::Dictionary& dictionary
}
bool SceneGraphLightSource::initialize() {
ZoneScoped
_sceneGraphNode =
global::renderEngine.scene()->sceneGraphNode(_sceneGraphNodeReference);
return _sceneGraphNode != nullptr;
@@ -33,6 +33,7 @@
#include <openspace/documentation/verifier.h>
#include <ghoul/glm.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
namespace {
@@ -189,25 +190,6 @@ void RenderableBoxGrid::render(const RenderData& data, RendererTasks&){
_gridProgram->setUniform("gridColor", _gridColor);
// Saves current state:
GLboolean isBlendEnabled = glIsEnabledi(GL_BLEND, 0);
GLfloat currentLineWidth;
glGetFloatv(GL_LINE_WIDTH, &currentLineWidth);
GLboolean isLineSmoothEnabled = glIsEnabled(GL_LINE_SMOOTH);
GLenum blendEquationRGB;
GLenum blendEquationAlpha;
GLenum blendDestAlpha;
GLenum blendDestRGB;
GLenum blendSrcAlpha;
GLenum blendSrcRGB;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
// Changes GL state:
glLineWidth(_lineWidth);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -221,17 +203,8 @@ void RenderableBoxGrid::render(const RenderData& data, RendererTasks&){
_gridProgram->deactivate();
// Restores GL State
glLineWidth(currentLineWidth);
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
if (!isBlendEnabled) {
glDisablei(GL_BLEND, 0);
}
if (!isLineSmoothEnabled) {
glDisable(GL_LINE_SMOOTH);
}
global::renderEngine.openglStateCache().resetBlendState();
global::renderEngine.openglStateCache().resetLineState();
}
void RenderableBoxGrid::update(const UpdateData&) {
@@ -33,6 +33,7 @@
#include <openspace/util/updatestructures.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/glm.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
namespace {
@@ -205,25 +206,6 @@ void RenderableGrid::render(const RenderData& data, RendererTasks&){
_gridProgram->setUniform("gridColor", _gridColor);
// Saves current state:
GLboolean isBlendEnabled = glIsEnabledi(GL_BLEND, 0);
GLfloat currentLineWidth;
glGetFloatv(GL_LINE_WIDTH, &currentLineWidth);
GLboolean isLineSmoothEnabled = glIsEnabled(GL_LINE_SMOOTH);
GLenum blendEquationRGB;
GLenum blendEquationAlpha;
GLenum blendDestAlpha;
GLenum blendDestRGB;
GLenum blendSrcAlpha;
GLenum blendSrcRGB;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
// Changes GL state:
glLineWidth(_lineWidth);
glEnablei(GL_BLEND, 0);
@@ -237,17 +219,8 @@ void RenderableGrid::render(const RenderData& data, RendererTasks&){
_gridProgram->deactivate();
// Restores GL State
glLineWidth(currentLineWidth);
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
if (!isBlendEnabled) {
glDisablei(GL_BLEND, 0);
}
if (!isLineSmoothEnabled) {
glDisable(GL_LINE_SMOOTH);
}
global::renderEngine.openglStateCache().resetBlendState();
global::renderEngine.openglStateCache().resetLineState();
}
void RenderableGrid::update(const UpdateData&) {
@@ -33,6 +33,7 @@
#include <openspace/documentation/verifier.h>
#include <ghoul/glm.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
namespace {
@@ -266,25 +267,6 @@ void RenderableRadialGrid::render(const RenderData& data, RendererTasks&) {
adjustedLineWidth = _lineWidth;
#endif
// Saves current state:
GLboolean isBlendEnabled = glIsEnabledi(GL_BLEND, 0);
GLfloat currentLineWidth;
glGetFloatv(GL_LINE_WIDTH, &currentLineWidth);
GLboolean isLineSmoothEnabled = glIsEnabled(GL_LINE_SMOOTH);
GLenum blendEquationRGB;
GLenum blendEquationAlpha;
GLenum blendDestAlpha;
GLenum blendDestRGB;
GLenum blendSrcAlpha;
GLenum blendSrcRGB;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
// Changes GL state:
glLineWidth(adjustedLineWidth);
glEnablei(GL_BLEND, 0);
@@ -300,17 +282,8 @@ void RenderableRadialGrid::render(const RenderData& data, RendererTasks&) {
_gridProgram->deactivate();
// Restores GL State
glLineWidth(currentLineWidth);
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
if (!isBlendEnabled) {
glDisablei(GL_BLEND, 0);
}
if (!isLineSmoothEnabled) {
glDisable(GL_LINE_SMOOTH);
}
global::renderEngine.openglStateCache().resetBlendState();
global::renderEngine.openglStateCache().resetLineState();
}
void RenderableRadialGrid::update(const UpdateData&) {
@@ -32,6 +32,7 @@
#include <openspace/documentation/verifier.h>
#include <ghoul/glm.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
namespace {
@@ -209,25 +210,6 @@ void RenderableSphericalGrid::render(const RenderData& data, RendererTasks&){
adjustedLineWidth = _lineWidth;
#endif
// Saves current state:
GLboolean isBlendEnabled = glIsEnabledi(GL_BLEND, 0);
GLfloat currentLineWidth;
glGetFloatv(GL_LINE_WIDTH, &currentLineWidth);
GLboolean isLineSmoothEnabled = glIsEnabled(GL_LINE_SMOOTH);
GLenum currentDepthFunction;
glGetIntegerv(GL_DEPTH_FUNC, &currentDepthFunction);
glDepthFunc(GL_LEQUAL);
GLenum blendEquationRGB, blendEquationAlpha, blendDestAlpha,
blendDestRGB, blendSrcAlpha, blendSrcRGB;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
// Changes GL state:
glLineWidth(adjustedLineWidth);
glEnablei(GL_BLEND, 0);
@@ -242,19 +224,8 @@ void RenderableSphericalGrid::render(const RenderData& data, RendererTasks&){
_gridProgram->deactivate();
// Restores GL State
glLineWidth(currentLineWidth);
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
if (!isBlendEnabled) {
glDisablei(GL_BLEND, 0);
}
if (!isLineSmoothEnabled) {
glDisable(GL_LINE_SMOOTH);
}
glDepthFunc(currentDepthFunction);
global::renderEngine.openglStateCache().resetBlendState();
global::renderEngine.openglStateCache().resetLineState();
}
void RenderableSphericalGrid::update(const UpdateData&) {
+50 -7
View File
@@ -25,14 +25,18 @@
#include <modules/base/rendering/modelgeometry.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/rendering/renderable.h>
#include <openspace/util/factorymanager.h>
#include <openspace/util/memorymanager.h>
#include <ghoul/filesystem/cachemanager.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/invariants.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/misc/templatefactory.h>
#include <fstream>
@@ -41,6 +45,7 @@ namespace {
constexpr const char* KeyType = "Type";
constexpr const char* KeyGeomModelFile = "GeometryFile";
constexpr const char* KeyColorTexture = "ColorTexture";
constexpr const int8_t CurrentCacheVersion = 3;
} // namespace
@@ -65,13 +70,20 @@ documentation:: Documentation ModelGeometry::Documentation() {
"The file that should be loaded in this ModelGeometry. The file can "
"contain filesystem tokens or can be specified relatively to the "
"location of the .mod file."
},
{
KeyColorTexture,
new StringVerifier,
Optional::Yes,
"This value points to a color texture file that is applied to the "
"geometry rendered in this object."
}
}
};
}
std::unique_ptr<ModelGeometry> ModelGeometry::createFromDictionary(
// Create with ghoul::mm_unique_ptr
ghoul::mm_unique_ptr<ModelGeometry> ModelGeometry::createFromDictionary(
const ghoul::Dictionary& dictionary)
{
if (!dictionary.hasKeyAndValue<std::string>(KeyType)) {
@@ -81,13 +93,15 @@ std::unique_ptr<ModelGeometry> ModelGeometry::createFromDictionary(
const std::string& geometryType = dictionary.value<std::string>(KeyType);
auto factory = FactoryManager::ref().factory<ModelGeometry>();
ModelGeometry* geometry = factory->create(geometryType, dictionary);
return std::unique_ptr<ModelGeometry>(geometry);
ModelGeometry* geometry = factory->create(
geometryType,
dictionary,
&global::memoryManager.PersistentMemory
);
return ghoul::mm_unique_ptr<ModelGeometry>(geometry);
}
ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary)
: properties::PropertyOwner({ "ModelGeometry" })
{
ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary) {
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
@@ -95,12 +109,22 @@ ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary)
);
_file = absPath(dictionary.value<std::string>(KeyGeomModelFile));
if (dictionary.hasKey(KeyColorTexture)) {
_colorTexturePath = absPath(dictionary.value<std::string>(KeyColorTexture));
}
}
double ModelGeometry::boundingRadius() const {
return _boundingRadius;
}
void ModelGeometry::bindTexture() {
if (_texture) {
_texture->bind();
}
}
void ModelGeometry::render() {
glBindVertexArray(_vaoID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
@@ -118,6 +142,8 @@ void ModelGeometry::changeRenderMode(GLenum mode) {
}
bool ModelGeometry::initialize(Renderable* parent) {
ZoneScoped
float maximumDistanceSquared = 0;
for (const Vertex& v : _vertices) {
maximumDistanceSquared = glm::max(
@@ -176,6 +202,21 @@ bool ModelGeometry::initialize(Renderable* parent) {
glBindVertexArray(0);
if (!_colorTexturePath.empty()) {
_texture = ghoul::io::TextureReader::ref().loadTexture(
absPath(_colorTexturePath)
);
if (_texture) {
LDEBUGC(
"RenderableModel",
fmt::format("Loaded texture from '{}'", absPath(_colorTexturePath))
);
_texture->uploadTexture();
_texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_texture->purgeFromRAM();
}
}
return true;
}
@@ -183,6 +224,8 @@ void ModelGeometry::deinitialize() {
glDeleteBuffers(1, &_vbo);
glDeleteVertexArrays(1, &_vaoID);
glDeleteBuffers(1, &_ibo);
_texture = nullptr;
}
bool ModelGeometry::loadObj(const std::string& filename) {
+7 -4
View File
@@ -25,9 +25,9 @@
#ifndef __OPENSPACE_MODULE_BASE___MODELGEOMETRY___H__
#define __OPENSPACE_MODULE_BASE___MODELGEOMETRY___H__
#include <openspace/properties/propertyowner.h>
#include <ghoul/misc/managedmemoryuniqueptr.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/texture.h>
#include <memory>
namespace ghoul { class Dictionary; }
@@ -38,7 +38,7 @@ namespace openspace::documentation { struct Documentation; }
namespace openspace::modelgeometry {
class ModelGeometry : public properties::PropertyOwner {
class ModelGeometry {
public:
struct Vertex {
GLfloat location[4];
@@ -46,7 +46,7 @@ public:
GLfloat normal[3];
};
static std::unique_ptr<ModelGeometry> createFromDictionary(
static ghoul::mm_unique_ptr<ModelGeometry> createFromDictionary(
const ghoul::Dictionary& dictionary
);
@@ -55,6 +55,7 @@ public:
virtual bool initialize(Renderable* parent);
virtual void deinitialize();
void bindTexture();
void render();
virtual bool loadModel(const std::string& filename) = 0;
@@ -79,6 +80,8 @@ protected:
GLenum _mode = GL_TRIANGLES;
double _boundingRadius = 0.0;
std::string _colorTexturePath;
std::unique_ptr<ghoul::opengl::Texture> _texture;
std::vector<Vertex> _vertices;
std::vector<int> _indices;
@@ -32,6 +32,7 @@
#include <openspace/documentation/verifier.h>
#include <ghoul/glm.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
namespace {
@@ -233,21 +234,6 @@ void RenderableCartesianAxes::render(const RenderData& data, RendererTasks&){
_program->setUniform("yColor", _yColor);
_program->setUniform("zColor", _zColor);
// Saves current state:
GLboolean isBlendEnabled = glIsEnabledi(GL_BLEND, 0);
GLboolean isLineSmoothEnabled = glIsEnabled(GL_LINE_SMOOTH);
GLfloat currentLineWidth;
glGetFloatv(GL_LINE_WIDTH, &currentLineWidth);
GLenum blendEquationRGB, blendEquationAlpha, blendDestAlpha,
blendDestRGB, blendSrcAlpha, blendSrcRGB;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
// Changes GL state:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnablei(GL_BLEND, 0);
@@ -261,15 +247,8 @@ void RenderableCartesianAxes::render(const RenderData& data, RendererTasks&){
_program->deactivate();
// Restores GL State
glLineWidth(currentLineWidth);
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
if (!isBlendEnabled) {
glDisablei(GL_BLEND, 0);
}
if (!isLineSmoothEnabled) {
glDisable(GL_LINE_SMOOTH);
}
global::renderEngine.openglStateCache().resetBlendState();
global::renderEngine.openglStateCache().resetLineState();
}
} // namespace openspace
@@ -40,6 +40,7 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/crc32.h>
#include <ghoul/misc/defer.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/misc/templatefactory.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
@@ -604,6 +605,8 @@ bool RenderableLabels::isReady() const {
}
void RenderableLabels::initialize() {
ZoneScoped
bool success = true;// loadData();
if (!success) {
throw ghoul::RuntimeError("Error loading objects labels data.");
+37 -81
View File
@@ -36,11 +36,10 @@
#include <openspace/scene/lightsource.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/misc/invariants.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/invariants.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
namespace {
@@ -54,13 +53,6 @@ namespace {
"specularIntensity"
};
constexpr openspace::properties::Property::PropertyInfo TextureInfo = {
"ColorTexture",
"Color Texture",
"This value points to a color texture file that is applied to the geometry "
"rendered in this object."
};
constexpr openspace::properties::Property::PropertyInfo AmbientIntensityInfo = {
"AmbientIntensity",
"Ambient Intensity",
@@ -122,16 +114,16 @@ documentation::Documentation RenderableModel::Documentation() {
{
{
KeyGeometry,
new ReferencingVerifier("base_geometry_model"),
new TableVerifier({
{
"*",
new ReferencingVerifier("base_geometry_model"),
Optional::Yes
}
}),
Optional::No,
"This specifies the model that is rendered by the Renderable."
},
{
TextureInfo.identifier,
new StringVerifier,
Optional::Yes,
TextureInfo.description
},
{
AmbientIntensityInfo.identifier,
new DoubleVerifier,
@@ -192,7 +184,6 @@ documentation::Documentation RenderableModel::Documentation() {
RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _colorTexturePath(TextureInfo)
, _ambientIntensity(AmbientIntensityInfo, 0.2f, 0.f, 1.f)
, _diffuseIntensity(DiffuseIntensityInfo, 1.f, 0.f, 1.f)
, _specularIntensity(SpecularIntensityInfo, 1.f, 0.f, 1.f)
@@ -219,13 +210,11 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
if (dictionary.hasKey(KeyGeometry)) {
ghoul::Dictionary dict = dictionary.value<ghoul::Dictionary>(KeyGeometry);
_geometry = modelgeometry::ModelGeometry::createFromDictionary(dict);
}
if (dictionary.hasKey(TextureInfo.identifier)) {
_colorTexturePath = absPath(dictionary.value<std::string>(
TextureInfo.identifier
));
for (int i = 1; i <= dict.size(); ++i) {
std::string key = std::to_string(i);
ghoul::Dictionary geom = dict.value<ghoul::Dictionary>(key);
_geometry.push_back(modelgeometry::ModelGeometry::createFromDictionary(geom));
}
}
if (dictionary.hasKey(ModelTransformInfo.identifier)) {
@@ -265,11 +254,6 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
addPropertySubOwner(_lightSourcePropertyOwner);
addPropertySubOwner(_geometry.get());
addProperty(_colorTexturePath);
_colorTexturePath.onChange(std::bind(&RenderableModel::loadTexture, this));
addProperty(_ambientIntensity);
addProperty(_diffuseIntensity);
@@ -290,16 +274,20 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
}
bool RenderableModel::isReady() const {
return _program && _texture;
return _program;
}
void RenderableModel::initialize() {
ZoneScoped
for (const std::unique_ptr<LightSource>& ls : _lightSources) {
ls->initialize();
}
}
void RenderableModel::initializeGL() {
ZoneScoped
_program = BaseModule::ProgramObjectManager.request(
ProgramName,
[]() -> std::unique_ptr<ghoul::opengl::ProgramObject> {
@@ -313,17 +301,16 @@ void RenderableModel::initializeGL() {
ghoul::opengl::updateUniformLocations(*_program, _uniformCache, UniformNames);
loadTexture();
_geometry->initialize(this);
for (const ghoul::mm_unique_ptr<modelgeometry::ModelGeometry>& geom : _geometry) {
geom->initialize(this);
}
}
void RenderableModel::deinitializeGL() {
if (_geometry) {
_geometry->deinitialize();
_geometry = nullptr;
for (const ghoul::mm_unique_ptr<modelgeometry::ModelGeometry>& geom : _geometry) {
geom->deinitialize();
}
_texture = nullptr;
_geometry.clear();
BaseModule::ProgramObjectManager.release(
ProgramName,
@@ -395,37 +382,23 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
_uniformCache.projectionTransform,
data.camera.projectionMatrix()
);
_program->setUniform(
_uniformCache.ambientIntensity,
_ambientIntensity
);
_program->setUniform(
_uniformCache.diffuseIntensity,
_diffuseIntensity
);
_program->setUniform(
_uniformCache.specularIntensity,
_specularIntensity
);
_program->setUniform(
_uniformCache.performShading,
_performShading
);
_geometry->setUniforms(*_program);
// Bind texture
ghoul::opengl::TextureUnit unit;
unit.activate();
_texture->bind();
_program->setUniform(_uniformCache.texture, unit);
_program->setUniform(_uniformCache.ambientIntensity, _ambientIntensity);
_program->setUniform(_uniformCache.diffuseIntensity, _diffuseIntensity);
_program->setUniform(_uniformCache.specularIntensity, _specularIntensity);
_program->setUniform(_uniformCache.performShading, _performShading);
if (_disableFaceCulling) {
glDisable(GL_CULL_FACE);
}
_geometry->render();
ghoul::opengl::TextureUnit unit;
unit.activate();
_program->setUniform(_uniformCache.texture, unit);
for (const ghoul::mm_unique_ptr<modelgeometry::ModelGeometry>& geom : _geometry) {
geom->setUniforms(*_program);
geom->bindTexture();
geom->render();
}
if (_disableFaceCulling) {
glEnable(GL_CULL_FACE);
}
@@ -440,21 +413,4 @@ void RenderableModel::update(const UpdateData&) {
}
}
void RenderableModel::loadTexture() {
_texture = nullptr;
if (!_colorTexturePath.value().empty()) {
_texture = ghoul::io::TextureReader::ref().loadTexture(
absPath(_colorTexturePath)
);
if (_texture) {
LDEBUGC(
"RenderableModel",
fmt::format("Loaded texture from '{}'", absPath(_colorTexturePath))
);
_texture->uploadTexture();
_texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
}
}
}
} // namespace openspace
+4 -12
View File
@@ -27,16 +27,14 @@
#include <openspace/rendering/renderable.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/matrix/dmat4property.h>
#include <openspace/properties/matrix/mat3property.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/vector/vec3property.h>
#include <ghoul/misc/managedmemoryuniqueptr.h>
#include <ghoul/opengl/uniformcache.h>
#include <memory>
#include <openspace/properties/matrix/dmat4property.h>
#include <openspace/properties/vector/vec3property.h>
namespace ghoul::opengl {
class ProgramObject;
@@ -68,13 +66,8 @@ public:
static documentation::Documentation Documentation();
protected:
void loadTexture();
private:
std::unique_ptr<modelgeometry::ModelGeometry> _geometry;
properties::StringProperty _colorTexturePath;
std::vector<ghoul::mm_unique_ptr<modelgeometry::ModelGeometry>> _geometry;
properties::FloatProperty _ambientIntensity;
@@ -92,7 +85,6 @@ private:
performShading, texture, ambientIntensity, diffuseIntensity,
specularIntensity) _uniformCache;
std::unique_ptr<ghoul::opengl::Texture> _texture;
std::vector<std::unique_ptr<LightSource>> _lightSources;
// Buffers for uniform uploading
+3 -28
View File
@@ -35,6 +35,7 @@
#include <openspace/util/updatestructures.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
namespace {
@@ -290,25 +291,6 @@ void RenderableNodeLine::render(const RenderData& data, RendererTasks&) {
_program->setUniform("projectionTransform", data.camera.projectionMatrix());
_program->setUniform("color", glm::vec4(_lineColor.value(), _opacity));
// Save current state:
GLboolean isBlendEnabled = glIsEnabledi(GL_BLEND, 0);
GLboolean isLineSmoothEnabled = glIsEnabled(GL_LINE_SMOOTH);
GLfloat currentLineWidth;
glGetFloatv(GL_LINE_WIDTH, &currentLineWidth);
GLenum blendEquationRGB;
GLenum blendEquationAlpha;
GLenum blendDestAlpha;
GLenum blendDestRGB;
GLenum blendSrcAlpha;
GLenum blendSrcRGB;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
// Change GL state:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnablei(GL_BLEND, 0);
@@ -322,15 +304,8 @@ void RenderableNodeLine::render(const RenderData& data, RendererTasks&) {
// Restore GL State
unbindGL();
_program->deactivate();
glLineWidth(currentLineWidth);
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
if (!isBlendEnabled) {
glDisablei(GL_BLEND, 0);
}
if (!isLineSmoothEnabled) {
glDisable(GL_LINE_SMOOTH);
}
global::renderEngine.openglStateCache().resetBlendState();
global::renderEngine.openglStateCache().resetLineState();
}
void RenderableNodeLine::validateNodes() {
+9 -1
View File
@@ -34,6 +34,7 @@
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/misc/defer.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -166,6 +167,8 @@ bool RenderablePlane::isReady() const {
}
void RenderablePlane::initializeGL() {
ZoneScoped
glGenVertexArrays(1, &_quad); // generate array
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
createPlane();
@@ -183,6 +186,8 @@ void RenderablePlane::initializeGL() {
}
void RenderablePlane::deinitializeGL() {
ZoneScoped
glDeleteVertexArrays(1, &_quad);
_quad = 0;
@@ -199,8 +204,9 @@ void RenderablePlane::deinitializeGL() {
}
void RenderablePlane::render(const RenderData& data, RendererTasks&) {
_shader->activate();
ZoneScoped
_shader->activate();
_shader->setUniform("opacity", _opacity);
glm::dvec3 objectPositionWorld = glm::dvec3(
@@ -277,6 +283,8 @@ void RenderablePlane::bindTexture() {}
void RenderablePlane::unbindTexture() {}
void RenderablePlane::update(const UpdateData&) {
ZoneScoped
if (_shader->isDirty()) {
_shader->rebuildFromFile();
}
@@ -32,6 +32,7 @@
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/crc32.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/texture.h>
#include <fstream>
@@ -172,6 +173,8 @@ void RenderablePlaneImageLocal::bindTexture() {
}
void RenderablePlaneImageLocal::update(const UpdateData& data) {
ZoneScoped
RenderablePlane::update(data);
if (_textureIsDirty) {
@@ -181,6 +184,8 @@ void RenderablePlaneImageLocal::update(const UpdateData& data) {
}
void RenderablePlaneImageLocal::loadTexture() {
ZoneScoped
if (!_texturePath.value().empty()) {
ghoul::opengl::Texture* t = _texture;
@@ -488,6 +488,7 @@ void RenderableSphere::loadTexture() {
);
texture->uploadTexture();
texture->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap);
texture->purgeFromRAM();
_texture = std::move(texture);
}
}
@@ -282,6 +282,8 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary)
}
void RenderableTrail::initializeGL() {
ZoneScoped
#ifdef __APPLE__
_programObject = BaseModule::ProgramObjectManager.request(
ProgramName,
@@ -29,6 +29,7 @@
#include <openspace/engine/windowdelegate.h>
#include <openspace/rendering/renderengine.h>
#include <ghoul/opengl/framebufferobject.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/textureunit.h>
namespace {
@@ -111,13 +112,16 @@ void ScreenSpaceFramebuffer::render() {
if (!_renderFunctions.empty()) {
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
//glGetIntegerv(GL_VIEWPORT, viewport);
global::renderEngine.openglStateCache().viewport(viewport);
glViewport(
static_cast<GLint>(-size.x * xratio),
static_cast<GLint>(-size.y * yratio),
static_cast<GLsizei>(resolution.x * xratio),
static_cast<GLsizei>(resolution.y * yratio)
);
global::renderEngine.openglStateCache().setViewportState(viewport);
GLint defaultFBO = _framebuffer->getActiveObject();
_framebuffer->activate();
@@ -180,6 +184,7 @@ void ScreenSpaceFramebuffer::createFramebuffer() {
_texture->uploadTexture();
_texture->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap);
_texture->purgeFromRAM();
_framebuffer->attachTexture(_texture.get(), GL_COLOR_ATTACHMENT0);
_framebuffer->deactivate();
}
@@ -132,10 +132,8 @@ void ScreenSpaceImageLocal::update() {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
texture->uploadTexture();
// Textures of planets looks much smoother with AnisotropicMipMap rather than
// linear
texture->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap);
texture->purgeFromRAM();
_texture = std::move(texture);
_objectSize = _texture->dimensions();
@@ -142,10 +142,8 @@ void ScreenSpaceImageOnline::update() {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
texture->uploadTexture();
// Textures of planets looks much smoother with AnisotropicMipMap rather
// than linear
texture->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap);
texture->purgeFromRAM();
_texture = std::move(texture);
_objectSize = _texture->dimensions();
+3
View File
@@ -31,6 +31,7 @@
#include <ghoul/fmt.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/assert.h>
#include <ghoul/misc/profiling.h>
#include <string>
namespace {
@@ -444,6 +445,8 @@ FixedRotation::FixedRotation(const ghoul::Dictionary& dictionary)
}
bool FixedRotation::initialize() {
ZoneScoped
// We need to do this in the initialize and not the constructor as the scene graph
// nodes referenced in the dictionary might not exist yet at construction time. At
// initialization time, however, we know that they already have been created
@@ -37,6 +37,8 @@
#include <ghoul/misc/templatefactory.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -701,6 +703,8 @@ bool RenderableBillboardsCloud::isReady() const {
}
void RenderableBillboardsCloud::initialize() {
ZoneScoped
bool success = loadData();
if (!success) {
throw ghoul::RuntimeError("Error loading data");
@@ -716,6 +720,8 @@ void RenderableBillboardsCloud::initialize() {
}
void RenderableBillboardsCloud::initializeGL() {
ZoneScoped
_program = DigitalUniverseModule::ProgramObjectManager.request(
ProgramObjectName,
[]() {
@@ -792,28 +798,6 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data,
float fadeInVariable)
{
glDepthMask(false);
glEnable(GL_DEPTH_TEST);
// Saving current OpenGL state
GLboolean blendEnabled = glIsEnabledi(GL_BLEND, 0);
GLenum blendEquationRGB;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
GLenum blendEquationAlpha;
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
GLenum blendDestAlpha;
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
GLenum blendDestRGB;
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
GLenum blendSrcAlpha;
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
GLenum blendSrcRGB;
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
glEnablei(GL_BLEND, 0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
@@ -881,15 +865,8 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data,
glBindVertexArray(0);
_program->deactivate();
// Restores blending state
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
if (!blendEnabled) {
glDisablei(GL_BLEND, 0);
}
glDepthMask(true);
global::renderEngine.openglStateCache().resetBlendState();
global::renderEngine.openglStateCache().resetDepthState();
}
@@ -1043,7 +1020,11 @@ void RenderableBillboardsCloud::render(const RenderData& data, RendererTasks&) {
}
void RenderableBillboardsCloud::update(const UpdateData&) {
ZoneScoped
if (_dataIsDirty && _hasSpeckFile) {
ZoneScopedN("Data dirty")
TracyGpuZone("Data dirty")
LDEBUG("Regenerating data");
createDataSlice();
@@ -1165,6 +1146,9 @@ void RenderableBillboardsCloud::update(const UpdateData&) {
if (_hasSpriteTexture && _spriteTextureIsDirty && !_spriteTexturePath.value().empty())
{
ZoneScopedN("Sprite texture")
TracyGpuZone("Sprite texture")
ghoul::opengl::Texture* t = _spriteTexture;
unsigned int hash = ghoul::hashCRC32File(_spriteTexturePath);
@@ -1177,6 +1161,7 @@ void RenderableBillboardsCloud::update(const UpdateData&) {
ghoul::io::TextureReader::ref().loadTexture(absPath(path));
t->uploadTexture();
t->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
t->purgeFromRAM();
return t;
}
);
@@ -1613,6 +1598,8 @@ bool RenderableBillboardsCloud::saveCachedFile(const std::string& file) const {
}
void RenderableBillboardsCloud::createDataSlice() {
ZoneScoped
_slicedData.clear();
if (_hasColorMapFile) {
_slicedData.reserve(8 * (_fullData.size() / _nValuesPerAstronomicalObject));
@@ -1714,6 +1701,8 @@ void RenderableBillboardsCloud::createDataSlice() {
}
void RenderableBillboardsCloud::createPolygonTexture() {
ZoneScoped
LDEBUG("Creating Polygon Texture");
glGenTextures(1, &_pTexture);
@@ -38,6 +38,7 @@
#include <ghoul/misc/templatefactory.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -401,30 +402,6 @@ void RenderableDUMeshes::renderMeshes(const RenderData&,
const glm::dmat4& modelViewMatrix,
const glm::dmat4& projectionMatrix)
{
// Saving current OpenGL state
GLfloat lineWidth = 1.0f;
glGetFloatv(GL_LINE_WIDTH, &lineWidth);
GLboolean blendEnabled = glIsEnabledi(GL_BLEND, 0);
GLenum blendEquationRGB;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
GLenum blendEquationAlpha;
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
GLenum blendDestAlpha;
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
GLenum blendDestRGB;
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
GLenum blendSrcAlpha;
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
GLenum blendSrcRGB;
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
glEnablei(GL_BLEND, 0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -447,7 +424,7 @@ void RenderableDUMeshes::renderMeshes(const RenderData&,
case Wire:
glLineWidth(_lineWidth);
glDrawArrays(GL_LINE_STRIP, 0, pair.second.numV);
glLineWidth(lineWidth);
global::renderEngine.openglStateCache().resetLineState();
break;
case Point:
glDrawArrays(GL_POINTS, 0, pair.second.numV);
@@ -461,15 +438,9 @@ void RenderableDUMeshes::renderMeshes(const RenderData&,
glBindVertexArray(0);
_program->deactivate();
// Restores blending state
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
glDepthMask(true);
if (!blendEnabled) {
glDisablei(GL_BLEND, 0);
}
// Restores GL State
global::renderEngine.openglStateCache().resetDepthState();
global::renderEngine.openglStateCache().resetBlendState();
}
void RenderableDUMeshes::renderLabels(const RenderData& data,
@@ -35,6 +35,8 @@
#include <ghoul/font/fontrenderer.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -478,6 +480,8 @@ bool RenderablePlanesCloud::isReady() const {
}
void RenderablePlanesCloud::initialize() {
ZoneScoped
const bool success = loadData();
if (!success) {
throw ghoul::RuntimeError("Error loading data");
@@ -485,6 +489,8 @@ void RenderablePlanesCloud::initialize() {
}
void RenderablePlanesCloud::initializeGL() {
ZoneScoped
_program = DigitalUniverseModule::ProgramObjectManager.request(
ProgramObjectName,
[]() -> std::unique_ptr<ghoul::opengl::ProgramObject> {
@@ -541,27 +547,6 @@ void RenderablePlanesCloud::renderPlanes(const RenderData&,
const glm::dmat4& projectionMatrix,
const float fadeInVariable)
{
// Saving current OpenGL state
GLboolean blendEnabled = glIsEnabledi(GL_BLEND, 0);
GLenum blendEquationRGB;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
GLenum blendEquationAlpha;
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
GLenum blendDestAlpha;
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
GLenum blendDestRGB;
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
GLenum blendSrcAlpha;
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
GLenum blendSrcRGB;
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
glEnablei(GL_BLEND, 0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -604,15 +589,9 @@ void RenderablePlanesCloud::renderPlanes(const RenderData&,
glBindVertexArray(0);
_program->deactivate();
// Restores blending state
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
glDepthMask(true);
if (!blendEnabled) {
glDisablei(GL_BLEND, 0);
}
// Restores OpenGL Rendering State
global::renderEngine.openglStateCache().resetBlendState();
global::renderEngine.openglStateCache().resetDepthState();
}
void RenderablePlanesCloud::renderLabels(const RenderData& data,
@@ -857,6 +836,7 @@ bool RenderablePlanesCloud::loadTextures() {
p.first->second->setFilter(
ghoul::opengl::Texture::FilterMode::LinearMipMap
);
p.first->second->purgeFromRAM();
}
}
}
@@ -34,6 +34,7 @@
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/misc/templatefactory.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
@@ -235,6 +236,8 @@ bool RenderablePoints::isReady() const {
}
void RenderablePoints::initialize() {
ZoneScoped
bool success = loadData();
if (!success) {
throw ghoul::RuntimeError("Error loading data");
@@ -242,6 +245,8 @@ void RenderablePoints::initialize() {
}
void RenderablePoints::initializeGL() {
ZoneScoped
// OBS: The ProgramObject name is later used to release the program as well, so the
// name parameter to requestProgramObject and the first parameter to
// buildRenderProgram has to be the same or an assertion will be thrown at the
@@ -245,7 +245,7 @@ bool FieldlinesState::loadStateFromJson(const std::string& pathToJsonFile,
*/
void FieldlinesState::saveStateToOsfls(const std::string& absPath) {
// ------------------------------- Create the file ------------------------------- //
std::string pathSafeTimeString = Time(_triggerTime).ISO8601();
std::string pathSafeTimeString = std::string(Time(_triggerTime).ISO8601());
pathSafeTimeString.replace(13, 1, "-");
pathSafeTimeString.replace(16, 1, "-");
pathSafeTimeString.replace(19, 1, "-");
@@ -341,7 +341,7 @@ void FieldlinesState::saveStateToJson(const std::string& absPath) {
json jFile;
const std::string timeStr = Time(_triggerTime).ISO8601();
std::string_view timeStr = Time(_triggerTime).ISO8601();
const size_t nLines = _lineStart.size();
// const size_t nPoints = _vertexPositions.size();
const size_t nExtras = _extraQuantities.size();
@@ -27,6 +27,7 @@
#include <openspace/rendering/renderable.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/textureunit.h>
#include <ghoul/opengl/texture.h>
@@ -49,6 +50,8 @@ GalaxyRaycaster::GalaxyRaycaster(ghoul::opengl::Texture& texture)
{}
void GalaxyRaycaster::initialize() {
ZoneScoped
_boundingBox.initialize();
}
+100 -111
View File
@@ -40,7 +40,9 @@
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -327,41 +329,6 @@ RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary)
else {
LERROR("No points filename specified.");
}
}
void RenderableGalaxy::initializeGL() {
// Aspect is currently hardcoded to cubic voxels.
_aspect = static_cast<glm::vec3>(_volumeDimensions);
_aspect /= std::max(std::max(_aspect.x, _aspect.y), _aspect.z);
// The volume
volume::RawVolumeReader<glm::tvec4<GLubyte>> reader(
_volumeFilename,
_volumeDimensions
);
_volume = reader.read();
_texture = std::make_unique<ghoul::opengl::Texture>(
_volumeDimensions,
ghoul::opengl::Texture::Format::RGBA,
GL_RGBA,
GL_UNSIGNED_BYTE,
ghoul::opengl::Texture::FilterMode::Linear,
ghoul::opengl::Texture::WrappingMode::ClampToEdge
);
_texture->setPixelData(
reinterpret_cast<char*>(_volume->data()),
ghoul::opengl::Texture::TakeOwnership::No
);
_texture->setDimensions(_volume->dimensions());
_texture->uploadTexture();
_raycaster = std::make_unique<GalaxyRaycaster>(*_texture);
_raycaster->initialize();
global::raycasterManager.attachRaycaster(*_raycaster);
auto onChange = [&](bool enabled) {
if (enabled) {
@@ -385,6 +352,95 @@ void RenderableGalaxy::initializeGL() {
addProperty(_rotation);
addProperty(_downScaleVolumeRendering);
addProperty(_numberOfRayCastingSteps);
}
void RenderableGalaxy::initialize() {
ZoneScoped
// Aspect is currently hardcoded to cubic voxels.
_aspect = static_cast<glm::vec3>(_volumeDimensions);
_aspect /= std::max(std::max(_aspect.x, _aspect.y), _aspect.z);
// The volume
volume::RawVolumeReader<glm::tvec4<GLubyte>> reader(
_volumeFilename,
_volumeDimensions
);
_volume = reader.read();
std::string cachedPointsFile = FileSys.cacheManager()->cachedFilename(
_pointsFilename,
ghoul::filesystem::CacheManager::Persistent::Yes
);
const bool hasCachedFile = FileSys.fileExists(cachedPointsFile);
if (hasCachedFile) {
LINFO(fmt::format("Cached file '{}' used for galaxy point file '{}'",
cachedPointsFile, _pointsFilename
));
Result res = loadCachedFile(cachedPointsFile);
if (res.success) {
_pointPositionsCache = std::move(res.positions);
_pointColorsCache = std::move(res.color);
}
else {
FileSys.cacheManager()->removeCacheFile(_pointsFilename);
Result resPoint = loadPointFile(_pointsFilename);
_pointPositionsCache = std::move(resPoint.positions);
_pointColorsCache = std::move(resPoint.color);
saveCachedFile(
cachedPointsFile,
_pointPositionsCache,
_pointColorsCache,
_nPoints,
_enabledPointsRatio
);
}
}
else {
Result res = loadPointFile(_pointsFilename);
ghoul_assert(res.success, "Point file loading failed");
_pointPositionsCache = std::move(res.positions);
_pointColorsCache = std::move(res.color);
saveCachedFile(
cachedPointsFile,
_pointPositionsCache,
_pointColorsCache,
_nPoints,
_enabledPointsRatio
);
}
}
void RenderableGalaxy::initializeGL() {
ZoneScoped
_texture = std::make_unique<ghoul::opengl::Texture>(
_volumeDimensions,
ghoul::opengl::Texture::Format::RGBA,
GL_RGBA,
GL_UNSIGNED_BYTE,
ghoul::opengl::Texture::FilterMode::Linear,
ghoul::opengl::Texture::WrappingMode::ClampToEdge,
ghoul::opengl::Texture::AllocateData::No,
ghoul::opengl::Texture::TakeOwnership::No
);
_texture->setPixelData(
reinterpret_cast<char*>(_volume->data()),
ghoul::opengl::Texture::TakeOwnership::No
);
_texture->setDimensions(_volume->dimensions());
_texture->uploadTexture();
_raycaster = std::make_unique<GalaxyRaycaster>(*_texture);
_raycaster->initialize();
// We no longer need the data
_volume = nullptr;
global::raycasterManager.attachRaycaster(*_raycaster);
// initialize points.
if (_pointsFilename.empty()) {
@@ -442,53 +498,6 @@ void RenderableGalaxy::initializeGL() {
GLint positionAttrib = _pointsProgram->attributeLocation("in_position");
GLint colorAttrib = _pointsProgram->attributeLocation("in_color");
std::vector<glm::vec3> pointPositions;
std::vector<glm::vec3> pointColors;
std::string cachedPointsFile = FileSys.cacheManager()->cachedFilename(
_pointsFilename,
ghoul::filesystem::CacheManager::Persistent::Yes
);
const bool hasCachedFile = FileSys.fileExists(cachedPointsFile);
if (hasCachedFile) {
LINFO(fmt::format("Cached file '{}' used for galaxy point file '{}'",
cachedPointsFile, _pointsFilename
));
Result res = loadCachedFile(cachedPointsFile);
if (res.success) {
pointPositions = std::move(res.positions);
pointColors = std::move(res.color);
}
else {
FileSys.cacheManager()->removeCacheFile(_pointsFilename);
Result resPoint = loadPointFile(_pointsFilename);
pointPositions = std::move(resPoint.positions);
pointColors = std::move(resPoint.color);
saveCachedFile(
cachedPointsFile,
pointPositions,
pointColors,
_nPoints,
_enabledPointsRatio
);
}
}
else {
Result res = loadPointFile(_pointsFilename);
ghoul_assert(res.success, "Point file loading failed");
pointPositions = std::move(res.positions);
pointColors = std::move(res.color);
saveCachedFile(
cachedPointsFile,
pointPositions,
pointColors,
_nPoints,
_enabledPointsRatio
);
}
glGenVertexArrays(1, &_pointsVao);
glGenBuffers(1, &_positionVbo);
glGenBuffers(1, &_colorVbo);
@@ -496,17 +505,19 @@ void RenderableGalaxy::initializeGL() {
glBindVertexArray(_pointsVao);
glBindBuffer(GL_ARRAY_BUFFER, _positionVbo);
glBufferData(GL_ARRAY_BUFFER,
pointPositions.size() * sizeof(glm::vec3),
pointPositions.data(),
_pointPositionsCache.size() * sizeof(glm::vec3),
_pointPositionsCache.data(),
GL_STATIC_DRAW
);
_pointPositionsCache.clear();
glBindBuffer(GL_ARRAY_BUFFER, _colorVbo);
glBufferData(GL_ARRAY_BUFFER,
pointColors.size() * sizeof(glm::vec3),
pointColors.data(),
_pointColorsCache.size() * sizeof(glm::vec3),
_pointColorsCache.data(),
GL_STATIC_DRAW
);
_pointColorsCache.clear();
glBindBuffer(GL_ARRAY_BUFFER, _positionVbo);
glEnableVertexAttribArray(positionAttrib);
@@ -632,23 +643,6 @@ void RenderableGalaxy::renderPoints(const RenderData& data) {
if (!_pointsProgram) {
return;
}
// Saving current OpenGL state
GLenum blendEquationRGB;
GLenum blendEquationAlpha;
GLenum blendDestAlpha;
GLenum blendDestRGB;
GLenum blendSrcAlpha;
GLenum blendSrcRGB;
GLboolean depthMask;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDepthMask(false);
@@ -697,14 +691,9 @@ void RenderableGalaxy::renderPoints(const RenderData& data) {
_pointsProgram->deactivate();
glEnable(GL_DEPTH_TEST);
glDepthMask(true);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Restores OpenGL blending state
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
glDepthMask(depthMask);
// Restores OpenGL Rendering State
global::renderEngine.openglStateCache().resetBlendState();
global::renderEngine.openglStateCache().resetDepthState();
}
void RenderableGalaxy::renderBillboards(const RenderData& data) {
@@ -47,6 +47,7 @@ public:
explicit RenderableGalaxy(const ghoul::Dictionary& dictionary);
virtual ~RenderableGalaxy() = default;
void initialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
@@ -110,6 +111,9 @@ private:
GLuint _pointsVao = 0;
GLuint _positionVbo = 0;
GLuint _colorVbo = 0;
std::vector<glm::vec3> _pointPositionsCache;
std::vector<glm::vec3> _pointColorsCache;
};
} // namespace openspace
@@ -219,10 +219,8 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary& dict) {
global::callback::initializeGL.emplace_back([&]() {
ZoneScopedN("GlobeBrowsingModule")
_tileCache = std::make_unique<globebrowsing::cache::MemoryAwareTileCache>(
_tileCacheSizeMB
);
addPropertySubOwner(*_tileCache);
_tileCache = std::make_unique<cache::MemoryAwareTileCache>(_tileCacheSizeMB);
addPropertySubOwner(_tileCache.get());
tileprovider::initializeDefaultTile();
@@ -521,7 +519,9 @@ void GlobeBrowsingModule::goToChunk(const globebrowsing::RenderableGlobe& globe,
);
return;
}
const glm::dmat4 inverseModelTransform = globeSceneGraphNode->inverseModelTransform();
const glm::dmat4 inverseModelTransform = glm::inverse(
globeSceneGraphNode->modelTransform()
);
const glm::dvec3 cameraPositionModelSpace =
glm::dvec3(inverseModelTransform * glm::dvec4(cameraPosition, 1.0));
const SurfacePositionHandle posHandle = globe.calculateSurfacePositionHandle(
@@ -551,7 +551,9 @@ void GlobeBrowsingModule::goToGeodetic2(const globebrowsing::RenderableGlobe& gl
LERROR("Error when going to Geodetic2");
}
const glm::dmat4 inverseModelTransform = globeSceneGraphNode->inverseModelTransform();
const glm::dmat4 inverseModelTransform = glm::inverse(
globeSceneGraphNode->modelTransform()
);
const glm::dvec3 cameraPositionModelSpace =
glm::dvec3(inverseModelTransform * glm::dvec4(cameraPosition, 1.0));
@@ -44,6 +44,8 @@ namespace openspace::globebrowsing::luascriptfunctions {
* Adds a layer to the specified globe.
*/
int addLayer(lua_State* L) {
ZoneScoped
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::addLayer");
// String arguments
@@ -329,7 +331,7 @@ int getGeoPositionForCamera(lua_State* L) {
const glm::dvec3 cameraPosition = global::navigationHandler.camera()->positionVec3();
const SceneGraphNode* anchor =
global::navigationHandler.orbitalNavigator().anchorNode();
const glm::dmat4 inverseModelTransform = anchor->inverseModelTransform();
const glm::dmat4 inverseModelTransform = glm::inverse(anchor->modelTransform());
const glm::dvec3 cameraPositionModelSpace =
glm::dvec3(inverseModelTransform * glm::dvec4(cameraPosition, 1.0));
const SurfacePositionHandle posHandle = globe->calculateSurfacePositionHandle(
@@ -1,11 +1,12 @@
openspace.globebrowsing.documentation = {
{
Name = "createTemporalGibsGdalXml",
Arguments = "string, string, string, string, string, string",
Arguments = "string, string, string, string, string, string, [string]",
Documentation =
"Creates an XML configuration for a temporal GIBS dataset." ..
"Arguments are: Name, Start date, end date, time resolution, time format," ..
"resolution, file format. For all specifications, see " ..
"resolution, file format. The last parameter is the temporal format and " ..
"defaults to YYYY-MM-DD. For all specifications, see " ..
"https://wiki.earthdata.nasa.gov/display/GIBS/GIBS+Available+Imagery+Products" ..
"Usage:" ..
"openspace.globebrowsing.addLayer(" ..
@@ -115,13 +116,14 @@ openspace.globebrowsing.addGibsLayer = function(layer, resolution, format, start
openspace.globebrowsing.addLayer('Earth', 'ColorLayers', { Identifier = layer, Type = "TemporalTileLayer", FilePath = xml })
end
openspace.globebrowsing.createTemporalGibsGdalXml = function (layerName, startDate, endDate, timeResolution, resolution, format)
openspace.globebrowsing.createTemporalGibsGdalXml = function (layerName, startDate, endDate, timeResolution, resolution, format, temporalFormat)
temporalFormat = temporalFormat or 'YYYY-MM-DD'
temporalTemplate =
"<OpenSpaceTemporalGDALDataset>" ..
"<OpenSpaceTimeStart>" .. startDate .. "</OpenSpaceTimeStart>" ..
"<OpenSpaceTimeEnd>" .. endDate .. "</OpenSpaceTimeEnd>" ..
"<OpenSpaceTimeResolution>" .. timeResolution .. "</OpenSpaceTimeResolution>" ..
"<OpenSpaceTimeIdFormat>YYYY-MM-DD</OpenSpaceTimeIdFormat>" ..
"<OpenSpaceTimeIdFormat>" .. temporalFormat .. "</OpenSpaceTimeIdFormat>" ..
openspace.globebrowsing.createGibsGdalXml(layerName, "${OpenSpaceTimeId}", resolution, format) ..
"</OpenSpaceTemporalGDALDataset>"
return temporalTemplate
@@ -31,6 +31,7 @@
#include <openspace/engine/moduleengine.h>
#include <openspace/engine/globals.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/ghoul_gl.h>
namespace openspace::globebrowsing {
@@ -45,6 +46,8 @@ AsyncTileDataProvider::AsyncTileDataProvider(std::string name,
, _rawTileDataReader(std::move(rawTileDataReader))
, _concurrentJobManager(LRUThreadPool<TileIndex::TileHashKey>(1, 10))
{
ZoneScoped
_globeBrowsingModule = global::moduleEngine.module<GlobeBrowsingModule>();
performReset(ResetRawTileDataReader::No);
}
@@ -56,6 +59,8 @@ const RawTileDataReader& AsyncTileDataProvider::rawTileDataReader() const {
}
bool AsyncTileDataProvider::enqueueTileIO(const TileIndex& tileIndex) {
ZoneScoped
if (_resetMode == ResetMode::ShouldNotReset && satisfiesEnqueueCriteria(tileIndex)) {
auto job = std::make_unique<TileLoadJob>(*_rawTileDataReader, tileIndex);
_concurrentJobManager.enqueueJob(std::move(job), tileIndex.hashKey());
@@ -94,6 +99,8 @@ std::optional<RawTile> AsyncTileDataProvider::popFinishedRawTile() {
}
bool AsyncTileDataProvider::satisfiesEnqueueCriteria(const TileIndex& tileIndex) {
ZoneScoped
// Only satisfies if it is not already enqueued. Also bumps the request to the top.
const bool alreadyEnqueued = _concurrentJobManager.touch(tileIndex.hashKey());
// Early out so we don't need to check the already enqueued requests
@@ -187,6 +194,8 @@ bool AsyncTileDataProvider::shouldBeDeleted() {
}
void AsyncTileDataProvider::performReset(ResetRawTileDataReader resetRawTileDataReader) {
ZoneScoped
ghoul_assert(_enqueuedTileRequests.empty(), "No enqueued requests left");
// Reset raw tile data reader
+15 -4
View File
@@ -26,6 +26,7 @@
#define __OPENSPACE_MODULE_GLOBEBROWSING__BASICTYPES___H__
#include <ghoul/glm.h>
#include <array>
#include <memory>
#include <optional>
#include <vector>
@@ -95,9 +96,15 @@ struct TileDepthTransform {
struct TileMetaData {
std::vector<float> maxValues;
std::vector<float> minValues;
std::vector<bool> hasMissingData;
// 4 => the number of rasters, which has a maximum of 4 for RGBA images, we don't
// currently support images with arbitrary number of color channels and I don't know
// if GDAL does either. The std::vector here causes a dynamic memory allocation every
// time we return a Tile (which contains a TileMetaData as a member variable
std::array<float, 4> maxValues;
std::array<float, 4> minValues;
std::array<bool, 4> hasMissingData;
uint8_t nValues;
};
@@ -161,7 +168,11 @@ struct ChunkTile {
using ChunkTilePile = std::vector<ChunkTile>;
//using ChunkTilePile = std::vector<ChunkTile>;
// The ChunkTilePile either contains 1 or 3 ChunkTile, depending on if layer-blending is
// enabled. If it is enabled, we need the two adjacent levels, if it is not enabled, only
// the current layer is needed
using ChunkTilePile = std::array<std::optional<ChunkTile>, 3>;
} // namespace openspace::globebrowsing
@@ -37,6 +37,7 @@
#include <ghoul/font/font.h>
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/misc/profiling.h>
namespace {
constexpr const char* KeyFontMono = "Mono";
@@ -135,12 +136,25 @@ DashboardItemGlobeLocation::DashboardItemGlobeLocation(
});
addProperty(_fontSize);
auto updateFormatString = [this]() {
using namespace fmt::literals;
_formatString =
"Position: {{:03.{0}f}}{{}}, {{:03.{0}f}}{{}} Altitude: {{}} {{}}"_format(
_significantDigits.value()
);
};
_significantDigits.onChange(updateFormatString);
addProperty(_significantDigits);
updateFormatString();
_font = global::fontManager.font(_fontName, _fontSize);
_buffer.resize(128);
}
void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
ZoneScoped
using namespace globebrowsing;
const SceneGraphNode* n = global::navigationHandler.orbitalNavigator().anchorNode();
@@ -153,7 +167,7 @@ void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
}
const glm::dvec3 cameraPosition = global::navigationHandler.camera()->positionVec3();
const glm::dmat4 inverseModelTransform = n->inverseModelTransform();
const glm::dmat4 inverseModelTransform = glm::inverse(n->modelTransform());
const glm::dvec3 cameraPositionModelSpace =
glm::dvec3(inverseModelTransform * glm::dvec4(cameraPosition, 1.0));
const SurfacePositionHandle posHandle = globe->calculateSurfacePositionHandle(
@@ -186,19 +200,22 @@ void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
std::pair<double, std::string> dist = simplifyDistance(altitude);
penPosition.y -= _font->height();
std::string d = std::to_string(_significantDigits);
std::string f = "Position: {:03." + d + "f}{}, {:03." + d + "f}{} Altitude: {} {}";
RenderFont(
*_font,
penPosition,
fmt::format(f,
lat, isNorth ? "N" : "S",
lon, isEast ? "E" : "W",
dist.first, dist.second
)
std::fill(_buffer.begin(), _buffer.end(), 0);
char* end = fmt::format_to(
_buffer.data(),
_formatString.c_str(),
lat, isNorth ? "N" : "S",
lon, isEast ? "E" : "W",
dist.first, dist.second
);
std::string_view text = std::string_view(_buffer.data(), end - _buffer.data());
RenderFont(*_font, penPosition, text);
}
glm::vec2 DashboardItemGlobeLocation::size() const {
ZoneScoped
return _font->boundingBox(
fmt::format("Position: {}, {} Altitude: {}", 1.f, 1.f, 1.f)
);
@@ -55,6 +55,8 @@ private:
properties::IntProperty _significantDigits;
std::shared_ptr<ghoul::fontrendering::Font> _font;
std::string _formatString;
std::vector<char> _buffer;
};
} // namespace openspace
@@ -30,6 +30,7 @@
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/consolelog.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
#include <cpl_conv.h>
#include <gdal.h>
@@ -106,6 +107,8 @@ GdalWrapper::GdalWrapper(size_t maximumCacheSize, size_t maximumMaximumCacheSize
1 // Step: One MB
)
{
ZoneScoped
addProperty(_logGdalErrors);
addProperty(_gdalMaximumCacheSize);
@@ -39,6 +39,7 @@
#include <ghoul/font/fontrenderer.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/programobject.h>
#include <cstdlib>
#include <fstream>
@@ -322,6 +323,8 @@ GlobeLabelsComponent::GlobeLabelsComponent()
void GlobeLabelsComponent::initialize(const ghoul::Dictionary& dictionary,
globebrowsing::RenderableGlobe* globe)
{
ZoneScoped
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
+5 -1
View File
@@ -27,6 +27,7 @@
#include <modules/globebrowsing/src/layer.h>
#include <modules/globebrowsing/src/layergroup.h>
#include <modules/globebrowsing/src/layermanager.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/texture.h>
namespace openspace::globebrowsing {
@@ -34,6 +35,8 @@ namespace openspace::globebrowsing {
void GPULayerGroup::setValue(ghoul::opengl::ProgramObject& program,
const LayerGroup& layerGroup, const TileIndex& tileIndex)
{
ZoneScoped
ghoul_assert(
layerGroup.activeLayers().size() == _gpuActiveLayers.size(),
"GPU and CPU active layers must have same size!"
@@ -76,7 +79,8 @@ void GPULayerGroup::setValue(ghoul::opengl::ProgramObject& program,
);
for (size_t j = 0; j < _gpuActiveLayers[i].gpuChunkTiles.size(); ++j) {
GPULayer::GPUChunkTile& t = _gpuActiveLayers[i].gpuChunkTiles[j];
const ChunkTile& ct = ctp[j];
ghoul_assert(ctp[j].has_value(), "Wrong ChunkTiles number in pile");
const ChunkTile& ct = *ctp[j];
t.texUnit.activate();
if (ct.tile.texture) {
+8 -4
View File
@@ -374,6 +374,8 @@ Layer::Layer(layergroupid::GroupID id, const ghoul::Dictionary& layerDict,
}
void Layer::initialize() {
ZoneScoped
if (_tileProvider) {
tileprovider::initialize(*_tileProvider);
}
@@ -386,16 +388,18 @@ void Layer::deinitialize() {
}
ChunkTilePile Layer::chunkTilePile(const TileIndex& tileIndex, int pileSize) const {
ZoneScoped
if (_tileProvider) {
return tileprovider::chunkTilePile(*_tileProvider, tileIndex, pileSize);
}
else {
ChunkTilePile chunkTilePile;
chunkTilePile.resize(pileSize);
std::fill(chunkTilePile.begin(), chunkTilePile.end(), std::nullopt);
for (int i = 0; i < pileSize; ++i) {
chunkTilePile[i].tile = Tile();
chunkTilePile[i].uvTransform.uvOffset = { 0, 0 };
chunkTilePile[i].uvTransform.uvScale = { 1, 1 };
chunkTilePile[i] = ChunkTile {
Tile(), TileUvTransform { { 0, 0 }, { 1, 1 } }
};
}
return chunkTilePile;
}
+2
View File
@@ -114,6 +114,8 @@ int LayerGroup::update() {
}
Layer* LayerGroup::addLayer(const ghoul::Dictionary& layerDict) {
ZoneScoped
documentation::TestResult res = documentation::testSpecification(
Layer::Documentation(),
layerDict
+12 -3
View File
@@ -23,6 +23,7 @@
****************************************************************************************/
#include <ghoul/misc/assert.h>
#include <ghoul/misc/profiling.h>
namespace openspace::globebrowsing::cache {
@@ -58,8 +59,16 @@ bool LRUCache<KeyType, ValueType, HasherType>::exist(const KeyType& key) const {
template<typename KeyType, typename ValueType, typename HasherType>
bool LRUCache<KeyType, ValueType, HasherType>::touch(const KeyType& key) {
ZoneScoped
const auto it = _itemMap.find(key);
if (it != _itemMap.end()) { // Found in cache
if (it != _itemMap.end()) {
// @TODO (abock, 2020-08-14) Instead of removing the iterator from the previous
// position and then readding it at the front, it might make more sense to move
// them around? That would prevent the dynamic memoray allocation that is
// happening here
// Found in cache
ValueType value = it->second->second;
// Remove from current position
_itemList.erase(it->second);
@@ -82,11 +91,11 @@ bool LRUCache<KeyType, ValueType, HasherType>::isEmpty() const {
template<typename KeyType, typename ValueType, typename HasherType>
ValueType LRUCache<KeyType, ValueType, HasherType>::get(const KeyType& key) {
//ghoul_assert(exist(key), "Key " << key << " must exist");
const auto it = _itemMap.find(key);
// Move list iterator pointing to value
_itemList.splice(_itemList.begin(), _itemList, it->second);
return it->second->second;
ValueType res = it->second->second;
return res;
}
template<typename KeyType, typename ValueType, typename HasherType>
@@ -195,10 +195,15 @@ MemoryAwareTileCache::TextureContainer::TextureContainer(TileTextureInitData ini
: _initData(std::move(initData))
, _numTextures(numTextures)
{
ZoneScoped
_textures.reserve(_numTextures);
reset();
}
void MemoryAwareTileCache::TextureContainer::reset() {
ZoneScoped
_textures.clear();
_freeTexture = 0;
for (size_t i = 0; i < _numTextures; ++i) {
@@ -222,6 +227,8 @@ void MemoryAwareTileCache::TextureContainer::reset() {
}
void MemoryAwareTileCache::TextureContainer::reset(size_t numTextures) {
ZoneScoped
_numTextures = numTextures;
reset();
}
@@ -260,6 +267,8 @@ MemoryAwareTileCache::MemoryAwareTileCache(int tileCacheSize)
, _applyTileCacheSize(ApplyTileCacheInfo)
, _clearTileCache(ClearTileCacheInfo)
{
ZoneScoped
createDefaultTextureContainers();
_clearTileCache.onChange([&]() { clear(); });
@@ -303,6 +312,8 @@ void MemoryAwareTileCache::clear() {
}
void MemoryAwareTileCache::createDefaultTextureContainers() {
ZoneScoped
for (int id = 0; id < layergroupid::NUM_LAYER_GROUPS; id++) {
TileTextureInitData initData = tileTextureInitData(
layergroupid::GroupID(id),
@@ -315,6 +326,8 @@ void MemoryAwareTileCache::createDefaultTextureContainers() {
void MemoryAwareTileCache::assureTextureContainerExists(
const TileTextureInitData& initData)
{
ZoneScoped
TileTextureInitData::HashKey initDataKey = initData.hashKey;
if (_textureContainerMap.find(initDataKey) == _textureContainerMap.end()) {
// For now create 500 textures of this type
@@ -328,9 +341,11 @@ void MemoryAwareTileCache::assureTextureContainerExists(
}
void MemoryAwareTileCache::setSizeEstimated(size_t estimatedSize) {
LDEBUG("Resetting tile cache size");
ZoneScoped
ghoul_assert(!_textureContainerMap.empty(), "Texture containers must exist.");
LDEBUG("Resetting tile cache size");
const size_t sumTextureTypeSize = std::accumulate(
_textureContainerMap.cbegin(),
_textureContainerMap.cend(),
@@ -353,6 +368,8 @@ void MemoryAwareTileCache::setSizeEstimated(size_t estimatedSize) {
}
void MemoryAwareTileCache::resetTextureContainerSize(size_t numTexturesPerTextureType) {
ZoneScoped
_numTextureBytesAllocatedOnCPU = 0;
for (std::pair<const TileTextureInitData::HashKey,
TextureContainerTileCache>& p : _textureContainerMap)
@@ -376,6 +393,8 @@ bool MemoryAwareTileCache::exist(const ProviderTileKey& key) const {
}
Tile MemoryAwareTileCache::get(const ProviderTileKey& key) {
ZoneScoped
const TextureContainerMap::const_iterator it = std::find_if(
_textureContainerMap.cbegin(),
_textureContainerMap.cend(),
@@ -393,8 +412,7 @@ Tile MemoryAwareTileCache::get(const ProviderTileKey& key) {
}
}
ghoul::opengl::Texture* MemoryAwareTileCache::texture(
const TileTextureInitData& initData)
ghoul::opengl::Texture* MemoryAwareTileCache::texture(const TileTextureInitData& initData)
{
// if this texture type does not exist among the texture containers
// it needs to be created
@@ -45,11 +45,10 @@ namespace openspace::globebrowsing::cache {
struct ProviderTileKey {
TileIndex tileIndex;
unsigned int providerID;
uint16_t providerID;
bool operator==(const ProviderTileKey& r) const {
return (providerID == r.providerID) &&
(tileIndex == r.tileIndex);
return (providerID == r.providerID) && (tileIndex == r.tileIndex);
}
};
@@ -85,7 +84,7 @@ struct ProviderTileHasher {
class MemoryAwareTileCache : public properties::PropertyOwner {
public:
MemoryAwareTileCache(int tileCacheSize = 1024);
explicit MemoryAwareTileCache(int tileCacheSize = 1024);
void clear();
void setSizeEstimated(size_t estimatedSize);
@@ -128,7 +127,7 @@ private:
const TileTextureInitData& tileTextureInitData() const;
/**
* \returns the number of textures in this TextureContainer
* \return the number of textures in this TextureContainer
*/
size_t size() const;
+32 -32
View File
@@ -33,6 +33,7 @@
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/exception.h>
#include <ghoul/misc/profiling.h>
#ifdef _MSC_VER
#pragma warning (push)
@@ -398,15 +399,11 @@ RawTile::ReadError postProcessErrorCheck(const RawTile& rawTile,
[[ maybe_unused ]] size_t nRasters,
float noDataValue)
{
// This check was implicit before and just made explicit here
ghoul_assert(
nRasters == rawTile.tileMetaData.maxValues.size(),
"Wrong numbers of max values"
);
ghoul_assert(nRasters == rawTile.tileMetaData.nValues, "Wrong numbers of max values");
const bool hasMissingData = std::any_of(
rawTile.tileMetaData.maxValues.begin(),
rawTile.tileMetaData.maxValues.end(),
rawTile.tileMetaData.maxValues.begin() + rawTile.tileMetaData.nValues,
[noDataValue](float v) { return v == noDataValue; }
);
@@ -427,6 +424,8 @@ RawTileDataReader::RawTileDataReader(std::string filePath,
, _initData(std::move(initData))
, _preprocess(preprocess)
{
ZoneScoped
initialize();
}
@@ -439,6 +438,8 @@ RawTileDataReader::~RawTileDataReader() {
}
void RawTileDataReader::initialize() {
ZoneScoped
if (_datasetFilePath.empty()) {
throw ghoul::RuntimeError("File path must not be empty");
}
@@ -447,6 +448,7 @@ void RawTileDataReader::initialize() {
std::string content = _datasetFilePath;
if (module.isWMSCachingEnabled()) {
ZoneScopedN("WMS Caching")
std::string c;
if (FileSys.fileExists(_datasetFilePath)) {
// Only replace the 'content' if the dataset is an XML file and we want to do
@@ -515,16 +517,19 @@ void RawTileDataReader::initialize() {
}
}
_dataset = static_cast<GDALDataset*>(GDALOpen(content.c_str(), GA_ReadOnly));
if (!_dataset) {
throw ghoul::RuntimeError("Failed to load dataset: " + _datasetFilePath);
{
ZoneScopedN("GDALOpen")
_dataset = static_cast<GDALDataset*>(GDALOpen(content.c_str(), GA_ReadOnly));
if (!_dataset) {
throw ghoul::RuntimeError("Failed to load dataset: " + _datasetFilePath);
}
}
// Assume all raster bands have the same data type
_rasterCount = _dataset->GetRasterCount();
// calculateTileDepthTransform
unsigned long long maximumValue = [t = _initData.glType]() {
unsigned long long maximumValue = [](GLenum t) {
switch (t) {
case GL_UNSIGNED_BYTE: return 1ULL << 8ULL;
case GL_UNSIGNED_SHORT: return 1ULL << 16ULL;
@@ -534,11 +539,9 @@ void RawTileDataReader::initialize() {
case GL_HALF_FLOAT: return 1ULL;
case GL_FLOAT: return 1ULL;
case GL_DOUBLE: return 1ULL;
default:
ghoul_assert(false, "Unknown data type");
throw ghoul::MissingCaseException();
default: throw ghoul::MissingCaseException();
}
}();
}(_initData.glType);
_depthTransform.scale = static_cast<float>(
@@ -558,7 +561,8 @@ void RawTileDataReader::initialize() {
}
double tileLevelDifference = calculateTileLevelDifference(
_dataset, _initData.dimensions.x
_dataset,
_initData.dimensions.x
);
const int numOverviews = _dataset->GetRasterBand(1)->GetOverviewCount();
@@ -935,18 +939,14 @@ TileMetaData RawTileDataReader::tileMetaData(RawTile& rawTile,
{
const size_t bytesPerLine = _initData.bytesPerPixel * region.numPixels.x;
TileMetaData preprocessData;
preprocessData.maxValues.resize(_initData.nRasters);
preprocessData.minValues.resize(_initData.nRasters);
preprocessData.hasMissingData.resize(_initData.nRasters);
TileMetaData ppData;
ghoul_assert(_initData.nRasters <= 4, "Unexpected number of rasters");
ppData.nValues = static_cast<uint8_t>(_initData.nRasters);
std::vector<float> noDataValues(_initData.nRasters);
for (size_t raster = 0; raster < _initData.nRasters; ++raster) {
preprocessData.maxValues[raster] = -FLT_MAX;
preprocessData.minValues[raster] = FLT_MAX;
preprocessData.hasMissingData[raster] = false;
noDataValues[raster] = noDataValueAsFloat();
}
std::fill(ppData.maxValues.begin(), ppData.maxValues.end(), -FLT_MAX);
std::fill(ppData.minValues.begin(), ppData.minValues.end(), FLT_MAX);
std::fill(ppData.hasMissingData.begin(), ppData.hasMissingData.end(), false);
std::vector<float> noDataValues(_initData.nRasters, noDataValueAsFloat());
bool allIsMissing = true;
for (int y = 0; y < region.numPixels.y; ++y) {
@@ -960,18 +960,18 @@ TileMetaData RawTileDataReader::tileMetaData(RawTile& rawTile,
&(rawTile.imageData.get()[yi + i])
);
if (val != noDataValue && val == val) {
preprocessData.maxValues[raster] = std::max(
ppData.maxValues[raster] = std::max(
val,
preprocessData.maxValues[raster]
ppData.maxValues[raster]
);
preprocessData.minValues[raster] = std::min(
ppData.minValues[raster] = std::min(
val,
preprocessData.minValues[raster]
ppData.minValues[raster]
);
allIsMissing = false;
}
else {
preprocessData.hasMissingData[raster] = true;
ppData.hasMissingData[raster] = true;
float& floatToRewrite = reinterpret_cast<float&>(
rawTile.imageData[yi + i]
);
@@ -986,7 +986,7 @@ TileMetaData RawTileDataReader::tileMetaData(RawTile& rawTile,
rawTile.error = RawTile::ReadError::Failure;
}
return preprocessData;
return ppData;
}
int RawTileDataReader::maxChunkLevel() const {
+128 -78
View File
@@ -37,11 +37,13 @@
#include <openspace/rendering/renderengine.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/scene/scene.h>
#include <openspace/util/memorymanager.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/memorypool.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -49,6 +51,7 @@
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
#include <numeric>
#include <queue>
#include <memory_resource>
namespace {
// Global flags to modify the RenderableGlobe
@@ -258,10 +261,14 @@ const Chunk& findChunkNode(const Chunk& node, const Geodetic2& location) {
return *n;
}
std::vector<std::pair<ChunkTile, const LayerRenderSettings*>>
std::pmr::vector<std::pair<ChunkTile, const LayerRenderSettings*>>
tilesAndSettingsUnsorted(const LayerGroup& layerGroup, const TileIndex& tileIndex)
{
std::vector<std::pair<ChunkTile, const LayerRenderSettings*>> tilesAndSettings;
ZoneScoped
std::pmr::vector<std::pair<ChunkTile, const LayerRenderSettings*>> tilesAndSettings(
&global::memoryManager.TemporaryMemory
);
for (Layer* layer : layerGroup.activeLayers()) {
if (layer->tileProvider()) {
tilesAndSettings.emplace_back(
@@ -275,6 +282,8 @@ tilesAndSettingsUnsorted(const LayerGroup& layerGroup, const TileIndex& tileInde
}
BoundingHeights boundingHeightsForChunk(const Chunk& chunk, const LayerManager& lm) {
ZoneScoped
using ChunkTileSettingsPair = std::pair<ChunkTile, const LayerRenderSettings*>;
BoundingHeights boundingHeights { 0.f, 0.f, false, true };
@@ -284,10 +293,9 @@ BoundingHeights boundingHeightsForChunk(const Chunk& chunk, const LayerManager&
// (that is channel 0).
const size_t HeightChannel = 0;
const LayerGroup& heightmaps = lm.layerGroup(layergroupid::GroupID::HeightLayers);
std::vector<ChunkTileSettingsPair> chunkTileSettingPairs = tilesAndSettingsUnsorted(
heightmaps,
chunk.tileIndex
);
std::pmr::vector<ChunkTileSettingsPair> chunkTileSettingPairs =
tilesAndSettingsUnsorted(heightmaps, chunk.tileIndex);
bool lastHadMissingData = true;
for (const ChunkTileSettingsPair& chunkTileSettingsPair : chunkTileSettingPairs) {
@@ -337,18 +345,16 @@ BoundingHeights boundingHeightsForChunk(const Chunk& chunk, const LayerManager&
}
bool colorAvailableForChunk(const Chunk& chunk, const LayerManager& lm) {
using ChunkTileSettingsPair = std::pair<ChunkTile, const LayerRenderSettings*>;
const LayerGroup& colormaps = lm.layerGroup(layergroupid::GroupID::ColorLayers);
std::vector<ChunkTileSettingsPair> chunkTileSettingPairs = tilesAndSettingsUnsorted(
colormaps,
chunk.tileIndex
);
ZoneScoped
for (const ChunkTileSettingsPair& chunkTileSettingsPair : chunkTileSettingPairs) {
const ChunkTile& chunkTile = chunkTileSettingsPair.first;
const LayerGroup& colorLayers = lm.layerGroup(layergroupid::GroupID::ColorLayers);
if (chunkTile.tile.status == Tile::Status::Unavailable) {
return false;
for (Layer* lyr : colorLayers.activeLayers()) {
if (lyr->tileProvider()) {
ChunkTile t = tileprovider::chunkTile(*lyr->tileProvider(), chunk.tileIndex);
if (t.tile.status == Tile::Status::Unavailable) {
return false;
}
}
}
@@ -359,6 +365,8 @@ std::array<glm::dvec4, 8> boundingCornersForChunk(const Chunk& chunk,
const Ellipsoid& ellipsoid,
const BoundingHeights& heights)
{
ZoneScoped
// assume worst case
const double patchCenterRadius = ellipsoid.maximumRadius();
@@ -607,7 +615,9 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
addPropertySubOwner(_debugPropertyOwner);
addPropertySubOwner(_layerManager);
_traversalMemory.reserve(512);
_globalChunkBuffer.resize(2048);
_localChunkBuffer.resize(2048);
_traversalMemory.resize(512);
//================================================================
//======== Reads Shadow (Eclipses) Entries in mod file ===========
@@ -843,6 +853,8 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask
}
void RenderableGlobe::update(const UpdateData& data) {
ZoneScoped
if (_localRenderer.program && _localRenderer.program->isDirty()) {
_localRenderer.program->rebuildFromFile();
@@ -911,21 +923,20 @@ void RenderableGlobe::update(const UpdateData& data) {
_shadowComponent.update(data);
}
_layerManager.update();
if (_nLayersIsDirty) {
std::array<LayerGroup*, LayerManager::NumLayerGroups> lgs =
_layerManager.layerGroups();
_generalProperties.nActiveLayers = std::accumulate(
lgs.begin(),
lgs.end(),
0,
[](int lhs, LayerGroup* lg) {
return lhs + static_cast<int>(lg->activeLayers().size());
}
);
_nLayersIsDirty = false;
}
// abock (2020-08-21)
// This is a bit nasty every since we removed the second update call from the render
// loop. The problem is when we enable a new layer, the dirty flags above will be set
// to true, but the update method hasn't run yet. So we need to move the layerManager
// update method to the render function call, but we don't want to *actually* update
// the layers once per render call; hence this nasty dirty flag
//
// How it is without in the frame when we enable a layer:
//
// RenderableGlobe::update() // updated with the old number of layers
// // Lua script to enable layer is executed and sets the dirty flags
// RenderableGlobe::render() // rendering with the new number of layers but the
// // LayerManager hasn't updated yet :o
_layerManagerDirty = true;
}
bool RenderableGlobe::renderedWithDesiredData() const {
@@ -958,6 +969,26 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&,
{
ZoneScoped
if (_layerManagerDirty) {
_layerManager.update();
_layerManagerDirty = false;
}
if (_nLayersIsDirty) {
std::array<LayerGroup*, LayerManager::NumLayerGroups> lgs =
_layerManager.layerGroups();
_generalProperties.nActiveLayers = std::accumulate(
lgs.begin(),
lgs.end(),
0,
[](int lhs, LayerGroup* lg) {
return lhs + static_cast<int>(lg->activeLayers().size());
}
);
_nLayersIsDirty = false;
}
if (_shadersNeedRecompilation) {
recompileShaders();
}
@@ -1045,20 +1076,22 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&,
_localRenderer.updatedSinceLastCall = false;
}
// Calculate the MVP matrix
const glm::dmat4& viewTransform = data.camera.combinedViewMatrix();
const glm::dmat4 vp = glm::dmat4(data.camera.sgctInternal.projectionMatrix()) *
viewTransform;
const glm::dmat4 mvp = vp * _cachedModelTransform;
_allChunksAvailable = true;
updateChunkTree(_leftRoot, data);
updateChunkTree(_rightRoot, data);
updateChunkTree(_leftRoot, data, mvp);
updateChunkTree(_rightRoot, data, mvp);
_chunkCornersDirty = false;
_iterationsOfAvailableData =
(_allChunksAvailable ? _iterationsOfAvailableData + 1 : 0);
_iterationsOfUnavailableData =
(_allChunksAvailable ? 0 : _iterationsOfUnavailableData + 1);
// Calculate the MVP matrix
const glm::dmat4& viewTransform = data.camera.combinedViewMatrix();
const glm::dmat4 vp = glm::dmat4(data.camera.sgctInternal.projectionMatrix()) *
viewTransform;
const glm::dmat4 mvp = vp * _cachedModelTransform;
//
// Setting uniforms that don't change between chunks but are view dependent
@@ -1165,24 +1198,22 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&,
_globalRenderer.program->setIgnoreUniformLocationError(IgnoreError::Yes);
}
constexpr const int ChunkBufferSize = 2048;
std::array<const Chunk*, ChunkBufferSize> global;
int globalCount = 0;
std::array<const Chunk*, ChunkBufferSize> local;
int localCount = 0;
auto traversal = [&global, &globalCount, &local, &localCount, this,
cutoff = _debugProperties.modelSpaceRenderingCutoffLevel](const Chunk& node)
auto traversal = [](const Chunk& node, std::vector<const Chunk*>& global,
int& globalCount, std::vector<const Chunk*>& local, int& localCount, int cutoff,
std::vector<const Chunk*>& traversalMemory)
{
ZoneScopedN("traversal")
_traversalMemory.clear();
traversalMemory.clear();
// Loop through nodes in breadths first order
_traversalMemory.push_back(&node);
while (!_traversalMemory.empty()) {
const Chunk* n = _traversalMemory.front();
_traversalMemory.erase(_traversalMemory.begin());
traversalMemory.push_back(&node);
while (!traversalMemory.empty()) {
const Chunk* n = traversalMemory.front();
traversalMemory.erase(traversalMemory.begin());
if (isLeaf(*n) && n->isVisible) {
if (n->tileIndex.level < cutoff) {
@@ -1198,43 +1229,59 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&,
// Add children to queue, if any
if (!isLeaf(*n)) {
for (int i = 0; i < 4; ++i) {
_traversalMemory.push_back(n->children[i]);
traversalMemory.push_back(n->children[i]);
}
}
}
};
traversal(_leftRoot);
traversal(_rightRoot);
traversal(
_leftRoot,
_globalChunkBuffer,
globalCount,
_localChunkBuffer,
localCount,
_debugProperties.modelSpaceRenderingCutoffLevel,
_traversalMemory
);
traversal(
_rightRoot,
_globalChunkBuffer,
globalCount,
_localChunkBuffer,
localCount,
_debugProperties.modelSpaceRenderingCutoffLevel,
_traversalMemory
);
// Render all chunks that want to be rendered globally
_globalRenderer.program->activate();
for (int i = 0; i < std::min(globalCount, ChunkBufferSize); ++i) {
renderChunkGlobally(*global[i], data, shadowData, renderGeomOnly);
for (int i = 0; i < globalCount; ++i) {
renderChunkGlobally(*_globalChunkBuffer[i], data, shadowData, renderGeomOnly);
}
_globalRenderer.program->deactivate();
// Render all chunks that need to be rendered locally
_localRenderer.program->activate();
for (int i = 0; i < std::min(localCount, ChunkBufferSize); ++i) {
renderChunkLocally(*local[i], data, shadowData, renderGeomOnly);
for (int i = 0; i < localCount; ++i) {
renderChunkLocally(*_localChunkBuffer[i], data, shadowData, renderGeomOnly);
}
_localRenderer.program->deactivate();
if (_debugProperties.showChunkBounds || _debugProperties.showChunkAABB) {
for (int i = 0; i < std::min(globalCount, ChunkBufferSize); ++i) {
for (int i = 0; i < globalCount; ++i) {
debugRenderChunk(
*global[i],
*_globalChunkBuffer[i],
mvp,
_debugProperties.showChunkBounds,
_debugProperties.showChunkAABB
);
}
for (int i = 0; i < std::min(localCount, ChunkBufferSize); ++i) {
for (int i = 0; i < localCount; ++i) {
debugRenderChunk(
*local[i],
*_localChunkBuffer[i],
mvp,
_debugProperties.showChunkBounds,
_debugProperties.showChunkAABB
@@ -1273,11 +1320,10 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData&
ZoneScoped
TracyGpuZone("renderChunkGlobally")
//PerfMeasure("globally");
const TileIndex& tileIndex = chunk.tileIndex;
ghoul::opengl::ProgramObject& program = *_globalRenderer.program;
const std::array<LayerGroup*, LayerManager::NumLayerGroups>& layerGroups =
std::array<LayerGroup*, LayerManager::NumLayerGroups> layerGroups =
_layerManager.layerGroups();
for (size_t i = 0; i < layerGroups.size(); ++i) {
_globalRenderer.gpuLayerGroups[i].setValue(program, *layerGroups[i], tileIndex);
@@ -1841,12 +1887,13 @@ SurfacePositionHandle RenderableGlobe::calculateSurfacePositionHandle(
bool RenderableGlobe::testIfCullable(const Chunk& chunk,
const RenderData& renderData,
const BoundingHeights& heights) const
const BoundingHeights& heights,
const glm::dmat4& mvp) const
{
ZoneScoped
return (PreformHorizonCulling && isCullableByHorizon(chunk, renderData, heights)) ||
(PerformFrustumCulling && isCullableByFrustum(chunk, renderData));
(PerformFrustumCulling && isCullableByFrustum(chunk, renderData, mvp));
}
int RenderableGlobe::desiredLevel(const Chunk& chunk, const RenderData& renderData,
@@ -2326,22 +2373,17 @@ int RenderableGlobe::desiredLevelByAvailableTileData(const Chunk& chunk) const {
//////////////////////////////////////////////////////////////////////////////////////////
bool RenderableGlobe::isCullableByFrustum(const Chunk& chunk,
const RenderData& renderData) const
const RenderData& renderData,
const glm::dmat4& mvp) const
{
ZoneScoped
// Calculate the MVP matrix
const glm::dmat4 viewTransform = glm::dmat4(renderData.camera.combinedViewMatrix());
const glm::dmat4 modelViewProjectionTransform = glm::dmat4(
renderData.camera.sgctInternal.projectionMatrix()
) * viewTransform * _cachedModelTransform;
const std::array<glm::dvec4, 8>& corners = chunk.corners;
// Create a bounding box that fits the patch corners
AABB3 bounds; // in screen space
for (size_t i = 0; i < 8; ++i) {
const glm::dvec4 cornerClippingSpace = modelViewProjectionTransform * corners[i];
const glm::dvec4 cornerClippingSpace = mvp * corners[i];
const glm::dvec3 ndc = glm::dvec3(
(1.f / glm::abs(cornerClippingSpace.w)) * cornerClippingSpace
);
@@ -2479,7 +2521,9 @@ void RenderableGlobe::mergeChunkNode(Chunk& cn) {
cn.children.fill(nullptr);
}
bool RenderableGlobe::updateChunkTree(Chunk& cn, const RenderData& data) {
bool RenderableGlobe::updateChunkTree(Chunk& cn, const RenderData& data,
const glm::dmat4& mvp)
{
ZoneScoped
// abock: I tried turning this into a queue and use iteration, rather than recursion
@@ -2488,7 +2532,8 @@ bool RenderableGlobe::updateChunkTree(Chunk& cn, const RenderData& data) {
// children and then again it self to be processed after the children finish).
// In addition, this didn't even improve performance --- 2018-10-04
if (isLeaf(cn)) {
updateChunk(cn, data);
ZoneScopedN("leaf")
updateChunk(cn, data, mvp);
if (cn.status == Chunk::Status::WantSplit) {
splitChunkNode(cn, 1);
@@ -2501,15 +2546,16 @@ bool RenderableGlobe::updateChunkTree(Chunk& cn, const RenderData& data) {
return cn.status == Chunk::Status::WantMerge;
}
else {
ZoneScopedN("!leaf")
char requestedMergeMask = 0;
for (int i = 0; i < 4; ++i) {
if (updateChunkTree(*cn.children[i], data)) {
if (updateChunkTree(*cn.children[i], data, mvp)) {
requestedMergeMask |= (1 << i);
}
}
const bool allChildrenWantsMerge = requestedMergeMask == 0xf;
updateChunk(cn, data);
updateChunk(cn, data, mvp);
if (allChildrenWantsMerge && (cn.status != Chunk::Status::WantSplit)) {
mergeChunkNode(cn);
@@ -2525,7 +2571,11 @@ bool RenderableGlobe::updateChunkTree(Chunk& cn, const RenderData& data) {
}
}
void RenderableGlobe::updateChunk(Chunk& chunk, const RenderData& data) const {
void RenderableGlobe::updateChunk(Chunk& chunk, const RenderData& data,
const glm::dmat4& mvp) const
{
ZoneScoped
const BoundingHeights& heights = boundingHeightsForChunk(chunk, _layerManager);
chunk.heightTileOK = heights.tileOK;
chunk.colorTileOK = colorAvailableForChunk(chunk, _layerManager);
@@ -2536,7 +2586,7 @@ void RenderableGlobe::updateChunk(Chunk& chunk, const RenderData& data) const {
// The flag gets set to false globally after the updateChunkTree calls
}
if (testIfCullable(chunk, data, heights)) {
if (testIfCullable(chunk, data, heights, mvp)) {
chunk.isVisible = false;
chunk.status = Chunk::Status::WantMerge;
}
+7 -4
View File
@@ -160,7 +160,7 @@ private:
* allows culling of the <code>Chunk</code>s in question.
*/
bool testIfCullable(const Chunk& chunk, const RenderData& renderData,
const BoundingHeights& heights) const;
const BoundingHeights& heights, const glm::dmat4& mvp) const;
/**
* Gets the desired level which can be used to determine if a chunk should split
@@ -222,7 +222,7 @@ private:
void debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp,
bool renderBounds, bool renderAABB) const;
bool isCullableByFrustum(const Chunk& chunk, const RenderData& renderData) const;
bool isCullableByFrustum(const Chunk& chunk, const RenderData& renderData, const glm::dmat4& mvp) const;
bool isCullableByHorizon(const Chunk& chunk, const RenderData& renderData,
const BoundingHeights& heights) const;
@@ -245,8 +245,8 @@ private:
void splitChunkNode(Chunk& cn, int depth);
void mergeChunkNode(Chunk& cn);
bool updateChunkTree(Chunk& cn, const RenderData& data);
void updateChunk(Chunk& chunk, const RenderData& data) const;
bool updateChunkTree(Chunk& cn, const RenderData& data, const glm::dmat4& mvp);
void updateChunk(Chunk& chunk, const RenderData& data, const glm::dmat4& mvp) const;
void freeChunkNode(Chunk* n);
Ellipsoid _ellipsoid;
@@ -258,6 +258,8 @@ private:
ghoul::ReusableTypedMemoryPool<Chunk, 256> _chunkPool;
std::vector<const Chunk*> _globalChunkBuffer;
std::vector<const Chunk*> _localChunkBuffer;
std::vector<const Chunk*> _traversalMemory;
@@ -287,6 +289,7 @@ private:
bool _chunkCornersDirty = true;
bool _nLayersIsDirty = true;
bool _allChunksAvailable = true;
bool _layerManagerDirty = true;
size_t _iterationsOfAvailableData = 0;
size_t _iterationsOfUnavailableData = 0;
Layer* _lastChangedLayer = nullptr;
@@ -40,6 +40,7 @@
#include <ghoul/font/fontrenderer.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -197,6 +198,8 @@ RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary)
}
void RingsComponent::initialize() {
ZoneScoped
using ghoul::filesystem::File;
addProperty(_enabled);
@@ -256,6 +259,8 @@ bool RingsComponent::isReady() const {
}
void RingsComponent::initializeGL() {
ZoneScoped
compileShadowShader();
try {
@@ -379,6 +384,8 @@ void RingsComponent::draw(const RenderData& data,
}
void RingsComponent::update(const UpdateData& data) {
ZoneScoped
if (_shader && _shader->isDirty()) {
compileShadowShader();
}
@@ -43,6 +43,7 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -226,6 +227,8 @@ bool ShadowComponent::isReady() const {
}
void ShadowComponent::initializeGL() {
ZoneScoped
createDepthTexture();
createShadowFBO();
}
@@ -437,6 +440,8 @@ void ShadowComponent::end() {
}
void ShadowComponent::update(const UpdateData&) {
ZoneScoped
_sunPosition = global::renderEngine.scene()->sceneGraphNode("Sun")->worldPosition();
glm::ivec2 renderingResolution = global::renderEngine.renderingResolution();
+1 -1
View File
@@ -30,7 +30,7 @@ bool operator==(const TileIndex& lhs, const TileIndex& rhs) {
return (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.level == rhs.level);
}
TileIndex::TileIndex(int x_, int y_, int level_)
TileIndex::TileIndex(uint32_t x_, uint32_t y_, uint8_t level_)
: x(x_)
, y(y_)
, level(level_)
+4 -4
View File
@@ -34,11 +34,11 @@ namespace openspace::globebrowsing {
struct TileIndex {
using TileHashKey = uint64_t;
TileIndex(int x, int y, int level);
TileIndex(uint32_t x, uint32_t y, uint8_t level);
int x = 0;
int y = 0;
int level = 0;
uint32_t x = 0;
uint32_t y = 0;
uint8_t level = 0;
TileIndex child(Quad q) const;
glm::vec2 positionRelativeParent() const;
+89 -52
View File
@@ -32,8 +32,10 @@
#include <modules/globebrowsing/src/rawtiledatareader.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/moduleengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/factorymanager.h>
#include <openspace/util/timemanager.h>
#include <openspace/util/spicemanager.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/font/fontmanager.h>
@@ -41,6 +43,7 @@
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/openglstatecache.h>
#include <fstream>
#include "cpl_minixml.h"
@@ -77,7 +80,7 @@ namespace openspace::globebrowsing::tileprovider {
namespace {
std::unique_ptr<ghoul::opengl::Texture> DefaultTileTexture;
Tile DefaultTile = Tile{ nullptr, std::nullopt, Tile::Status::Unavailable };
Tile DefaultTile = Tile { nullptr, std::nullopt, Tile::Status::Unavailable };
constexpr const char* KeyFilePath = "FilePath";
@@ -209,9 +212,9 @@ Tile tile(TextTileProvider& t, const TileIndex& tileIndex) {
// Keep track of defaultFBO and viewport to be able to reset state when done
GLint defaultFBO;
GLint viewport[4];
//GLint viewport[4];
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
glGetIntegerv(GL_VIEWPORT, viewport);
//glGetIntegerv(GL_VIEWPORT, viewport);
// Render to texture
glBindFramebuffer(GL_FRAMEBUFFER, t.fbo);
@@ -232,7 +235,8 @@ Tile tile(TextTileProvider& t, const TileIndex& tileIndex) {
t.fontRenderer->render(*t.font, t.textPosition, t.text, t.textColor);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
global::renderEngine.openglStateCache().resetViewportState();
//glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
tile = Tile{ texture, std::nullopt, Tile::Status::OK };
t.tileCache->put(key, t.initData.hashKey, tile);
@@ -273,34 +277,46 @@ TileProvider* levelProvider(TileProviderByLevel& t, int level) {
// TemporalTileProvider
//
std::string timeStringify(TemporalTileProvider::TimeFormatType type, const Time& t) {
// Buffer needs at least 22 characters space
int timeStringify(TemporalTileProvider::TimeFormatType type, const Time& t, char* buffer)
{
ZoneScoped
std::memset(buffer, 0, 22);
const double time = t.j2000Seconds();
switch (type) {
case TemporalTileProvider::TimeFormatType::YYYY_MM_DD:
return t.ISO8601().substr(0, 10);
{
constexpr const char Format[] = "YYYY-MM-DD";
constexpr const int Size = sizeof(Format);
SpiceManager::ref().dateFromEphemerisTime(time, buffer, Size, Format);
return Size - 1;
}
case TemporalTileProvider::TimeFormatType::YYYYMMDD_hhmmss: {
std::string ts = t.ISO8601().substr(0, 19);
// YYYY_MM_DDThh_mm_ss -> YYYYMMDD_hhmmss
ts.erase(std::remove(ts.begin(), ts.end(), '-'), ts.end());
ts.erase(std::remove(ts.begin(), ts.end(), ':'), ts.end());
replace(ts.begin(), ts.end(), 'T', '_');
return ts;
constexpr const char Format[] = "YYYYMMDD_HRMNSC";
constexpr const int Size = sizeof(Format);
SpiceManager::ref().dateFromEphemerisTime(time, buffer, Size, Format);
return Size - 1;
}
case TemporalTileProvider::TimeFormatType::YYYYMMDD_hhmm: {
std::string ts = t.ISO8601().substr(0, 16);
// YYYY_MM_DDThh_mm -> YYYYMMDD_hhmm
ts.erase(std::remove(ts.begin(), ts.end(), '-'), ts.end());
ts.erase(std::remove(ts.begin(), ts.end(), ':'), ts.end());
replace(ts.begin(), ts.end(), 'T', '_');
return ts;
constexpr const char Format[] = "YYYYMMDD_HRMN";
constexpr const int Size = sizeof(Format);
SpiceManager::ref().dateFromEphemerisTime(time, buffer, Size, Format);
return Size - 1;
}
case TemporalTileProvider::TimeFormatType::YYYY_MM_DDThhColonmmColonssZ:
return t.ISO8601().substr(0, 19) + "Z";
{
constexpr const char Format[] = "YYYY-MM-DDTHR:MN:SCZ";
constexpr const int Size = sizeof(Format);
SpiceManager::ref().dateFromEphemerisTime(time, buffer, Size, Format);
return Size - 1;
}
case TemporalTileProvider::TimeFormatType::YYYY_MM_DDThh_mm_ssZ: {
std::string timeString = t.ISO8601().substr(0, 19) + "Z";
replace(timeString.begin(), timeString.end(), ':', '_');
return timeString;
constexpr const char Format[] = "YYYY-MM-DDTHR_MN_SCZ";
constexpr const int Size = sizeof(Format);
SpiceManager::ref().dateFromEphemerisTime(time, buffer, Size, Format);
return Size - 1;
}
default:
throw ghoul::MissingCaseException();
@@ -308,7 +324,7 @@ std::string timeStringify(TemporalTileProvider::TimeFormatType type, const Time&
}
std::unique_ptr<TileProvider> initTileProvider(TemporalTileProvider& t,
const TemporalTileProvider::TimeKey& timekey)
std::string_view timekey)
{
ZoneScoped
@@ -337,12 +353,12 @@ std::unique_ptr<TileProvider> initTileProvider(TemporalTileProvider& t,
return std::make_unique<DefaultTileProvider>(t.initDict);
}
TileProvider* getTileProvider(TemporalTileProvider& t,
const TemporalTileProvider::TimeKey& timekey)
{
TileProvider* getTileProvider(TemporalTileProvider& t, std::string_view timekey) {
ZoneScoped
const auto it = t.tileProviderMap.find(timekey);
// @TODO (abock, 2020-08-20) This std::string creation can be removed once we switch
// to C++20 thanks to P0919R2
const auto it = t.tileProviderMap.find(std::string(timekey));
if (it != t.tileProviderMap.end()) {
return it->second.get();
}
@@ -351,7 +367,7 @@ TileProvider* getTileProvider(TemporalTileProvider& t,
initialize(*tileProvider);
TileProvider* res = tileProvider.get();
t.tileProviderMap[timekey] = std::move(tileProvider);
t.tileProviderMap[std::string(timekey)] = std::move(tileProvider);
return res;
}
}
@@ -361,9 +377,10 @@ TileProvider* getTileProvider(TemporalTileProvider& t, const Time& time) {
Time tCopy(time);
if (t.timeQuantizer.quantize(tCopy, true)) {
TemporalTileProvider::TimeKey timeKey = timeStringify(t.timeFormat, tCopy);
char Buffer[22];
const int size = timeStringify(t.timeFormat, tCopy, Buffer);
try {
return getTileProvider(t, timeKey);
return getTileProvider(t, std::string_view(Buffer, size));
}
catch (const ghoul::RuntimeError& e) {
LERRORC("TemporalTileProvider", e.message);
@@ -421,7 +438,10 @@ std::string consumeTemporalMetaData(TemporalTileProvider& t, const std::string&
}
try {
t.timeQuantizer.setStartEndRange(start.ISO8601(), end.ISO8601());
t.timeQuantizer.setStartEndRange(
std::string(start.ISO8601()),
std::string(end.ISO8601())
);
t.timeQuantizer.setResolution(timeResolution);
}
catch (const ghoul::RuntimeError& e) {
@@ -822,6 +842,13 @@ bool initialize(TileProvider& tp) {
ghoul_assert(!tp.isInitialized, "TileProvider can only be initialized once.");
if (TileProvider::NumTileProviders > std::numeric_limits<uint16_t>::max()) {
LERRORC(
"TileProvider",
"Number of tile providers exceeds 65535. Something will break soon"
);
TileProvider::NumTileProviders = 0;
}
tp.uniqueIdentifier = TileProvider::NumTileProviders++;
if (TileProvider::NumTileProviders == std::numeric_limits<unsigned int>::max()) {
--TileProvider::NumTileProviders;
@@ -915,29 +942,32 @@ Tile tile(TileProvider& tp, const TileIndex& tileIndex) {
switch (tp.type) {
case Type::DefaultTileProvider: {
ZoneScopedN("Type::DefaultTileProvider")
DefaultTileProvider& t = static_cast<DefaultTileProvider&>(tp);
if (t.asyncTextureDataProvider) {
if (tileIndex.level > maxLevel(t)) {
return Tile{ nullptr, std::nullopt, Tile::Status::OutOfRange };
return Tile { nullptr, std::nullopt, Tile::Status::OutOfRange };
}
const cache::ProviderTileKey key = { tileIndex, t.uniqueIdentifier };
const Tile tile = t.tileCache->get(key);
Tile tile = t.tileCache->get(key);
if (!tile.texture) {
//TracyMessage("Enqueuing tile", 32);
t.asyncTextureDataProvider->enqueueTileIO(tileIndex);
}
return tile;
}
else {
return Tile{ nullptr, std::nullopt, Tile::Status::Unavailable };
return Tile { nullptr, std::nullopt, Tile::Status::Unavailable };
}
}
case Type::SingleImageTileProvider: {
ZoneScopedN("Type::SingleImageTileProvider")
SingleImageProvider& t = static_cast<SingleImageProvider&>(tp);
return t.tile;
}
case Type::SizeReferenceTileProvider: {
ZoneScopedN("Type::SizeReferenceTileProvider")
SizeReferenceTileProvider& t = static_cast<SizeReferenceTileProvider&>(tp);
const GeodeticPatch patch(tileIndex);
@@ -978,6 +1008,7 @@ Tile tile(TileProvider& tp, const TileIndex& tileIndex) {
return tile(t, tileIndex);
}
case Type::TileIndexTileProvider: {
ZoneScopedN("Type::TileIndexTileProvider")
TileIndexTileProvider& t = static_cast<TileIndexTileProvider&>(tp);
t.text = fmt::format(
"level: {}\nx: {}\ny: {}", tileIndex.level, tileIndex.x, tileIndex.y
@@ -992,12 +1023,14 @@ Tile tile(TileProvider& tp, const TileIndex& tileIndex) {
return tile(t, tileIndex);
}
case Type::ByIndexTileProvider: {
ZoneScopedN("Type::ByIndexTileProvider")
TileProviderByIndex& t = static_cast<TileProviderByIndex&>(tp);
const auto it = t.tileProviderMap.find(tileIndex.hashKey());
const bool hasProvider = it != t.tileProviderMap.end();
return hasProvider ? tile(*it->second, tileIndex) : Tile();
}
case Type::ByLevelTileProvider: {
ZoneScopedN("Type::ByLevelTileProvider")
TileProviderByLevel& t = static_cast<TileProviderByLevel&>(tp);
TileProvider* provider = levelProvider(t, tileIndex.level);
if (provider) {
@@ -1008,6 +1041,7 @@ Tile tile(TileProvider& tp, const TileIndex& tileIndex) {
}
}
case Type::TemporalTileProvider: {
ZoneScopedN("Type::TemporalTileProvider")
TemporalTileProvider& t = static_cast<TemporalTileProvider&>(tp);
if (t.successfulInitialization) {
ensureUpdated(t);
@@ -1401,7 +1435,7 @@ ChunkTile chunkTile(TileProvider& tp, TileIndex tileIndex, int parents, int maxP
maxParents--;
}
if (maxParents < 0) {
return ChunkTile{ Tile(), uvTransform, TileDepthTransform() };
return ChunkTile { Tile(), uvTransform, TileDepthTransform() };
}
// Step 3. Traverse 0 or more parents up the chunkTree until we find a chunk that
@@ -1410,16 +1444,16 @@ ChunkTile chunkTile(TileProvider& tp, TileIndex tileIndex, int parents, int maxP
Tile t = tile(tp, tileIndex);
if (t.status != Tile::Status::OK) {
if (--maxParents < 0) {
return ChunkTile{ Tile(), uvTransform, TileDepthTransform() };
return ChunkTile { Tile(), uvTransform, TileDepthTransform() };
}
ascendToParent(tileIndex, uvTransform);
}
else {
return ChunkTile{ std::move(t), uvTransform, TileDepthTransform() };
return ChunkTile { std::move(t), uvTransform, TileDepthTransform() };
}
}
return ChunkTile{ Tile(), uvTransform, TileDepthTransform() };
return ChunkTile { Tile(), uvTransform, TileDepthTransform() };
}
@@ -1433,22 +1467,25 @@ ChunkTilePile chunkTilePile(TileProvider& tp, TileIndex tileIndex, int pileSize)
ghoul_assert(tp.isInitialized, "TileProvider was not initialized.");
ghoul_assert(pileSize >= 0, "pileSize must be positive");
ChunkTilePile chunkTilePile(pileSize);
ChunkTilePile chunkTilePile;
std::fill(chunkTilePile.begin(), chunkTilePile.end(), std::nullopt);
for (int i = 0; i < pileSize; ++i) {
chunkTilePile[i] = chunkTile(tp, tileIndex, i);
if (chunkTilePile[i].tile.status == Tile::Status::Unavailable) {
if (i > 0) {
if (chunkTilePile[i]->tile.status == Tile::Status::Unavailable) {
if (i == 0) {
// First iteration
chunkTilePile[i].tile = chunkTilePile[i - 1].tile;
chunkTilePile[i].uvTransform.uvOffset =
chunkTilePile[i - 1].uvTransform.uvOffset;
chunkTilePile[i].uvTransform.uvScale =
chunkTilePile[i - 1].uvTransform.uvScale;
chunkTilePile[i]->tile = DefaultTile;
chunkTilePile[i]->uvTransform.uvOffset = { 0.f, 0.f };
chunkTilePile[i]->uvTransform.uvScale = { 1.f, 1.f };
}
else {
chunkTilePile[i].tile = DefaultTile;
chunkTilePile[i].uvTransform.uvOffset = { 0.f, 0.f };
chunkTilePile[i].uvTransform.uvScale = { 1.f, 1.f };
// We are iterating through the array one-by-one, so we are guaranteed
// that for tile 'i', tile 'i-1' already was initializated
chunkTilePile[i]->tile = chunkTilePile[i - 1]->tile;
chunkTilePile[i]->uvTransform.uvOffset =
chunkTilePile[i - 1]->uvTransform.uvOffset;
chunkTilePile[i]->uvTransform.uvScale =
chunkTilePile[i - 1]->uvTransform.uvScale;
}
}
}
+1 -1
View File
@@ -76,7 +76,7 @@ struct TileProvider : public properties::PropertyOwner {
std::string name;
unsigned int uniqueIdentifier = 0;
uint16_t uniqueIdentifier = 0;
bool isInitialized = false;
};
+170 -151
View File
@@ -24,12 +24,16 @@
#include <modules/globebrowsing/src/timequantizer.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
#include <ghoul/fmt.h>
#include <ghoul/glm.h>
#include <ghoul/misc/assert.h>
#include <ghoul/misc/exception.h>
#include <ghoul/misc/profiling.h>
#include <date/date.h>
#include <algorithm>
#include <charconv>
#include <iomanip>
#include <sstream>
@@ -42,74 +46,54 @@
namespace openspace::globebrowsing {
namespace {
// returns the number of days in a given month and year (takes leap year into account)
int monthSize(int month, int year) {
// A year is a leap year if it is divisible by 4 unless it is also divisible by 100
// unless it is divisible by 4 *and* 100
const bool leap = ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0));
switch (month) {
case 2:
return leap ? 29 : 28;
case 4:
case 6:
case 9:
case 11:
return 30;
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
default:
return 31;
// returns the number of days in a given month and year (takes leap year into account)
constexpr int monthSize(int month, int year) {
date::year_month_day_last d = date::year(year) / date::month(month) / date::last;
return static_cast<int>(static_cast<unsigned>(d.day()));
}
}
/**
* singleIncrement is used for any of the date/time types, and handles overflow
* values using the min/max parameters
*
* \param oper the date/time variable to operate on (will be changed)
* \param val the value of the increment, which may be changed in this function
* if an overflow occurs
* \param min the minimum allowable value
* \param max the maximum allowable value (determines where overflow occurs)
*/
bool singleIncrement(int& oper, int& val, int min, int max) {
oper += val;
if (oper <= max) {
return true;
/**
* singleIncrement is used for any of the date/time types, and handles overflow
* values using the min/max parameters
*
* \param oper the date/time variable to operate on (will be changed)
* \param val the value of the increment, which may be changed in this function
* if an overflow occurs
* \param min the minimum allowable value
* \param max the maximum allowable value (determines where overflow occurs)
*/
bool singleIncrement(int& oper, int& val, int min, int max) {
oper += val;
if (oper <= max) {
return true;
}
oper = oper - max - (1 - min);
// Only single increments for the less-significant units on rollover
val = 1;
return false;
}
oper = oper - max - (1 - min);
// Only single increments for the less-significant units on rollover
val = 1;
return false;
}
/**
* singleDecrement is used for any of the date/time types, and handles underflow
* values using the min/max parameters
*
* \param oper the date/time variable to operate on (will be changed)
* \param val the value of the decrement, which may be changed in this function
* if an underflow occurs
* \param min the minimum allowable value
* \param max the maximum allowable value (determines where underflow occurs)
*/
bool singleDecrement(int& oper, int& val, int min, int max) {
oper -= val;
if (oper >= min) {
return true;
/**
* singleDecrement is used for any of the date/time types, and handles underflow
* values using the min/max parameters
*
* \param oper the date/time variable to operate on (will be changed)
* \param val the value of the decrement, which may be changed in this function
* if an underflow occurs
* \param min the minimum allowable value
* \param max the maximum allowable value (determines where underflow occurs)
*/
bool singleDecrement(int& oper, int& val, int min, int max) {
oper -= val;
if (oper >= min) {
return true;
}
oper = oper + max + (1 - min);
// Only single increments for the less-significant units on rollover
val = 1;
return false;
}
oper = oper + max + (1 - min);
// Only single increments for the less-significant units on rollover
val = 1;
return false;
}
} // namespace
RangedTime::RangedTime(std::string start, std::string end)
@@ -124,57 +108,63 @@ void RangedTime::setStart(std::string start) {
Time t1;
t1.setTime(start);
_startJ2000 = t1.j2000Seconds();
_start = start;
_start = std::move(start);
}
void RangedTime::setEnd(const std::string end) {
void RangedTime::setEnd(std::string end) {
Time t2;
t2.setTime(end);
_endJ2000 = t2.j2000Seconds();
_end = end;
_end = std::move(end);
}
bool RangedTime::includes(const std::string& checkTime) {
Time t;
t.setTime(checkTime);
const double tj = t.j2000Seconds();
bool RangedTime::includes(const Time& checkTime) const {
const double tj = checkTime.j2000Seconds();
return (_startJ2000 <= tj && tj <= _endJ2000);
}
std::string RangedTime::clamp(const std::string& checkTime) {
const char* RangedTime::clamp(const char* checkTime) {
Time t;
t.setTime(checkTime);
const double tj = t.j2000Seconds();
if (tj < _startJ2000) {
return _start;
return _start.c_str();
}
else if (tj > _endJ2000) {
return _end;
return _end.c_str();
}
else {
return checkTime;
}
}
std::string RangedTime::start() const {
std::string_view RangedTime::start() const {
return _start;
}
std::string RangedTime::end() const {
std::string_view RangedTime::end() const {
return _end;
}
DateTime::DateTime(const std::string& initDateTime) {
DateTime::DateTime(std::string_view initDateTime) {
setTime(initDateTime);
};
void DateTime::setTime(const std::string& input) {
_year = std::stoi(input.substr(index_year, len_year));
_month = std::stoi(input.substr(index_month, len_nonYear));
_day = std::stoi(input.substr(index_day, len_nonYear));
_hour = std::stoi(input.substr(index_hour, len_nonYear));
_minute = std::stoi(input.substr(index_minute, len_nonYear));
_second = std::stoi(input.substr(index_second, len_nonYear));
void DateTime::setTime(std::string_view input) {
// Indices into an ISO8601 YYYY-MM-ddTHH:mm:ss string
constexpr const size_t IndexYear = 0;
constexpr const size_t IndexMonth = 5;
constexpr const size_t IndexDay = 8;
constexpr const size_t IndexHour = 11;
constexpr const size_t IndexMinute = 14;
constexpr const size_t IndexSecond = 17;
std::from_chars(input.data() + IndexYear, input.data() + IndexYear + 4, _year);
std::from_chars(input.data() + IndexMonth, input.data() + IndexMonth + 2, _month);
std::from_chars(input.data() + IndexDay, input.data() + IndexDay + 2, _day);
std::from_chars(input.data() + IndexHour, input.data() + IndexHour + 2, _hour);
std::from_chars(input.data() + IndexMinute, input.data() + IndexMinute + 2, _minute);
std::from_chars(input.data() + IndexSecond, input.data() + IndexSecond + 2, _second);
}
std::string DateTime::ISO8601() const {
@@ -185,10 +175,14 @@ std::string DateTime::ISO8601() const {
};
double DateTime::J2000() const {
Time t;
std::string timeString = ISO8601();
t.setTime(timeString);
return t.j2000Seconds();
char Buffer[20];
std::memset(Buffer, 0, 20);
fmt::format_to(
Buffer,
"{:0>4}-{:0>2}-{:0>2}T{:0>2}:{:0>2}:{:0>2}",
_year, _month, _day, _hour, _minute, _second
);
return Time::convertTime(Buffer);
}
void DateTime::operator=(DateTime& src) {
@@ -215,36 +209,35 @@ void DateTime::incrementOnce(int value, char unit) {
bool inBounds = true;
switch (unit) {
case 'm':
if (singleIncrement(_minute, value, 0, 59))
if (singleIncrement(_minute, value, 0, 59)) {
break;
// else fall-through if overflow...
}
[[ fallthrough ]];
case 'h':
if (singleIncrement(_hour, value, 0, 23))
if (singleIncrement(_hour, value, 0, 23)) {
break;
// else fall-through if overflow...
}
[[ fallthrough ]];
case 'd':
if (singleIncrement(_day, value, 1, monthSize(_month, _year)))
if (singleIncrement(_day, value, 1, monthSize(_month, _year))) {
break;
// else fall-through if overflow...
}
[[ fallthrough ]];
case 'M':
inBounds = singleIncrement(_month, value, 1, 12);
_day = std::clamp(_day, 1, monthSize(_month, _year));
if (inBounds)
if (inBounds) {
break;
// else fall-through if overflow...
}
[[ fallthrough ]];
case 'y':
_year += value;
break;
default:
throw ghoul::RuntimeError(
"Invalid unit format in TQ incrementOnce '" + std::to_string(unit) +
"'. Expected 'y', 'M', 'd', 'h', or 'm'."
);
throw ghoul::RuntimeError(fmt::format(
"Invalid unit in incrementOnce '{}'. Expected 'y', 'M', 'd', 'h', or 'm'",
unit
));
}
}
@@ -481,43 +474,68 @@ double TimeQuantizer::computeSecondsFromResolution(const int valueIn, const char
}
bool TimeQuantizer::quantize(Time& t, bool clamp) {
const std::string unquantizedStr = t.ISO8601();
DateTime unquantized(unquantizedStr);
//resolutionFraction helps to improve iteration performance
const double resolutionFraction = 0.7;
double error = 0.0;
const int iterationLimit = 50;
ZoneScoped
constexpr const char Format[] = "YYYY-MM-DDTHR:MN:SC.###";
constexpr const int BufferSize = sizeof(Format);
char unquantizedString[BufferSize];
std::memset(unquantizedString, 0, BufferSize);
SpiceManager::ref().dateFromEphemerisTime(
t.j2000Seconds(),
unquantizedString, BufferSize,
Format
);
DateTime unquantized(std::string_view(unquantizedString, BufferSize));
// resolutionFraction helps to improve iteration performance
constexpr const double ResolutionFraction = 0.7;
constexpr const int IterationLimit = 50;
int iterations = 0;
int lastIncr = 0;
int lastDecr = 0;
if (_timerange.includes(unquantizedStr)) {
if (_timerange.includes(t)) {
DateTime quantized = DateTime(_timerange.start());
doFirstApproximation(quantized, unquantized, _resolutionValue, _resolutionUnit);
error = diff(quantized, unquantized);
while (error > (_resolution * resolutionFraction) || error < 0) {
double error = unquantized.J2000() - quantized.J2000();
while (error > (_resolution * ResolutionFraction) || error < 0) {
if (error > 0) {
lastIncr = quantized.increment(static_cast<int>(_resolutionValue),
_resolutionUnit, error, _resolution);
lastIncr = quantized.increment(
static_cast<int>(_resolutionValue),
_resolutionUnit,
error,
_resolution
);
}
else if (error < 0) {
lastDecr = quantized.decrement(static_cast<int>(_resolutionValue),
_resolutionUnit, error, _resolution);
lastDecr = quantized.decrement(
static_cast<int>(_resolutionValue),
_resolutionUnit,
error,
_resolution
);
}
error = diff(quantized, unquantized);
error = unquantized.J2000() - quantized.J2000();
bool hasSettled = (lastIncr == 1 && lastDecr == 1 && error >= 0.0);
iterations++;
if (hasSettled || iterations > iterationLimit) {
if (hasSettled || iterations > IterationLimit) {
break;
}
}
quantized.setTime(_timerange.clamp(quantized.ISO8601()));
t.setTime(quantized.J2000());
char Buffer[20];
std::memset(Buffer, 0, 20);
fmt::format_to(
Buffer,
"{:0>4}-{:0>2}-{:0>2}T{:0>2}:{:0>2}:{:0>2}",
quantized.year(), quantized.month(), quantized.day(),
quantized.hour(), quantized.minute(), quantized.second()
);
t.setTime(_timerange.clamp(Buffer));
return true;
}
else if (clamp) {
const std::string clampedTime = _timerange.clamp(unquantizedStr);
t.setTime(clampedTime);
t.setTime(_timerange.clamp(unquantizedString));
return true;
}
else {
@@ -525,49 +543,50 @@ bool TimeQuantizer::quantize(Time& t, bool clamp) {
}
}
double TimeQuantizer::diff(DateTime& from, DateTime& to) {
return to.J2000() - from.J2000();
}
void TimeQuantizer::doFirstApproximation(DateTime& quantized, DateTime& unQ,
double value, char unit)
void TimeQuantizer::doFirstApproximation(DateTime& quantized, DateTime& unQ, double value,
char unit)
{
double minYearsToAdjust;
double minIncrementsAdjust;
bool isSimMonthPastQuantizedMonth;
double error = 0.0;
int originalHour, originalMinute, originalSecond;
Time testDay;
double addToTime;
ZoneScoped
switch (unit) {
case 'y':
minYearsToAdjust = static_cast<double>(unQ.year()) -
static_cast<double>(_start.year());
minIncrementsAdjust = minYearsToAdjust / value;
{
const double minYearsToAdjust = static_cast<double>(
unQ.year()) - static_cast<double>(_start.year()
);
const double minIncrementsAdjust = minYearsToAdjust / value;
quantized.setYear(
_start.year() + static_cast<int>(minIncrementsAdjust * value)
);
break;
}
case 'M':
isSimMonthPastQuantizedMonth = unQ.month() > static_cast<int>(value);
{
bool isSimMonthPastQuantizedMonth = unQ.month() > static_cast<int>(value);
quantized.setYear(
(isSimMonthPastQuantizedMonth) ? unQ.year() : unQ.year() - 1
);
break;
}
case 'd':
error = diff(quantized, unQ) / (60 * 60 * 24);
originalHour = quantized.hour();
originalMinute = quantized.minute();
originalSecond = quantized.second();
addToTime = std::round(error) * 86400;
testDay.setTime(quantized.J2000() + addToTime);
quantized.setTime(testDay.ISO8601());
{
const double error = (unQ.J2000() - quantized.J2000()) / (60.0 * 60.0 * 24.0);
const int originalHour = quantized.hour();
const int originalMinute = quantized.minute();
const int originalSecond = quantized.second();
const double addToTime = std::round(error) * 86400;
Time testDay(quantized.J2000() + addToTime);
char Buffer[25];
testDay.ISO8601(Buffer);
quantized.setTime(std::string_view(Buffer, 25));
quantized.setHour(originalHour);
quantized.setMinute(originalMinute);
quantized.setSecond(originalSecond);
break;
}
case 'h':
{
quantized = unQ;
quantized.setMinute(0);
quantized.setSecond(0);
@@ -578,6 +597,7 @@ void TimeQuantizer::doFirstApproximation(DateTime& quantized, DateTime& unQ,
quantized.decrementOnce(1, 'd');
}
break;
}
case 'm':
quantized = unQ;
quantized.setMinute(0);
@@ -591,8 +611,7 @@ void TimeQuantizer::doFirstApproximation(DateTime& quantized, DateTime& unQ,
break;
default:
throw ghoul::RuntimeError(fmt::format(
"Invalid unit format in doFirstApproximation '{}'. Expected 'y', 'M', "
"d', 'h', or 'm'", unit
"Invalid unit '{}'. Expected 'y', 'M', 'd', 'h', or 'm'", unit
));
}
}
@@ -616,8 +635,8 @@ std::vector<std::string> TimeQuantizer::quantized(Time& start, Time& end) {
std::vector<std::string> result;
DateTime itr = s;
RangedTime range(start.ISO8601(), end.ISO8601());
while (range.includes(itr.ISO8601())) {
RangedTime range(std::string(start.ISO8601()), std::string(end.ISO8601()));
while (range.includes(Time(itr.ISO8601()))) {
itr.incrementOnce(static_cast<int>(_resolutionValue), _resolutionUnit);
result.push_back(itr.ISO8601());
}
+7 -19
View File
@@ -54,11 +54,11 @@ public:
* Checks if a date/time value falls within the start/end range defined in this
* instance of the class.
*
* \param checkTime An ISO8601 date/time string to test if it falls within the range
* \param checkTime The time to test if it falls within the range
*
* \returns true if the input date/time falls between the start and end date/times
*/
bool includes(const std::string& checkTime);
bool includes(const Time& checkTime) const;
/*
* Enforces the start/end range on a given date/time string by clamping the value
@@ -69,21 +69,21 @@ public:
* less than start, equal to end if greater than end, or equal to input
* parameter if falls in-between
*/
std::string clamp(const std::string& checkTime);
const char* clamp(const char* checkTime);
/*
* Get the start date/time of the time range
*
* \returns The ISO8601 date/time string that defines the start of the range
*/
std::string start() const;
std::string_view start() const;
/*
* Get the end date/time of the time range
*
* \returns The ISO8601 date/time string that defines the end of the range
*/
std::string end() const;
std::string_view end() const;
/*
* Set the start date/time of the time range
@@ -122,14 +122,14 @@ public:
*
* \params initDateTime the ISO8601 date/time string (YYYY-MM-DDTHH:mm:ss)
*/
DateTime(const std::string& initDateTime);
DateTime(std::string_view initDateTime);
/*
* Set the date/time value
*
* \params input the ISO8601 date/time string (YYYY-MM-DDTHH:mm:ss) to set
*/
void setTime(const std::string& input);
void setTime(std::string_view input);
/*
* Used to deep-copy from another DateTime instance
@@ -276,17 +276,6 @@ public:
void decrementOnce(int value, char unit);
private:
// index_ values are indices into an ISO8601 YYYY-MM-ddTHH:mm:ss string
const int index_year = 0;
const int index_month = 5;
const int index_day = 8;
const int index_hour = 11;
const int index_minute = 14;
const int index_second = 17;
const int len_year = 4;
const int len_nonYear = 2;
int _year = 2000;
int _month = 1;
int _day = 1;
@@ -369,7 +358,6 @@ public:
private:
void verifyStartTimeRestrictions();
void verifyResolutionRestrictions(const int value, const char unit);
double diff(DateTime& from, DateTime& to);
void doFirstApproximation(DateTime& q, DateTime& unQ, double value, char unit);
double computeSecondsFromResolution(const int valueIn, const char unit);
double _resolution = 0.0;
+2
View File
@@ -31,6 +31,7 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/include/guiassetcomponent.h
${CMAKE_CURRENT_SOURCE_DIR}/include/guicomponent.h
${CMAKE_CURRENT_SOURCE_DIR}/include/guifilepathcomponent.h
${CMAKE_CURRENT_SOURCE_DIR}/include/guigibscomponent.h
${CMAKE_CURRENT_SOURCE_DIR}/include/guiglobebrowsingcomponent.h
${CMAKE_CURRENT_SOURCE_DIR}/include/guihelpcomponent.h
${CMAKE_CURRENT_SOURCE_DIR}/include/guijoystickcomponent.h
@@ -51,6 +52,7 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/src/guiassetcomponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guicomponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guifilepathcomponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guigibscomponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guiglobebrowsingcomponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guihelpcomponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/guijoystickcomponent.cpp
+4 -1
View File
@@ -29,6 +29,7 @@
#include <modules/imgui/include/guiassetcomponent.h>
#include <modules/imgui/include/guifilepathcomponent.h>
#include <modules/imgui/include/guigibscomponent.h>
#include <modules/imgui/include/guiglobebrowsingcomponent.h>
#include <modules/imgui/include/guihelpcomponent.h>
#include <modules/imgui/include/guiiswacomponent.h>
@@ -63,7 +64,7 @@ namespace openspace::gui {
namespace detail {
constexpr int nComponents() {
const int nRegularComponents = 16;
const int nRegularComponents = 17;
int totalComponents = nRegularComponents;
#ifdef OPENSPACE_MODULE_ISWA_ENABLED
@@ -105,6 +106,7 @@ public:
GuiHelpComponent _help;
GuiFilePathComponent _filePath;
GuiAssetComponent _asset;
GuiGIBSComponent _gibs;
GuiGlobeBrowsingComponent _globeBrowsing;
GuiPropertyComponent _globalProperty;
@@ -144,6 +146,7 @@ private:
&_spaceTime,
&_mission,
&_parallel,
&_gibs,
&_globeBrowsing,
#ifdef OPENSPACE_MODULE_ISWA_ENABLED
&_iswa,
+42
View File
@@ -0,0 +1,42 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2020 *
* *
* 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_MODULE_IMGUI___GUIGIBSCOMPONENT___H__
#define __OPENSPACE_MODULE_IMGUI___GUIGIBSCOMPONENT___H__
#include <modules/imgui/include/guicomponent.h>
#include <string>
namespace openspace::gui {
class GuiGIBSComponent : public GuiComponent {
public:
GuiGIBSComponent();
void render() override;
};
} // namespace openspace::gui
#endif // __OPENSPACE_MODULE_IMGUI___GUIGIBSCOMPONENT___H__
+134
View File
@@ -0,0 +1,134 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2020 *
* *
* 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 <modules/imgui/include/guigibscomponent.h>
#include <modules/imgui/include/imgui_include.h>
#include <openspace/engine/globals.h>
#include <openspace/scripting/scriptengine.h>
#include <array>
#pragma optimize ("", off)
namespace {
const ImVec2 WindowSize = ImVec2(350, 500);
} // namespace
namespace openspace::gui {
GuiGIBSComponent::GuiGIBSComponent()
: GuiComponent("GIBS", "GIBS")
{}
void GuiGIBSComponent::render() {
ImGui::SetNextWindowCollapsed(_isCollapsed);
bool e = _isEnabled;
ImGui::Begin("GIBS", &e, WindowSize, 0.5f);
_isEnabled = e;
_isCollapsed = ImGui::IsWindowCollapsed();
ImGui::Text("%s", "GIBS Layers");
ImGui::Text("%s", "Find the information on the GIBS layer page at:");
ImGui::Text(
"%s",
"https://wiki.earthdata.nasa.gov/display/GIBS/GIBS+Available+Imagery+Products"
);
ImGui::Separator();
static std::array<char, 256> LayerBuffer;
ImGui::InputText("Layer Name", LayerBuffer.data(), LayerBuffer.size());
static std::array<char, 64> StartDateBuffer;
ImGui::InputText("Start Date", StartDateBuffer.data(), StartDateBuffer.size());
static std::array<char, 64> EndDateBuffer = { "Yesterday" };
ImGui::InputText("End Date", EndDateBuffer.data(), EndDateBuffer.size());
static std::array<char, 64> TemporalResolutionBuffer = { "1d" };
ImGui::InputText(
"Temporal Resolution",
TemporalResolutionBuffer.data(),
TemporalResolutionBuffer.size()
);
//static std::array<char, 64> TemporalFormatBuffer;
// @TODO Replace with dropdown menu
constexpr std::array<const char*, 5> TemporalFormats = {
// @FRAGILE: Synchronized with tileprovider.cpp `from_string` method
"YYYY-MM-DD",
"YYYY-MM-DDThh:mm:ssZ",
"YYYY-MM-DDThh_mm_ssZ",
"YYYYMMDD_hhmmss",
"YYYYMMDD_hhmm"
};
static const char* currentTemporalFormat = "YYYY-MM-DD";
if (ImGui::BeginCombo("##Temporal Format", currentTemporalFormat)) {
for (const char* f : TemporalFormats) {
bool isSelected = (f == currentTemporalFormat);
if (ImGui::Selectable(f, &isSelected)) {
currentTemporalFormat = f;
}
}
ImGui::EndCombo();
}
static std::array<char, 64> ImageResolutionBuffer = { "250m" };
ImGui::InputText(
"Image Resolution",
ImageResolutionBuffer.data(),
ImageResolutionBuffer.size()
);
static std::array<char, 64> ImageFormatBuffer = { "png" };
ImGui::InputText("Image Format", ImageFormatBuffer.data(), ImageFormatBuffer.size());
if (ImGui::Button("Add Layer")) {
std::string layer = std::string(LayerBuffer.data());
std::string startDate = std::string(StartDateBuffer.data());
std::string endDate = std::string(EndDateBuffer.data());
std::string temporalRes = std::string(TemporalResolutionBuffer.data());
std::string temporalFormat = std::string(currentTemporalFormat);
std::string imageRes = std::string(ImageResolutionBuffer.data());
std::string imageFormat = std::string(ImageFormatBuffer.data());
std::string xmlFunc = fmt::format(
"openspace.globebrowsing.createTemporalGibsGdalXml("
"'{}', '{}', '{}', '{}', '{}', '{}', '{}')",
layer, startDate, endDate, temporalRes, imageRes, imageFormat, temporalFormat
);
std::string script = fmt::format(
"openspace.globebrowsing.addLayer('Earth', 'ColorLayers', {{ "
"Identifier = '{}', Enabled = true, Type = 'TemporalTileLayer', "
"FilePath = {} }})",
layer, xmlFunc
);
global::scriptEngine.queueScript(
script,
scripting::ScriptEngine::RemoteScripting::Yes
);
}
ImGui::End();
}
} // namespace openspace::gui
+4 -4
View File
@@ -41,9 +41,9 @@ namespace {
" %i: %i/%i (%.2f/%.2f kiB)",
i,
occupancies[i],
p.BucketSize,
p._bucketSize,
occupancies[i] / 1024.f,
p.BucketSize / 1024.f
p._bucketSize / 1024.f
);
}
}
@@ -66,8 +66,8 @@ void GuiMemoryComponent::render() {
ImGui::Text("%s", "Persistent Memory Pool");
renderMemoryPoolInformation(global::memoryManager.PersistentMemory);
ImGui::Text("%s", "Temporary Memory Pool");
renderMemoryPoolInformation(global::memoryManager.TemporaryMemory);
//ImGui::Text("%s", "Temporary Memory Pool");
//renderMemoryPoolInformation(global::memoryManager.TemporaryMemory);
ImGui::End();
}
+3 -3
View File
@@ -63,7 +63,7 @@ namespace {
openspace::gui::CaptionText("Mission Progress");
ImGui::Text("%s", startTime.UTC().c_str());
ImGui::Text("%s", std::string(startTime.UTC()).c_str());
ImGui::SameLine();
float v = static_cast<float>(currentTime);
const float s = static_cast<float>(startTime.j2000Seconds());
@@ -74,10 +74,10 @@ namespace {
&v,
s,
e,
openspace::global::timeManager.time().UTC().c_str()
std::string(openspace::global::timeManager.time().UTC()).c_str()
);
ImGui::SameLine();
ImGui::Text("%s", endTime.UTC().c_str());
ImGui::Text("%s", std::string(endTime.UTC()).c_str());
openspace::gui::CaptionText("Phases");
+5 -2
View File
@@ -211,7 +211,10 @@ void GuiSpaceTimeComponent::render() {
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 10.f);
ImGui::Text("Current Date: %s", global::timeManager.time().UTC().c_str());
ImGui::Text(
"Current Date: %s",
std::string(global::timeManager.time().UTC()).c_str()
);
constexpr int BufferSize = 256;
static char Buffer[BufferSize];
@@ -296,7 +299,7 @@ void GuiSpaceTimeComponent::render() {
const bool nowDay = ImGui::Button("Now");
if (nowDay) {
std::string nowTime = Time::now().UTC();
std::string nowTime = std::string(Time::now().UTC());
// UTC returns a string of the type YYYY MMM DDTHH:mm:ss.xxx
// setTime doesn't like the T in it and wants a space instead
nowTime[11] = ' ';
+3 -2
View File
@@ -269,8 +269,9 @@ std::string IswaManager::iswaUrl(int id, double timestamp, const std::string& ty
}
//std::string t = Time::ref().currentTimeUTC();
std::string t = SpiceManager::ref().dateFromEphemerisTime(timestamp);
std::stringstream ss(t);
std::string_view t = SpiceManager::ref().dateFromEphemerisTime(timestamp);
std::stringstream ss;
ss << t;
std::string token;
std::getline(ss, token, ' ');
+3 -2
View File
@@ -204,8 +204,9 @@ void ServerModule::handleConnection(std::shared_ptr<Connection> connection) {
ZoneScoped
std::string messageString;
messageString.reserve(256);
while (connection->socket()->getMessage(messageString)) {
std::lock_guard<std::mutex> lock(_messageQueueMutex);
std::lock_guard lock(_messageQueueMutex);
_messageQueue.push_back({ connection, std::move(messageString) });
}
}
@@ -213,7 +214,7 @@ void ServerModule::handleConnection(std::shared_ptr<Connection> connection) {
void ServerModule::consumeMessages() {
ZoneScoped
std::lock_guard<std::mutex> lock(_messageQueueMutex);
std::lock_guard lock(_messageQueueMutex);
while (!_messageQueue.empty()) {
const Message& m = _messageQueue.front();
if (std::shared_ptr<Connection> c = m.connection.lock()) {
+6 -2
View File
@@ -85,7 +85,7 @@ Connection::Connection(std::unique_ptr<ghoul::io::Socket> s,
AuthenticationTopicKey,
[password](bool, const ghoul::Dictionary&, ghoul::MemoryPoolBase* pool) {
if (pool) {
void* ptr = pool->alloc(sizeof(AuthorizationTopic));
void* ptr = pool->allocate(sizeof(AuthorizationTopic));
return new (ptr) AuthorizationTopic(password);
}
else {
@@ -139,7 +139,7 @@ void Connection::handleMessage(const std::string& message) {
message.end(),
sanitizedString.begin(),
[](wchar_t c) {
return std::isprint(c, std::locale("")) ? c : ' ';
return std::isprint(c, std::locale("")) ? char(c) : ' ';
}
);
LERROR(fmt::format("Could not parse JSON: '{}'", sanitizedString));
@@ -207,10 +207,14 @@ void Connection::handleJson(const nlohmann::json& json) {
}
void Connection::sendMessage(const std::string& message) {
ZoneScoped
_socket->putMessage(message);
}
void Connection::sendJson(const nlohmann::json& json) {
ZoneScoped
sendMessage(json.dump());
}
@@ -303,12 +303,10 @@ void FlightControllerTopic::changeFocus(const nlohmann::json& json) const {
fmt::format("Could not find {} key in JSON. JSON was:\n{}", FocusKey, j)
);
if (json.find(AimKey) == json.end()) {
const std::string j = json;
LWARNING(
fmt::format("Could not find {} key in JSON. JSON was:\n{}", AimKey, j)
);
if (json.find(AnchorKey) == json.end()) {
const std::string j = json;
LWARNING(fmt::format(
"Could not find {} key in JSON. JSON was:\n{}", AnchorKey, j
));
+5 -3
View File
@@ -30,7 +30,6 @@
#include <openspace/query/query.h>
#include <openspace/util/timemanager.h>
#include <ghoul/logging/logmanager.h>
#include <optional>
namespace {
constexpr const char* EventKey = "event";
@@ -133,15 +132,18 @@ const json TimeTopic::getNextPrevDeltaTimeStepJson() {
}
void TimeTopic::sendCurrentTime() {
ZoneScoped
const json timeJson = {
{ "time", global::timeManager.time().ISO8601() }
};
_connection->sendJson(wrappedPayload(timeJson));
const json payload = wrappedPayload(timeJson);
_connection->sendJson(payload);
_lastUpdateTime = std::chrono::system_clock::now();
}
void TimeTopic::sendFullTimeData() {
const std::string currentTime = global::timeManager.time().ISO8601();
std::string_view currentTime = global::timeManager.time().ISO8601();
const double deltaTime = global::timeManager.deltaTime();
const double targetDeltaTime = global::timeManager.targetDeltaTime();
const bool isPaused = global::timeManager.isPaused();
+5
View File
@@ -26,6 +26,7 @@
#include <modules/server/servermodule.h>
#include <openspace/json.h>
#include <ghoul/misc/profiling.h>
namespace openspace {
@@ -35,6 +36,8 @@ void Topic::initialize(Connection* connection, size_t topicId) {
}
nlohmann::json Topic::wrappedPayload(const nlohmann::json& payload) const {
ZoneScoped
// TODO: add message time
nlohmann::json j = {
{ "topic", _topicId },
@@ -44,6 +47,8 @@ nlohmann::json Topic::wrappedPayload(const nlohmann::json& payload) const {
}
nlohmann::json Topic::wrappedError(std::string message, int code) {
ZoneScoped
nlohmann::json j = {
{ "topic", _topicId },
{ "status", "error" },
+4 -19
View File
@@ -36,6 +36,7 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/templatefactory.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -811,23 +812,8 @@ void RenderableStars::renderPSFToTexture() {
GLint defaultFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
GLint m_viewport[4];
glGetIntegerv(GL_VIEWPORT, m_viewport);
// Saving current OpenGL state
GLenum blendEquationRGB;
GLenum blendEquationAlpha;
GLenum blendDestAlpha;
GLenum blendDestRGB;
GLenum blendSrcAlpha;
GLenum blendSrcRGB;
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
// GLint m_viewport[4];
// global::renderEngine.openglStateCache().viewPort(m_viewport);
// Creates the FBO for the calculations
GLuint psfFBO;
@@ -929,8 +915,7 @@ void RenderableStars::renderPSFToTexture() {
//glDeleteFramebuffers(1, &convolveFBO);
// Restores OpenGL blending state
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
global::renderEngine.openglStateCache().resetBlendState();
}
void RenderableStars::render(const RenderData& data, RendererTasks&) {
@@ -35,6 +35,7 @@
#include <ghoul/font/font.h>
#include <ghoul/font/fontmanager.h>
#include <ghoul/font/fontrenderer.h>
#include <ghoul/misc/profiling.h>
#include <chrono>
namespace {
@@ -178,6 +179,8 @@ DashboardItemInstruments::DashboardItemInstruments(const ghoul::Dictionary& dict
}
void DashboardItemInstruments::render(glm::vec2& penPosition) {
ZoneScoped
double currentTime = global::timeManager.time().j2000Seconds();
if (!ImageSequencer::ref().isReady()) {
@@ -227,7 +230,7 @@ void DashboardItemInstruments::render(glm::vec2& penPosition) {
ghoul::fontrendering::CrDirection::Down
);
std::string str = SpiceManager::ref().dateFromEphemerisTime(
std::string_view str = SpiceManager::ref().dateFromEphemerisTime(
sequencer.nextCaptureTime(global::timeManager.time().j2000Seconds()),
"YYYY MON DD HR:MN:SC"
);
@@ -332,7 +335,6 @@ glm::vec2 DashboardItemInstruments::size() const {
if (remaining > 0) {
using FR = ghoul::fontrendering::FontRenderer;
FR& renderer = FR::defaultRenderer();
std::string progress = progressToStr(25, t);
size = addToBoundingbox(
@@ -65,13 +65,6 @@ namespace {
"ProjectorMatrix", "ModelTransform"
};
constexpr openspace::properties::Property::PropertyInfo ColorTextureInfo = {
"ColorTexture",
"Color Base Texture",
"This is the path to a local image file that is used as the base texture for the "
"model on which the image projections are layered."
};
constexpr openspace::properties::Property::PropertyInfo PerformShadingInfo = {
"PerformShading",
"Perform Shading",
@@ -107,12 +100,6 @@ documentation::Documentation RenderableModelProjection::Documentation() {
Optional::No,
"Contains information about projecting onto this planet."
},
{
ColorTextureInfo.identifier,
new StringVerifier,
Optional::No,
ColorTextureInfo.description
},
{
PerformShadingInfo.identifier,
new BoolVerifier,
@@ -134,7 +121,6 @@ documentation::Documentation RenderableModelProjection::Documentation() {
RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _colorTexturePath(ColorTextureInfo)
, _performShading(PerformShadingInfo, true)
{
documentation::testSpecificationAndThrow(
@@ -146,16 +132,8 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di
Dictionary geometryDictionary = dictionary.value<Dictionary>(keyGeometry);
_geometry = modelgeometry::ModelGeometry::createFromDictionary(geometryDictionary);
_colorTexturePath = absPath(dictionary.value<std::string>(
ColorTextureInfo.identifier
));
addPropertySubOwner(_geometry.get());
addPropertySubOwner(_projectionComponent);
addProperty(_colorTexturePath);
_colorTexturePath.onChange(std::bind(&RenderableModelProjection::loadTextures, this));
_projectionComponent.initialize(
identifier(),
dictionary.value<ghoul::Dictionary>(keyProjection)
@@ -175,8 +153,7 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di
RenderableModelProjection::~RenderableModelProjection() {} // NOLINT
bool RenderableModelProjection::isReady() const {
return (_programObject != nullptr) && (_baseTexture != nullptr) &&
_projectionComponent.isReady();
return (_programObject != nullptr) && _projectionComponent.isReady();
}
void RenderableModelProjection::initializeGL() {
@@ -220,7 +197,6 @@ void RenderableModelProjection::initializeGL() {
DepthFboUniformNames
);
loadTextures();
_projectionComponent.initializeGL();
float bs = boundingSphere();
@@ -234,7 +210,6 @@ void RenderableModelProjection::deinitializeGL() {
}
_geometry = nullptr;
_baseTexture = nullptr;
_projectionComponent.deinitialize();
@@ -301,7 +276,7 @@ void RenderableModelProjection::render(const RenderData& data, RendererTasks&) {
ghoul::opengl::TextureUnit baseUnit;
baseUnit.activate();
_baseTexture->bind();
_geometry->bindTexture();
_programObject->setUniform(_mainUniformCache.baseTexture, baseUnit);
ghoul::opengl::TextureUnit projectionUnit;
@@ -489,20 +464,4 @@ void RenderableModelProjection::project() {
_shouldCapture = false;
}
bool RenderableModelProjection::loadTextures() {
_baseTexture = nullptr;
if (!_colorTexturePath.value().empty()) {
_baseTexture = ghoul::io::TextureReader::ref().loadTexture(
absPath(_colorTexturePath)
);
if (_baseTexture) {
LDEBUG(fmt::format("Loaded texture from '{}'", absPath(_colorTexturePath)));
_baseTexture->uploadTexture();
_baseTexture->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap);
}
}
return _baseTexture != nullptr;
}
} // namespace openspace
@@ -31,6 +31,7 @@
#include <modules/spacecraftinstruments/util/projectioncomponent.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/vector/vec3property.h>
#include <ghoul/misc/managedmemoryuniqueptr.h>
#include <ghoul/opengl/uniformcache.h>
namespace ghoul::opengl {
@@ -65,7 +66,6 @@ public:
static documentation::Documentation Documentation();
private:
bool loadTextures();
void attitudeParameters(double time);
void imageProjectGPU(const ghoul::opengl::Texture& projectionTexture);
@@ -73,8 +73,6 @@ private:
ProjectionComponent _projectionComponent;
properties::StringProperty _colorTexturePath;
std::unique_ptr<ghoul::opengl::ProgramObject> _programObject;
UniformCache(performShading, directionToSunViewSpace, modelViewTransform,
projectionTransform, projectionFading, baseTexture,
@@ -86,9 +84,7 @@ private:
std::unique_ptr<ghoul::opengl::ProgramObject> _depthFboProgramObject;
UniformCache(ProjectorMatrix, ModelTransform) _depthFboUniformCache;
std::unique_ptr<ghoul::opengl::Texture> _baseTexture;
std::unique_ptr<modelgeometry::ModelGeometry> _geometry;
ghoul::mm_unique_ptr<modelgeometry::ModelGeometry> _geometry;
glm::dmat3 _instrumentMatrix = glm::dmat3(1.0);
+3 -2
View File
@@ -37,6 +37,7 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/assert.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/memorypool.h>
#include <ghoul/misc/templatefactory.h>
namespace {
@@ -80,7 +81,7 @@ void SyncModule::internalInitialize(const ghoul::Dictionary& configuration) {
"HttpSynchronization",
[this](bool, const ghoul::Dictionary& dictionary, ghoul::MemoryPoolBase* pool) {
if (pool) {
void* ptr = pool->alloc(sizeof(HttpSynchronization));
void* ptr = pool->allocate(sizeof(HttpSynchronization));
return new (ptr) HttpSynchronization(
dictionary,
_synchronizationRoot,
@@ -101,7 +102,7 @@ void SyncModule::internalInitialize(const ghoul::Dictionary& configuration) {
"UrlSynchronization",
[this](bool, const ghoul::Dictionary& dictionary, ghoul::MemoryPoolBase* pool) {
if (pool) {
void* ptr = pool->alloc(sizeof(UrlSynchronization));
void* ptr = pool->allocate(sizeof(UrlSynchronization));
return new (ptr) UrlSynchronization(
dictionary,
_synchronizationRoot
+3 -3
View File
@@ -112,12 +112,12 @@ ghoul::Dictionary RawVolumeMetadata::dictionary() {
}
if (hasTime) {
std::string timeString = Time(time).ISO8601();
std::string_view timeString = Time(time).ISO8601();
// Do not include time offset in time string
if (timeString.back() == 'Z') {
timeString.pop_back();
timeString = timeString.substr(0, timeString.size() - 1);
}
dict.setValue<std::string>(KeyTime, timeString);
dict.setValue<std::string>(KeyTime, std::string(timeString));
}
return dict;
}
+9
View File
@@ -25,7 +25,16 @@
#ifndef __OPENSPACE_MODULE_WEBBROWSER___CEF_HOST___H__
#define __OPENSPACE_MODULE_WEBBROWSER___CEF_HOST___H__
#ifdef WIN32
#pragma warning(push)
#pragma warning(disable : 4100)
#endif // WIN32
#include <include/wrapper/cef_helpers.h>
#ifdef WIN32
#pragma warning(pop)
#endif // WIN32
#include <string>
struct CefSettingsTraits;
-1
View File
@@ -29,7 +29,6 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/profiling.h>
#include <fmt/format.h>
#include <include/wrapper/cef_helpers.h>
#ifdef __APPLE__
#include <include/wrapper/cef_library_loader.h>