mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-25 21:48:57 -05:00
Merge branch 'master' into thesis/2018/exoplanets
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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, ¤tLineWidth);
|
||||
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, ¤tLineWidth);
|
||||
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, ¤tLineWidth);
|
||||
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, ¤tLineWidth);
|
||||
GLboolean isLineSmoothEnabled = glIsEnabled(GL_LINE_SMOOTH);
|
||||
|
||||
GLenum currentDepthFunction;
|
||||
glGetIntegerv(GL_DEPTH_FUNC, ¤tDepthFunction);
|
||||
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&) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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, ¤tLineWidth);
|
||||
|
||||
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.");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, ¤tLineWidth);
|
||||
|
||||
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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -114,6 +114,8 @@ int LayerGroup::update() {
|
||||
}
|
||||
|
||||
Layer* LayerGroup::addLayer(const ghoul::Dictionary& layerDict) {
|
||||
ZoneScoped
|
||||
|
||||
documentation::TestResult res = documentation::testSpecification(
|
||||
Layer::Documentation(),
|
||||
layerDict
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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_)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ struct TileProvider : public properties::PropertyOwner {
|
||||
|
||||
std::string name;
|
||||
|
||||
unsigned int uniqueIdentifier = 0;
|
||||
uint16_t uniqueIdentifier = 0;
|
||||
bool isInitialized = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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] = ' ';
|
||||
|
||||
@@ -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, ' ');
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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
|
||||
));
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user