mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-23 05:19:18 -06:00
Merge master into issue/1669 to fix build conflict
This commit is contained in:
@@ -132,8 +132,6 @@ if (MSVC)
|
||||
set(GHOUL_OPTIMIZATION_ENABLE_OTHER_OPTIMIZATIONS ${OPENSPACE_OPTIMIZATION_ENABLE_OTHER_OPTIMIZATIONS} CACHE BOOL "" FORCE)
|
||||
endif ()
|
||||
|
||||
option(OPENSPACE_WITH_ABUFFER_RENDERER "Compile ABuffer Renderer" OFF)
|
||||
|
||||
if (UNIX)
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -stdlib=libc++")
|
||||
|
||||
@@ -115,6 +115,7 @@ PropertiesDialog QListWidget {
|
||||
*/
|
||||
AssetsDialog QTreeView {
|
||||
min-width: 40em;
|
||||
min-height: 40em;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -312,8 +312,24 @@ void LauncherWindow::setBackgroundImage(const std::string& syncPath) {
|
||||
std::mt19937 g(rd());
|
||||
std::shuffle(files.begin(), files.end(), g);
|
||||
// We know there has to be at least one folder, so it's fine to just pick the first
|
||||
std::string image = files.front();
|
||||
_backgroundImage->setPixmap(QPixmap(QString::fromStdString(image)));
|
||||
while (!files.empty()) {
|
||||
std::string p = files.front();
|
||||
if (std::filesystem::path(p).extension() == ".png") {
|
||||
// If the top path starts with the png extension, we have found our candidate
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// There shouldn't be any non-png images in here, but you never know. So we
|
||||
// just remove non-image files here
|
||||
files.erase(files.begin());
|
||||
}
|
||||
}
|
||||
|
||||
// There better be at least one file left, but just in in case
|
||||
if (!files.empty()) {
|
||||
std::string image = files.front();
|
||||
_backgroundImage->setPixmap(QPixmap(QString::fromStdString(image)));
|
||||
}
|
||||
}
|
||||
|
||||
void LauncherWindow::populateProfilesList(std::string preset) {
|
||||
|
||||
@@ -129,10 +129,7 @@ AssetsDialog::AssetsDialog(openspace::Profile& profile, const std::string& asset
|
||||
{
|
||||
setWindowTitle("Assets");
|
||||
_assetTreeModel.importModelData(assetBasePath, userAssetBasePath);
|
||||
createWidgets();
|
||||
}
|
||||
|
||||
void AssetsDialog::createWidgets() {
|
||||
QBoxLayout* layout = new QVBoxLayout(this);
|
||||
{
|
||||
QLabel* heading = new QLabel("Select assets from /data/assets");
|
||||
@@ -173,18 +170,19 @@ void AssetsDialog::createWidgets() {
|
||||
nRows,
|
||||
_assetTreeModel.index(-1, 0)
|
||||
);
|
||||
layout->addWidget(_assetTree);
|
||||
layout->addWidget(_assetTree, 4);
|
||||
}
|
||||
{
|
||||
QWidget* box = new QWidget;
|
||||
QBoxLayout* boxLayout = new QVBoxLayout(box);
|
||||
QLabel* summaryHeading = new QLabel("Selection summary");
|
||||
summaryHeading->setObjectName("heading");
|
||||
layout->addWidget(summaryHeading);
|
||||
}
|
||||
{
|
||||
boxLayout->addWidget(summaryHeading);
|
||||
_summary = new QTextEdit;
|
||||
_summary->setReadOnly(true);
|
||||
_summary->setText(createTextSummary());
|
||||
layout->addWidget(_summary);
|
||||
boxLayout->addWidget(_summary);
|
||||
layout->addWidget(box, 1);
|
||||
}
|
||||
|
||||
layout->addWidget(new Line);
|
||||
|
||||
@@ -20,7 +20,7 @@ local Gaia = {
|
||||
XAxis = { 1.0, 0.0, 0.0 },
|
||||
XAxisOrthogonal = true,
|
||||
YAxis = "Sun",
|
||||
YAxisInverted = true
|
||||
YAxisInvert = true
|
||||
},
|
||||
Scale = {
|
||||
Type = "StaticScale",
|
||||
|
||||
@@ -11,7 +11,7 @@ local trail = asset.syncedResource({
|
||||
|
||||
local GaiaTrail = {
|
||||
Identifier = "GaiaTrail",
|
||||
Parent = earthTransforms.EarthBarycenter.Identifier,
|
||||
Parent = earthTransforms.EarthCenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderableTrailTrajectory",
|
||||
Translation = {
|
||||
@@ -36,7 +36,7 @@ local GaiaTrail = {
|
||||
|
||||
local GaiaTrailEclip = {
|
||||
Identifier = "GaiaTrail_Eclip",
|
||||
Parent = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
Parent = sunTransforms.SunCenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderableTrailTrajectory",
|
||||
Enabled = false,
|
||||
|
||||
@@ -11,7 +11,7 @@ local trail = asset.syncedResource({
|
||||
|
||||
local GaiaPosition = {
|
||||
Identifier = "GaiaPosition",
|
||||
Parent = earthTransforms.EarthBarycenter.Identifier,
|
||||
Parent = earthTransforms.EarthCenter.Identifier,
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "HorizonsTranslation",
|
||||
|
||||
@@ -42,7 +42,6 @@ local Atmosphere = {
|
||||
G = 0.85
|
||||
},
|
||||
Debug = {
|
||||
-- PreCalculatedTextureScale is a float from 1.0 to N, with N > 0.0 and N in Naturals (i.e., 1, 2, 3, 4, 5....)
|
||||
PreCalculatedTextureScale = 1.0,
|
||||
SaveCalculatedTextures = false
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ local Atmosphere = {
|
||||
G = 0.85
|
||||
},
|
||||
Debug = {
|
||||
-- PreCalculatedTextureScale is a float from 1.0 to N, with N > 0.0 and N in Naturals (i.e., 1, 2, 3, 4, 5....)
|
||||
PreCalculatedTextureScale = 1.0,
|
||||
SaveCalculatedTextures = false
|
||||
}
|
||||
|
||||
@@ -20,6 +20,24 @@ local SolarSystemBarycenter = {
|
||||
}
|
||||
}
|
||||
|
||||
local SunCenter = {
|
||||
Identifier = "SunCenter",
|
||||
Parent = SolarSystemBarycenter.Identifier,
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "SpiceTranslation",
|
||||
Target = "SUN",
|
||||
Observer = "SSB"
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "SUN Center",
|
||||
Path = "/Solar System/Sun",
|
||||
Description = [[Spice frame for the Sun]],
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
-- Spice frame for the Sun
|
||||
local SunIAU = {
|
||||
Identifier = "SunIAU",
|
||||
@@ -67,7 +85,7 @@ local SunECLIPJ2000 = {
|
||||
}
|
||||
}
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { SolarSystemBarycenter, SunIAU, SunECLIPJ2000 })
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { SolarSystemBarycenter, SunCenter, SunIAU, SunECLIPJ2000 })
|
||||
|
||||
|
||||
asset.meta = {
|
||||
|
||||
@@ -67,7 +67,7 @@ local addCartesianAxes = function (specification)
|
||||
Parent = parent,
|
||||
Transform = {
|
||||
Scale = {
|
||||
Type = "StaticScale",
|
||||
Type = "NonUniformStaticScale",
|
||||
Scale = scale
|
||||
},
|
||||
Translation = {
|
||||
|
||||
Submodule ext/ghoul updated: 2ffa7b7f7a...57e96a6a8d
@@ -98,18 +98,17 @@ struct Configuration {
|
||||
bool usePerProfileCache = false;
|
||||
|
||||
bool isRenderingOnMasterDisabled = false;
|
||||
glm::dvec3 globalRotation = glm::dvec3(0.0);
|
||||
glm::dvec3 screenSpaceRotation = glm::dvec3(0.0);
|
||||
glm::dvec3 masterRotation = glm::dvec3(0.0);
|
||||
glm::vec3 globalRotation = glm::vec3(0.0);
|
||||
glm::vec3 screenSpaceRotation = glm::vec3(0.0);
|
||||
glm::vec3 masterRotation = glm::vec3(0.0);
|
||||
bool isConsoleDisabled = false;
|
||||
bool bypassLauncher = false;
|
||||
|
||||
std::map<std::string, ghoul::Dictionary> moduleConfigurations;
|
||||
|
||||
std::string renderingMethod = "Framebuffer";
|
||||
|
||||
struct OpenGLDebugContext {
|
||||
bool isActive = false;
|
||||
bool printStacktrace = false;
|
||||
bool isSynchronous = true;
|
||||
struct IdentifierFilter {
|
||||
std::string type;
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___ABUFFERRENDERER___H__
|
||||
#define __OPENSPACE_CORE___ABUFFERRENDERER___H__
|
||||
|
||||
#ifdef OPENSPACE_WITH_ABUFFER_RENDERER
|
||||
|
||||
#include <openspace/rendering/renderer.h>
|
||||
#include <openspace/rendering/raycasterlistener.h>
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ghoul::filesystem { class File; }
|
||||
|
||||
namespace ghoul::opengl {
|
||||
class ProgramObject;
|
||||
class Texture;
|
||||
} // namespace ghoul::opengl
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct RaycasterTask;
|
||||
class RenderableVolume;
|
||||
class Camera;
|
||||
class Scene;
|
||||
struct RaycastData;
|
||||
|
||||
class ABufferRenderer : public Renderer, public RaycasterListener {
|
||||
public:
|
||||
virtual ~ABufferRenderer() = default;
|
||||
|
||||
void initialize() override;
|
||||
void deinitialize() override;
|
||||
|
||||
void setResolution(glm::ivec2 res) override;
|
||||
void setNAaSamples(int nAaSamples) override;
|
||||
void setBlurrinessLevel(int level) override;
|
||||
void setHDRExposure(float hdrExposure) override;
|
||||
void setGamma(float gamma) override;
|
||||
void setMaxWhite(float maxWhite) override;
|
||||
void setToneMapOperator(int tmOp) override;
|
||||
void setBloomThreMin(float minV) override;
|
||||
void setBloomThreMax(float maxV) override;
|
||||
void setBloomOrigFactor(float origFactor) override;
|
||||
void setBloomNewFactor(float newFactor) override;
|
||||
void setKey(float key) override;
|
||||
void setYwhite(float white) override;
|
||||
void setTmoSaturation(float sat) override;
|
||||
void setHue(float hue) override;
|
||||
void setValue(float value) override;
|
||||
void setSaturation(float sat) override;
|
||||
void setLightness(float lightness) override;
|
||||
void setColorSpace(unsigned int colorspace) override;
|
||||
|
||||
void enableBloom(bool enable) override;
|
||||
void enableHistogram(bool enable) override;
|
||||
|
||||
int nAaSamples() const override;
|
||||
const std::vector<double>& mSSAPattern() const override;
|
||||
|
||||
using Renderer::preRaycast;
|
||||
void preRaycast(const RaycasterTask& raycasterTask);
|
||||
using Renderer::postRaycast;
|
||||
void postRaycast(const RaycasterTask& raycasterTask);
|
||||
|
||||
void update() override;
|
||||
void render(Scene* scene, Camera* camera, float blackoutFactor) override;
|
||||
|
||||
/**
|
||||
* Update render data
|
||||
* Responsible for calling renderEngine::setRenderData
|
||||
*/
|
||||
virtual void updateRendererData() override;
|
||||
virtual void raycastersChanged(VolumeRaycaster& raycaster,
|
||||
IsAttached attached) override;
|
||||
|
||||
private:
|
||||
void clear();
|
||||
void updateResolution();
|
||||
void updateRaycastData();
|
||||
void updateResolveDictionary();
|
||||
void updateMSAASamplingPattern();
|
||||
void saveTextureToMemory(GLenum color_buffer_attachment, int width, int height,
|
||||
std::vector<double> & memory) const;
|
||||
|
||||
glm::ivec2 _resolution = glm::ivec2(0);
|
||||
|
||||
bool _dirtyResolution = true;
|
||||
bool _dirtyRendererData = true;
|
||||
bool _dirtyRaycastData = true;
|
||||
bool _dirtyResolveDictionary = true;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _resolveProgram = nullptr;
|
||||
|
||||
/**
|
||||
* When a volume is attached or detached from the scene graph,
|
||||
* the resolve program needs to be recompiled.
|
||||
* The _volumes map keeps track of which volumes that can
|
||||
* be rendered using the current resolve program, along with their raycast data
|
||||
* (id, namespace, etc)
|
||||
*/
|
||||
std::map<VolumeRaycaster*, RaycastData> _raycastData;
|
||||
std::map<
|
||||
VolumeRaycaster*, std::unique_ptr<ghoul::opengl::ProgramObject>
|
||||
> _boundsPrograms;
|
||||
std::vector<std::string> _helperPaths;
|
||||
|
||||
ghoul::Dictionary _resolveDictionary;
|
||||
|
||||
GLuint _mainColorTexture;
|
||||
GLuint _mainDepthTexture;
|
||||
|
||||
GLuint _mainFramebuffer;
|
||||
GLuint _screenQuad;
|
||||
GLuint _anchorPointerTexture;
|
||||
GLuint _anchorPointerTextureInitializer;
|
||||
GLuint _atomicCounterBuffer;
|
||||
GLuint _fragmentBuffer;
|
||||
GLuint _fragmentTexture;
|
||||
GLuint _vertexPositionBuffer;
|
||||
int _nAaSamples;
|
||||
int _blurrinessLevel = 1;
|
||||
|
||||
float _hdrExposure = 0.4f;
|
||||
float _hdrBackground = 2.8f;
|
||||
float _gamma = 2.2f;
|
||||
float _maxWhite = 1.f;
|
||||
float _blackoutFactor;
|
||||
bool _bloomEnabled = false;
|
||||
float _bloomThresholdMin = 0.0;
|
||||
float _bloomThresholdMax = 1.0;
|
||||
float _bloomOrigFactor = 1.0;
|
||||
float _bloomNewFactor = 1.0;
|
||||
int _toneMapOperator = 0;
|
||||
bool _histogramEnabled = false;
|
||||
int _numberOfBins = 1024; // JCC TODO: Add a parameter control for this.
|
||||
float _tmoKey = 0.18f;
|
||||
float _tmoYwhite = 1e6f;
|
||||
float _tmoSaturation = 1.0f;
|
||||
float _hue = 1.f;
|
||||
float _saturation = 1.f;
|
||||
float _value = 1.f;
|
||||
float _lightness = 1.f;
|
||||
unsigned int _colorSpace = 1;
|
||||
|
||||
std::vector<double> _mSAAPattern;
|
||||
|
||||
ghoul::Dictionary _rendererData;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // OPENSPACE_WITH_ABUFFER_RENDERER
|
||||
|
||||
#endif // __OPENSPACE_CORE___ABUFFERRENDERER___H__
|
||||
@@ -51,8 +51,6 @@ public:
|
||||
const DeferredcastData& /*deferredData*/,
|
||||
ghoul::opengl::ProgramObject& /*program*/) {};
|
||||
|
||||
virtual std::filesystem::path deferredcastPath() const = 0;
|
||||
|
||||
virtual std::filesystem::path deferredcastVSPath() const = 0;
|
||||
|
||||
virtual std::filesystem::path deferredcastFSPath() const = 0;
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#ifndef __OPENSPACE_CORE___FRAMEBUFFERRENDERER___H__
|
||||
#define __OPENSPACE_CORE___FRAMEBUFFERRENDERER___H__
|
||||
|
||||
#include <openspace/rendering/renderer.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/raycasterlistener.h>
|
||||
#include <openspace/rendering/deferredcasterlistener.h>
|
||||
|
||||
@@ -56,14 +54,14 @@ struct RaycasterTask;
|
||||
class Scene;
|
||||
struct UpdateStructures;
|
||||
|
||||
class FramebufferRenderer : public Renderer, public RaycasterListener,
|
||||
class FramebufferRenderer : public RaycasterListener,
|
||||
public DeferredcasterListener
|
||||
{
|
||||
public:
|
||||
virtual ~FramebufferRenderer() = default;
|
||||
|
||||
void initialize() override;
|
||||
void deinitialize() override;
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
|
||||
void updateResolution();
|
||||
void updateRaycastData();
|
||||
@@ -72,33 +70,33 @@ public:
|
||||
void updateFXAA();
|
||||
void updateDownscaledVolume();
|
||||
|
||||
void setResolution(glm::ivec2 res) override;
|
||||
void setHDRExposure(float hdrExposure) override;
|
||||
void setGamma(float gamma) override;
|
||||
void setHue(float hue) override;
|
||||
void setValue(float value) override;
|
||||
void setSaturation(float sat) override;
|
||||
void setResolution(glm::ivec2 res);
|
||||
void setHDRExposure(float hdrExposure);
|
||||
void setGamma(float gamma);
|
||||
void setHue(float hue);
|
||||
void setValue(float value);
|
||||
void setSaturation(float sat);
|
||||
|
||||
void enableFXAA(bool enable) override;
|
||||
void setDisableHDR(bool disable) override;
|
||||
void enableFXAA(bool enable);
|
||||
void setDisableHDR(bool disable);
|
||||
|
||||
void update() override;
|
||||
void update();
|
||||
void performRaycasterTasks(const std::vector<RaycasterTask>& tasks,
|
||||
const glm::ivec4& viewport);
|
||||
void performDeferredTasks(const std::vector<DeferredcasterTask>& tasks,
|
||||
const glm::ivec4& viewport);
|
||||
void render(Scene* scene, Camera* camera, float blackoutFactor) override;
|
||||
void render(Scene* scene, Camera* camera, float blackoutFactor);
|
||||
|
||||
/**
|
||||
* Update render data
|
||||
* Responsible for calling renderEngine::setRenderData
|
||||
*/
|
||||
virtual void updateRendererData() override;
|
||||
virtual void updateRendererData();
|
||||
|
||||
virtual void raycastersChanged(VolumeRaycaster& raycaster,
|
||||
RaycasterListener::IsAttached attached) override;
|
||||
RaycasterListener::IsAttached attached);
|
||||
virtual void deferredcastersChanged(Deferredcaster& deferredcaster,
|
||||
DeferredcasterListener::IsAttached isAttached) override;
|
||||
DeferredcasterListener::IsAttached isAttached);
|
||||
|
||||
private:
|
||||
using RaycasterProgObjMap = std::map<
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/vector/vec3property.h>
|
||||
#include <openspace/properties/triggerproperty.h>
|
||||
#include <openspace/rendering/framebufferrenderer.h>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
|
||||
@@ -54,7 +55,6 @@ namespace scripting { struct LuaLibrary; }
|
||||
class Camera;
|
||||
class RaycasterManager;
|
||||
class DeferredcasterManager;
|
||||
class Renderer;
|
||||
class Scene;
|
||||
class SceneManager;
|
||||
class ScreenLog;
|
||||
@@ -63,12 +63,6 @@ struct ShutdownInformation;
|
||||
|
||||
class RenderEngine : public properties::PropertyOwner {
|
||||
public:
|
||||
enum class RendererImplementation {
|
||||
Framebuffer = 0,
|
||||
ABuffer,
|
||||
Invalid
|
||||
};
|
||||
|
||||
RenderEngine();
|
||||
~RenderEngine();
|
||||
|
||||
@@ -80,9 +74,6 @@ public:
|
||||
Scene* scene();
|
||||
void updateScene();
|
||||
|
||||
const Renderer& renderer() const;
|
||||
RendererImplementation rendererImplementation() const;
|
||||
|
||||
ghoul::opengl::OpenGLStateCache& openglStateCache();
|
||||
|
||||
void updateShaderPrograms();
|
||||
@@ -120,24 +111,11 @@ public:
|
||||
|
||||
void removeRenderProgram(ghoul::opengl::ProgramObject* program);
|
||||
|
||||
/**
|
||||
* Set raycasting uniforms on the program object, and setup raycasting.
|
||||
*/
|
||||
void preRaycast(ghoul::opengl::ProgramObject& programObject);
|
||||
|
||||
/**
|
||||
* Tear down raycasting for the specified program object.
|
||||
*/
|
||||
void postRaycast(ghoul::opengl::ProgramObject& programObject);
|
||||
|
||||
/**
|
||||
* Set the camera to use for rendering
|
||||
*/
|
||||
void setCamera(Camera* camera);
|
||||
|
||||
|
||||
void setRendererFromString(const std::string& renderingMethod);
|
||||
|
||||
/**
|
||||
* Lets the renderer update the data to be brought into the rendererer programs
|
||||
* as a 'rendererData' variable in the dictionary.
|
||||
@@ -176,9 +154,6 @@ public:
|
||||
uint64_t frameNumber() const;
|
||||
|
||||
private:
|
||||
void setRenderer(std::unique_ptr<Renderer> renderer);
|
||||
RendererImplementation rendererFromString(const std::string& renderingMethod) const;
|
||||
|
||||
void renderScreenLog();
|
||||
void renderVersionInformation();
|
||||
void renderCameraInformation();
|
||||
@@ -188,8 +163,7 @@ private:
|
||||
Camera* _camera = nullptr;
|
||||
Scene* _scene = nullptr;
|
||||
|
||||
std::unique_ptr<Renderer> _renderer;
|
||||
RendererImplementation _rendererImplementation = RendererImplementation::Invalid;
|
||||
FramebufferRenderer _renderer;
|
||||
ghoul::Dictionary _rendererData;
|
||||
ghoul::Dictionary _resolveData;
|
||||
ScreenLog* _log = nullptr;
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___RENDERER___H__
|
||||
#define __OPENSPACE_CORE___RENDERER___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <vector>
|
||||
|
||||
namespace ghoul { class Dictionary; }
|
||||
namespace ghoul::filesystem { class File; }
|
||||
namespace ghoul::opengl {
|
||||
class ProgramObject;
|
||||
class Texture;
|
||||
} // namespace ghoul::opengl
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class RenderableVolume;
|
||||
class Camera;
|
||||
class Scene;
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
virtual ~Renderer() = default;
|
||||
|
||||
virtual void initialize() = 0;
|
||||
virtual void deinitialize() = 0;
|
||||
|
||||
virtual void setResolution(glm::ivec2 res) = 0;
|
||||
virtual void setHDRExposure(float hdrExposure) = 0;
|
||||
virtual void setGamma(float gamma) = 0;
|
||||
virtual void setHue(float hue) = 0;
|
||||
virtual void setValue(float value) = 0;
|
||||
virtual void setSaturation(float sat) = 0;
|
||||
virtual void enableFXAA(bool enable) = 0;
|
||||
virtual void setDisableHDR(bool disable) = 0;
|
||||
|
||||
/**
|
||||
* Set raycasting uniforms on the program object, and setup raycasting.
|
||||
*/
|
||||
virtual void preRaycast(ghoul::opengl::ProgramObject& /*programObject*/) {};
|
||||
|
||||
/**
|
||||
* Tear down raycasting for the specified program object.
|
||||
*/
|
||||
virtual void postRaycast(ghoul::opengl::ProgramObject& /*programObject*/) {};
|
||||
|
||||
|
||||
virtual void update() = 0;
|
||||
|
||||
virtual void render(Scene* scene, Camera* camera, float blackoutFactor) = 0;
|
||||
/**
|
||||
* Update render data
|
||||
* Responsible for calling renderEngine::setRenderData
|
||||
*/
|
||||
virtual void updateRendererData() = 0;
|
||||
};
|
||||
|
||||
} // openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___RENDERER___H__
|
||||
@@ -36,7 +36,7 @@ template<typename P>
|
||||
void ConcurrentJobManager<P>::enqueueJob(std::shared_ptr<Job<P>> job) {
|
||||
threadPool.enqueue([this, job]() {
|
||||
job->execute();
|
||||
std::lock_guard<std::mutex> lock(_finishedJobsMutex);
|
||||
std::lock_guard lock(_finishedJobsMutex);
|
||||
_finishedJobs.push(job);
|
||||
});
|
||||
}
|
||||
@@ -50,7 +50,7 @@ template<typename P>
|
||||
std::shared_ptr<Job<P>> ConcurrentJobManager<P>::popFinishedJob() {
|
||||
ghoul_assert(!_finishedJobs.empty(), "There is no finished job to pop!");
|
||||
|
||||
std::lock_guard<std::mutex> lock(_finishedJobsMutex);
|
||||
std::lock_guard lock(_finishedJobsMutex);
|
||||
return _finishedJobs.pop();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -57,16 +57,17 @@ struct ShadowRenderingStruct {
|
||||
|
||||
class AtmosphereDeferredcaster : public Deferredcaster {
|
||||
public:
|
||||
AtmosphereDeferredcaster(float textureScale,
|
||||
std::vector<ShadowConfiguration> shadowConfigArray, bool saveCalculatedTextures);
|
||||
virtual ~AtmosphereDeferredcaster() = default;
|
||||
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
void preRaycast(const RenderData& renderData, const DeferredcastData& deferredData,
|
||||
void preRaycast(const RenderData& data, const DeferredcastData& deferredData,
|
||||
ghoul::opengl::ProgramObject& program) override;
|
||||
void postRaycast(const RenderData& renderData, const DeferredcastData& deferredData,
|
||||
void postRaycast(const RenderData& data, const DeferredcastData& deferredData,
|
||||
ghoul::opengl::ProgramObject& program) override;
|
||||
|
||||
std::filesystem::path deferredcastPath() const override;
|
||||
std::filesystem::path deferredcastVSPath() const override;
|
||||
std::filesystem::path deferredcastFSPath() const override;
|
||||
std::filesystem::path helperPath() const override;
|
||||
@@ -75,82 +76,64 @@ public:
|
||||
|
||||
void update(const UpdateData&) override;
|
||||
|
||||
void preCalculateAtmosphereParam();
|
||||
void calculateAtmosphereParameters();
|
||||
|
||||
void setModelTransform(glm::dmat4 transform);
|
||||
void setTime(double time);
|
||||
void setAtmosphereRadius(float atmRadius);
|
||||
void setPlanetRadius(float planetRadius);
|
||||
void setPlanetAverageGroundReflectance(float averageGReflectance);
|
||||
void setPlanetGroundRadianceEmission(float groundRadianceEmission);
|
||||
void setRayleighHeightScale(float rayleighHeightScale);
|
||||
void enableOzone(bool enable);
|
||||
void setOzoneHeightScale(float ozoneHeightScale);
|
||||
void setMieHeightScale(float mieHeightScale);
|
||||
void setMiePhaseConstant(float miePhaseConstant);
|
||||
void setSunRadianceIntensity(float sunRadiance);
|
||||
void setRayleighScatteringCoefficients(glm::vec3 rayScattCoeff);
|
||||
void setOzoneExtinctionCoefficients(glm::vec3 ozoneExtCoeff);
|
||||
void setMieScatteringCoefficients(glm::vec3 mieScattCoeff);
|
||||
void setMieExtinctionCoefficients(glm::vec3 mieExtCoeff);
|
||||
void setEllipsoidRadii(glm::dvec3 radii);
|
||||
void setShadowConfigArray(std::vector<ShadowConfiguration> shadowConfigArray);
|
||||
void setHardShadows(bool enabled);
|
||||
void enableSunFollowing(bool enable);
|
||||
|
||||
void setPrecalculationTextureScale(float preCalculatedTexturesScale);
|
||||
void enablePrecalculationTexturesSaving();
|
||||
void setParameters(float atmosphereRadius, float planetRadius,
|
||||
float averageGroundReflectance, float groundRadianceEmission,
|
||||
float rayleighHeightScale, bool enableOzone, float ozoneHeightScale,
|
||||
float mieHeightScale, float miePhaseConstant, float sunRadiance,
|
||||
glm::vec3 rayScatteringCoefficients, glm::vec3 ozoneExtinctionCoefficients,
|
||||
glm::vec3 mieScatteringCoefficients, glm::vec3 mieExtinctionCoefficients,
|
||||
bool sunFollowing);
|
||||
|
||||
void setHardShadows(bool enabled);
|
||||
|
||||
private:
|
||||
void loadComputationPrograms();
|
||||
void unloadComputationPrograms();
|
||||
void createComputationTextures();
|
||||
void deleteComputationTextures();
|
||||
void deleteUnusedComputationTextures();
|
||||
void executeCalculations(GLuint quadCalcVAO, GLenum drawBuffers[1],
|
||||
GLsizei vertexSize);
|
||||
void step3DTexture(ghoul::opengl::ProgramObject& shaderProg, int layer,
|
||||
bool doCalculation);
|
||||
void loadAtmosphereDataIntoShaderProgram(ghoul::opengl::ProgramObject& shaderProg);
|
||||
void step3DTexture(ghoul::opengl::ProgramObject& prg, int layer);
|
||||
|
||||
void calculateTransmittance();
|
||||
GLuint calculateDeltaE();
|
||||
std::pair<GLuint, GLuint> calculateDeltaS();
|
||||
void calculateIrradiance();
|
||||
void calculateInscattering(GLuint deltaSRayleigh, GLuint deltaSMie);
|
||||
void calculateDeltaJ(int scatteringOrder,
|
||||
ghoul::opengl::ProgramObject& program, GLuint deltaJ, GLuint deltaE,
|
||||
GLuint deltaSRayleigh, GLuint deltaSMie);
|
||||
void calculateDeltaE(int scatteringOrder,
|
||||
ghoul::opengl::ProgramObject& program, GLuint deltaE, GLuint deltaSRayleigh,
|
||||
GLuint deltaSMie);
|
||||
void calculateDeltaS(int scatteringOrder,
|
||||
ghoul::opengl::ProgramObject& program, GLuint deltaSRayleigh, GLuint deltaJ);
|
||||
void calculateIrradiance(int scatteringOrder,
|
||||
ghoul::opengl::ProgramObject& program, GLuint deltaE);
|
||||
void calculateInscattering(int scatteringOrder,
|
||||
ghoul::opengl::ProgramObject& program, GLuint deltaSRayleigh);
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _transmittanceProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceSupTermsProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceFinalProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _inScatteringProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _inScatteringSupTermsProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaEProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaSProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaSSupTermsProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaJProgramObject;
|
||||
|
||||
UniformCache(cullAtmosphere, Rg, Rt, groundRadianceEmission, HR, betaRayleigh, HM,
|
||||
betaMieExtinction, mieG, sunRadiance, ozoneLayerEnabled, HO, betaOzoneExtinction,
|
||||
SAMPLES_R, SAMPLES_MU, SAMPLES_MU_S, SAMPLES_NU, inverseModelTransformMatrix,
|
||||
modelTransformMatrix, projectionToModelTransformMatrix,
|
||||
viewToWorldMatrix, camPosObj, sunDirectionObj, hardShadows,
|
||||
transmittanceTexture, irradianceTexture, inscatterTexture) _uniformCache;
|
||||
|
||||
GLuint _transmittanceTableTexture = 0;
|
||||
GLuint _irradianceTableTexture = 0;
|
||||
GLuint _inScatteringTableTexture = 0;
|
||||
GLuint _deltaETableTexture = 0;
|
||||
GLuint _deltaSRayleighTableTexture = 0;
|
||||
GLuint _deltaSMieTableTexture = 0;
|
||||
GLuint _deltaJTableTexture = 0;
|
||||
modelTransformMatrix, projectionToModelTransform, viewToWorldMatrix,
|
||||
camPosObj, sunDirectionObj, hardShadows, transmittanceTexture, irradianceTexture,
|
||||
inscatterTexture) _uniformCache;
|
||||
|
||||
ghoul::opengl::TextureUnit _transmittanceTableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _irradianceTableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _inScatteringTableTextureUnit;
|
||||
|
||||
GLuint _transmittanceTableTexture = 0;
|
||||
GLuint _irradianceTableTexture = 0;
|
||||
GLuint _inScatteringTableTexture = 0;
|
||||
|
||||
// Atmosphere Data
|
||||
bool _atmosphereCalculated = false;
|
||||
bool _ozoneEnabled = false;
|
||||
bool _sunFollowingCameraEnabled = false;
|
||||
float _atmosphereRadius = 0.f;
|
||||
float _atmospherePlanetRadius = 0.f;
|
||||
float _planetAverageGroundReflectance = 0.f;
|
||||
float _planetGroundRadianceEmission = 0.f;
|
||||
float _averageGroundReflectance = 0.f;
|
||||
float _groundRadianceEmission = 0.f;
|
||||
float _rayleighHeightScale = 0.f;
|
||||
float _ozoneHeightScale = 0.f;
|
||||
float _mieHeightScale = 0.f;
|
||||
@@ -161,34 +144,33 @@ private:
|
||||
glm::vec3 _ozoneExtinctionCoeff = glm::vec3(0.f);
|
||||
glm::vec3 _mieScatteringCoeff = glm::vec3(0.f);
|
||||
glm::vec3 _mieExtinctionCoeff = glm::vec3(0.f);
|
||||
glm::dvec3 _ellipsoidRadii = glm::dvec3(0.0);
|
||||
|
||||
// Atmosphere Textures Dimmensions
|
||||
glm::ivec2 _transmittanceTableSize = glm::ivec2(256, 64);
|
||||
glm::ivec2 _irradianceTableSize = glm::ivec2(64, 16);
|
||||
glm::ivec2 _deltaETableSize = glm::ivec2(64, 16);
|
||||
int _r_samples = 32;
|
||||
int _mu_samples = 128;
|
||||
int _mu_s_samples = 32;
|
||||
int _nu_samples = 8;
|
||||
const glm::ivec2 _transmittanceTableSize;
|
||||
const glm::ivec2 _irradianceTableSize;
|
||||
const glm::ivec2 _deltaETableSize;
|
||||
const int _muSSamples;
|
||||
const int _nuSamples;
|
||||
const int _muSamples;
|
||||
const int _rSamples;
|
||||
const glm::ivec3 _textureSize;
|
||||
|
||||
glm::dmat4 _modelTransform;
|
||||
double _time = 0.0;
|
||||
|
||||
// Eclipse Shadows
|
||||
std::vector<ShadowConfiguration> _shadowConfArray;
|
||||
std::vector<ShadowRenderingStruct> _shadowDataArrayCache;
|
||||
bool _hardShadowsEnabled = false;
|
||||
|
||||
// Atmosphere Debugging
|
||||
bool _saveCalculationTextures = false;
|
||||
const bool _saveCalculationTextures = false;
|
||||
|
||||
std::vector<ShadowRenderingStruct> _shadowDataArrayCache;
|
||||
// Assuming < 1000 shadow casters, the longest uniform name that we are getting is
|
||||
// shadowDataArray[999].casterPositionVec
|
||||
// which needs to fit into the uniform buffer
|
||||
char _uniformNameBuffer[40];
|
||||
};
|
||||
|
||||
} // openspace
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_ATMOSPHERE___ATMOSPHEREDEFERREDCASTER___H__
|
||||
|
||||
@@ -244,7 +244,7 @@ RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
|
||||
MieScatteringCoeffInfo,
|
||||
glm::vec3(0.004f), glm::vec3(0.00001f), glm::vec3(1.f)
|
||||
)
|
||||
, _mieScatteringExtinctionPropCoefficient(
|
||||
, _mieScatteringExtinctionPropCoeff(
|
||||
MieScatteringExtinctionPropCoeffInfo,
|
||||
0.9f, 0.01f, 1.f
|
||||
)
|
||||
@@ -328,16 +328,15 @@ RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
|
||||
_miePhaseConstant.onChange(updateWithCalculation);
|
||||
addProperty(_miePhaseConstant);
|
||||
|
||||
_mieScatteringExtinctionPropCoefficient =
|
||||
_mieScatteringExtinctionPropCoeff =
|
||||
_mieScattExtPropCoefProp != 1.f ? _mieScattExtPropCoefProp :
|
||||
_mieScatteringCoeff.value().x / _mieExtinctionCoeff.x;
|
||||
|
||||
_mieScatteringExtinctionPropCoefficient.onChange(updateWithCalculation);
|
||||
addProperty(_mieScatteringExtinctionPropCoefficient);
|
||||
_mieScatteringExtinctionPropCoeff.onChange(updateWithCalculation);
|
||||
addProperty(_mieScatteringExtinctionPropCoeff);
|
||||
|
||||
if (p.debug.has_value()) {
|
||||
_preCalculatedTexturesScale =
|
||||
p.debug->preCalculatedTextureScale.value_or(_preCalculatedTexturesScale);
|
||||
_textureScale = p.debug->preCalculatedTextureScale.value_or(_textureScale);
|
||||
|
||||
_saveCalculationsToTexture =
|
||||
p.debug->saveCalculatedTextures.value_or(_saveCalculationsToTexture);
|
||||
@@ -364,15 +363,13 @@ void RenderableAtmosphere::deinitializeGL() {
|
||||
}
|
||||
|
||||
void RenderableAtmosphere::initializeGL() {
|
||||
_deferredcaster = std::make_unique<AtmosphereDeferredcaster>();
|
||||
_deferredcaster = std::make_unique<AtmosphereDeferredcaster>(
|
||||
_textureScale,
|
||||
_shadowEnabled ? std::move(_shadowConfArray) : std::vector<ShadowConfiguration>(),
|
||||
_saveCalculationsToTexture
|
||||
);
|
||||
_shadowConfArray.clear();
|
||||
updateAtmosphereParameters();
|
||||
|
||||
if (_shadowEnabled) {
|
||||
_deferredcaster->setShadowConfigArray(_shadowConfArray);
|
||||
// We no longer need it
|
||||
_shadowConfArray.clear();
|
||||
}
|
||||
|
||||
_deferredcaster->initialize();
|
||||
|
||||
global::deferredcasterManager->attachDeferredcaster(*_deferredcaster);
|
||||
@@ -382,13 +379,11 @@ bool RenderableAtmosphere::isReady() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
glm::dmat4 RenderableAtmosphere::computeModelTransformMatrix(
|
||||
const TransformData& transformData)
|
||||
{
|
||||
glm::dmat4 RenderableAtmosphere::computeModelTransformMatrix(const TransformData& data) {
|
||||
// scale the planet to appropriate size since the planet is a unit sphere
|
||||
return glm::translate(glm::dmat4(1.0), transformData.translation) *
|
||||
glm::dmat4(transformData.rotation) *
|
||||
glm::scale(glm::dmat4(1.0), glm::dvec3(transformData.scale));
|
||||
return glm::translate(glm::dmat4(1.0), data.translation) *
|
||||
glm::dmat4(data.rotation) *
|
||||
glm::scale(glm::dmat4(1.0), glm::dvec3(data.scale));
|
||||
}
|
||||
|
||||
void RenderableAtmosphere::render(const RenderData& data, RendererTasks& renderTask) {
|
||||
@@ -404,11 +399,10 @@ void RenderableAtmosphere::update(const UpdateData& data) {
|
||||
_deferredCasterNeedsUpdate = false;
|
||||
}
|
||||
if (_deferredCasterNeedsCalculation) {
|
||||
_deferredcaster->preCalculateAtmosphereParam();
|
||||
_deferredcaster->calculateAtmosphereParameters();
|
||||
_deferredCasterNeedsCalculation = false;
|
||||
}
|
||||
|
||||
_deferredcaster->setTime(data.time.j2000Seconds());
|
||||
glm::dmat4 modelTransform = computeModelTransformMatrix(data.modelTransform);
|
||||
_deferredcaster->setModelTransform(modelTransform);
|
||||
_deferredcaster->update(data);
|
||||
@@ -416,34 +410,26 @@ void RenderableAtmosphere::update(const UpdateData& data) {
|
||||
|
||||
void RenderableAtmosphere::updateAtmosphereParameters() {
|
||||
_mieExtinctionCoeff =
|
||||
_mieScatteringCoeff.value() / _mieScatteringExtinctionPropCoefficient.value();
|
||||
_mieScatteringCoeff.value() / _mieScatteringExtinctionPropCoeff.value();
|
||||
|
||||
_deferredcaster->setAtmosphereRadius(_planetRadius + _atmosphereHeight);
|
||||
_deferredcaster->setPlanetRadius(_planetRadius);
|
||||
_deferredcaster->setPlanetAverageGroundReflectance(_groundAverageReflectance);
|
||||
_deferredcaster->setPlanetGroundRadianceEmission(_groundRadianceEmission);
|
||||
_deferredcaster->setRayleighHeightScale(_rayleighHeightScale);
|
||||
_deferredcaster->enableOzone(_ozoneEnabled);
|
||||
_deferredcaster->setOzoneHeightScale(_ozoneHeightScale);
|
||||
_deferredcaster->setMieHeightScale(_mieHeightScale);
|
||||
_deferredcaster->setMiePhaseConstant(_miePhaseConstant);
|
||||
_deferredcaster->setSunRadianceIntensity(_sunIntensity);
|
||||
_deferredcaster->setRayleighScatteringCoefficients(_rayleighScatteringCoeff);
|
||||
_deferredcaster->setOzoneExtinctionCoefficients(_ozoneCoeff);
|
||||
_deferredcaster->setMieScatteringCoefficients(_mieScatteringCoeff);
|
||||
_deferredcaster->setMieExtinctionCoefficients(_mieExtinctionCoeff);
|
||||
_deferredcaster->enableSunFollowing(_sunFollowingCameraEnabled);
|
||||
// TODO: Fix the ellipsoid nature of the renderable globe (JCC)
|
||||
//_deferredcaster->setEllipsoidRadii(_ellipsoid.radii());
|
||||
|
||||
_deferredcaster->setPrecalculationTextureScale(_preCalculatedTexturesScale);
|
||||
if (_saveCalculationsToTexture) {
|
||||
_deferredcaster->enablePrecalculationTexturesSaving();
|
||||
}
|
||||
|
||||
if (_shadowEnabled) {
|
||||
_deferredcaster->setHardShadows(_hardShadowsEnabled);
|
||||
}
|
||||
_deferredcaster->setParameters(
|
||||
_planetRadius + _atmosphereHeight,
|
||||
_planetRadius,
|
||||
_groundAverageReflectance,
|
||||
_groundRadianceEmission,
|
||||
_rayleighHeightScale,
|
||||
_ozoneEnabled,
|
||||
_ozoneHeightScale,
|
||||
_mieHeightScale,
|
||||
_miePhaseConstant,
|
||||
_sunIntensity,
|
||||
_rayleighScatteringCoeff,
|
||||
_ozoneCoeff,
|
||||
_mieScatteringCoeff,
|
||||
_mieExtinctionCoeff,
|
||||
_sunFollowingCameraEnabled
|
||||
);
|
||||
_deferredcaster->setHardShadows(_hardShadowsEnabled);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
glm::dmat4 computeModelTransformMatrix(const openspace::TransformData& transformData);
|
||||
glm::dmat4 computeModelTransformMatrix(const openspace::TransformData& data);
|
||||
void updateAtmosphereParameters();
|
||||
|
||||
properties::FloatProperty _atmosphereHeight;
|
||||
@@ -85,7 +85,7 @@ private:
|
||||
properties::Vec3Property _ozoneCoeff;
|
||||
properties::FloatProperty _mieHeightScale;
|
||||
properties::Vec3Property _mieScatteringCoeff;
|
||||
properties::FloatProperty _mieScatteringExtinctionPropCoefficient;
|
||||
properties::FloatProperty _mieScatteringExtinctionPropCoeff;
|
||||
properties::FloatProperty _miePhaseConstant;
|
||||
properties::FloatProperty _sunIntensity;
|
||||
properties::BoolProperty _sunFollowingCameraEnabled;
|
||||
@@ -98,7 +98,7 @@ private:
|
||||
|
||||
// Atmosphere Debug
|
||||
bool _saveCalculationsToTexture = false;
|
||||
float _preCalculatedTexturesScale = 1.f;
|
||||
float _textureScale = 1.f;
|
||||
|
||||
std::unique_ptr<AtmosphereDeferredcaster> _deferredcaster;
|
||||
|
||||
|
||||
@@ -54,85 +54,11 @@
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Atmosphere Rendering Parameters
|
||||
uniform float Rg;
|
||||
uniform float Rt;
|
||||
uniform float AverageGroundReflectance;
|
||||
uniform float groundRadianceEmission;
|
||||
uniform float HR;
|
||||
uniform vec3 betaRayleigh;
|
||||
uniform float HO;
|
||||
uniform vec3 betaOzoneExtinction;
|
||||
uniform float HM;
|
||||
uniform vec3 betaMieScattering;
|
||||
uniform vec3 betaMieExtinction;
|
||||
uniform float mieG;
|
||||
uniform float sunRadiance;
|
||||
|
||||
uniform bool ozoneLayerEnabled;
|
||||
|
||||
uniform ivec2 TRANSMITTANCE;
|
||||
uniform ivec2 SKY;
|
||||
uniform ivec2 OTHER_TEXTURES;
|
||||
uniform int SAMPLES_R;
|
||||
uniform int SAMPLES_MU;
|
||||
uniform int SAMPLES_MU_S;
|
||||
uniform int SAMPLES_NU;
|
||||
|
||||
const int INSCATTER_INTEGRAL_SAMPLES = 50;
|
||||
const float M_PI = 3.141592657;
|
||||
const float ATM_EPSILON = 1.0;
|
||||
|
||||
// Integration steps
|
||||
const int TRANSMITTANCE_STEPS = 500;
|
||||
const int INSCATTER_INTEGRAL_SAMPLES = 50;
|
||||
const int IRRADIANCE_INTEGRAL_SAMPLES = 32;
|
||||
const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 16;
|
||||
|
||||
const float M_PI = 3.141592657;
|
||||
const float M_2PI = 2.0 * M_PI;
|
||||
|
||||
uniform sampler2D transmittanceTexture;
|
||||
|
||||
float Rg2 = Rg * Rg;
|
||||
float Rt2 = Rt * Rt;
|
||||
float H = sqrt(Rt2 - Rg2);
|
||||
float H2 = Rt2 - Rg2;
|
||||
float invSamplesMu = 1.0 / float(SAMPLES_MU);
|
||||
float invSamplesR = 1.0 / float(SAMPLES_R);
|
||||
float invSamplesMuS = 1.0 / float(SAMPLES_MU_S);
|
||||
float invSamplesNu = 1.0 / float(SAMPLES_NU);
|
||||
float RtMinusRg = float(Rt - Rg);
|
||||
float invRtMinusRg = 1.0 / RtMinusRg;
|
||||
|
||||
float opticalDepth(float localH, float r, float mu, float d) {
|
||||
float invH = 1.0 / localH;
|
||||
float a = sqrt(0.5 * invH * r);
|
||||
vec2 a01 = a * vec2(mu, mu + d / r);
|
||||
vec2 a01s = sign(a01);
|
||||
vec2 a01sq = a01 * a01;
|
||||
float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0;
|
||||
vec2 y = a01s / (2.3193 * abs(a01) + sqrt(1.52 * a01sq + 4.0)) * vec2(1.0, exp(-d * invH * (d / (2.0 * r) + mu)));
|
||||
return sqrt(M_2PI * H * r) * exp((Rg-r)*invH) * (x + dot(y, vec2(1.0, -1.0)));
|
||||
}
|
||||
|
||||
vec3 analyticTransmittance(float r, float mu, float d) {
|
||||
vec3 ozone = vec3(0.0);
|
||||
if (ozoneLayerEnabled) {
|
||||
ozone = betaOzoneExtinction * (0.0000006) * opticalDepth(HO, r, mu, d);
|
||||
}
|
||||
return exp(-betaRayleigh * opticalDepth(HR, r, mu, d) - ozone -
|
||||
betaMieExtinction * opticalDepth(HM, r, mu, d));
|
||||
}
|
||||
|
||||
vec3 irradiance(sampler2D sampler, float r, float muSun) {
|
||||
float u_r = (r - Rg) * invRtMinusRg;
|
||||
float u_muSun = (muSun + 0.2) / 1.2;
|
||||
return texture(sampler, vec2(u_muSun, u_r)).rgb;
|
||||
}
|
||||
|
||||
|
||||
//================================================//
|
||||
//=============== General Functions ==============//
|
||||
//================================================//
|
||||
// In the following shaders r (altitude) is the length of vector/position x in the
|
||||
// atmosphere (or on the top of it when considering an observer in space), where the light
|
||||
// is coming from the opposite direction of the view direction, here the vector v or
|
||||
@@ -142,7 +68,7 @@ vec3 irradiance(sampler2D sampler, float r, float muSun) {
|
||||
// or top of atmosphere
|
||||
// r := || vec(x) || e [0, Rt]
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
float rayDistance(float r, float mu) {
|
||||
float rayDistance(float r, float mu, float Rt, float Rg) {
|
||||
// The light ray starting at the observer in/on the atmosphere can have to possible end
|
||||
// points: the top of the atmosphere or the planet ground. So the shortest path is the
|
||||
// one we are looking for, otherwise we may be passing through the ground
|
||||
@@ -151,9 +77,8 @@ float rayDistance(float r, float mu) {
|
||||
float atmRadiusEps2 = (Rt + ATM_EPSILON) * (Rt + ATM_EPSILON);
|
||||
float mu2 = mu * mu;
|
||||
float r2 = r * r;
|
||||
float rg2 = Rg * Rg;
|
||||
float rayDistanceAtmosphere = -r * mu + sqrt(r2 * (mu2 - 1.0) + atmRadiusEps2);
|
||||
float delta = r2 * (mu2 - 1.0) + rg2;
|
||||
float delta = r2 * (mu2 - 1.0) + Rg*Rg;
|
||||
|
||||
// Ray may be hitting ground
|
||||
if (delta >= 0.0) {
|
||||
@@ -173,19 +98,23 @@ float rayDistance(float r, float mu) {
|
||||
// nu := cosone of the angle between vec(s) and vec(v)
|
||||
// dhdH := it is a vec4. dhdH.x stores the dminT := Rt - r, dhdH.y stores the dH value
|
||||
// (see paper), dhdH.z stores dminG := r - Rg and dhdH.w stores dh (see paper)
|
||||
void unmappingMuMuSunNu(float r, vec4 dhdH, out float mu, out float muSun, out float nu) {
|
||||
void unmappingMuMuSunNu(float r, vec4 dhdH, int SAMPLES_MU, float Rg, float Rt,
|
||||
int SAMPLES_MU_S, int SAMPLES_NU,
|
||||
out float mu, out float muSun, out float nu)
|
||||
{
|
||||
// Window coordinates of pixel (uncentering also)
|
||||
vec2 fragment = gl_FragCoord.xy - vec2(0.5);
|
||||
|
||||
// Pre-calculations
|
||||
float r2 = r * r;
|
||||
float Rg2 = Rg * Rg;
|
||||
|
||||
float halfSAMPLE_MU = float(SAMPLES_MU) / 2.0;
|
||||
// If the (vec(x) dot vec(v))/r is negative, i.e., the light ray has great probability
|
||||
// to touch the ground, we obtain mu considering the geometry of the ground
|
||||
if (fragment.y < halfSAMPLE_MU) {
|
||||
float ud = 1.0 - (fragment.y / (halfSAMPLE_MU - 1.0));
|
||||
float d = min(max(dhdH.z, ud * dhdH.w), dhdH.w * 0.999);
|
||||
float d = min(max(dhdH.z, ud * dhdH.w), dhdH.w * 0.999);
|
||||
// cosine law: Rg^2 = r^2 + d^2 - 2rdcos(pi-theta) where cosine(theta) = mu
|
||||
mu = (Rg2 - r2 - d * d) / (2.0 * r * d);
|
||||
// We can't handle a ray inside the planet, i.e., when r ~ Rg, so we check against it.
|
||||
@@ -199,12 +128,12 @@ void unmappingMuMuSunNu(float r, vec4 dhdH, out float mu, out float muSun, out f
|
||||
float d = (fragment.y - halfSAMPLE_MU) / (halfSAMPLE_MU - 1.0);
|
||||
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
|
||||
// cosine law: Rt^2 = r^2 + d^2 - 2rdcos(pi-theta) where cosine(theta) = mu
|
||||
mu = (Rt2 - r2 - d * d) / (2.0 * r * d);
|
||||
mu = (Rt*Rt - r2 - d * d) / (2.0 * r * d);
|
||||
}
|
||||
|
||||
float modValueMuSun = mod(fragment.x, float(SAMPLES_MU_S)) / (float(SAMPLES_MU_S) - 1.0);
|
||||
// The following mapping is different from the paper. See Colliene for an details.
|
||||
muSun = tan((2.0 * modValueMuSun - 1.0 + 0.26) * 1.1f) / tan(1.26 * 1.1);
|
||||
// The following mapping is different from the paper. See Collienne for an details.
|
||||
muSun = tan((2.0 * modValueMuSun - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
|
||||
nu = -1.0 + floor(fragment.x / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0) * 2.0;
|
||||
}
|
||||
|
||||
@@ -213,14 +142,14 @@ void unmappingMuMuSunNu(float r, vec4 dhdH, out float mu, out float muSun, out f
|
||||
// hits the ground or the top of atmosphere.
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
vec3 transmittance(float r, float mu) {
|
||||
vec3 transmittance(sampler2D tex, float r, float mu, float Rg, float Rt) {
|
||||
// Given the position x (here the altitude r) and the view angle v
|
||||
// (here the cosine(v)= mu), we map this
|
||||
float u_r = sqrt((r - Rg) * invRtMinusRg);
|
||||
// See Colliene to understand the mapping
|
||||
float u_r = sqrt((r - Rg) / (Rt - Rg));
|
||||
// See Collienne to understand the mapping
|
||||
float u_mu = atan((mu + 0.15) / 1.15 * tan(1.5)) / 1.5;
|
||||
|
||||
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
|
||||
return texture(tex, vec2(u_mu, u_r)).rgb;
|
||||
}
|
||||
|
||||
// Given a position r and direction mu, calculates de transmittance along the ray with
|
||||
@@ -228,13 +157,13 @@ vec3 transmittance(float r, float mu) {
|
||||
// T(a,b) = TableT(a,v)/TableT(b, v)
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
vec3 transmittance(float r, float mu, float d) {
|
||||
vec3 transmittance(sampler2D tex, float r, float mu, float d, float Rg, float Rt) {
|
||||
// Here we use the transmittance property: T(x,v) = T(x,d)*T(d,v) to, given a distance
|
||||
// d, calculates that transmittance along that distance starting in x (height r):
|
||||
// T(x,d) = T(x,v)/T(d,v).
|
||||
//
|
||||
// From cosine law: c^2 = a^2 + b^2 - 2*a*b*cos(ab)
|
||||
float ri = sqrt(d * d + r * r + 2.0 * r * d * mu);
|
||||
float ri = sqrt(d * d + r * r + 2.0 * r * d * mu);
|
||||
// mu_i = (vec(d) dot vec(v)) / r_i
|
||||
// = ((vec(x) + vec(d-x)) dot vec(v))/ r_i
|
||||
// = (r*mu + d) / r_i
|
||||
@@ -246,19 +175,21 @@ vec3 transmittance(float r, float mu, float d) {
|
||||
// x --> x0, then x0-->x.
|
||||
// Also, let's use the property: T(a,c) = T(a,b)*T(b,c)
|
||||
// Because T(a,c) and T(b,c) are already in the table T, T(a,b) = T(a,c)/T(b,c).
|
||||
vec3 res;
|
||||
if (mu > 0.0) {
|
||||
return min(transmittance(r, mu) / transmittance(ri, mui), 1.0);
|
||||
res = transmittance(tex, r, mu, Rg, Rt) / transmittance(tex, ri, mui, Rg, Rt);
|
||||
}
|
||||
else {
|
||||
return min(transmittance(ri, -mui) / transmittance(r, -mu), 1.0);
|
||||
res = transmittance(tex, ri, -mui, Rg, Rt) / transmittance(tex, r, -mu, Rg, Rt);
|
||||
}
|
||||
return min(res, 1.0);
|
||||
}
|
||||
|
||||
// Calculates Rayleigh phase function given the scattering cosine angle mu
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
float rayleighPhaseFunction(float mu) {
|
||||
//return (3.0f / (16.0f * M_PI)) * (1.0f + mu * mu);
|
||||
return 0.0596831036 * (1.0 + mu * mu);
|
||||
// return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
|
||||
return 0.0596831036 * (1.0 + mu * mu);
|
||||
}
|
||||
|
||||
// Calculates Mie phase function given the scattering cosine angle mu
|
||||
@@ -277,38 +208,30 @@ float miePhaseFunction(float mu, float mieG) {
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
// nu := cosine of the angle between vec(s) and vec(v)
|
||||
vec4 texture4D(sampler3D table, float r, float mu, float muSun, float nu) {
|
||||
vec4 texture4D(sampler3D table, float r, float mu, float muSun, float nu, float Rg,
|
||||
int samplesMu, float Rt, int samplesR, int samplesMuS,
|
||||
int samplesNu)
|
||||
{
|
||||
float r2 = r * r;
|
||||
float Rg2 = Rg * Rg;
|
||||
float Rt2 = Rt * Rt;
|
||||
float rho = sqrt(r2 - Rg2);
|
||||
float rmu = r * mu;
|
||||
float delta = rmu * rmu - r2 + Rg2;
|
||||
|
||||
vec4 cst = rmu < 0.0 && delta > 0.0 ?
|
||||
vec4(1.0, 0.0, 0.0, 0.5 - 0.5 * invSamplesMu) :
|
||||
vec4(-1.0, H2, H, 0.5 + 0.5 * invSamplesMu);
|
||||
vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(samplesMu)) :
|
||||
vec4(-1.0, Rt2 - Rg2, sqrt(Rt2 - Rg2), 0.5 + 0.5 / float(samplesMu));
|
||||
|
||||
float u_r = 0.5 * invSamplesR + rho / H * (1.0 - invSamplesR);
|
||||
float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - invSamplesMu);
|
||||
float u_mu_s = 0.5 * invSamplesMuS +
|
||||
(atan(max(muSun, -0.1975) * tan(1.386)) * 0.9090909090909090 + 0.74) * 0.5 * (1.0 - invSamplesMuS);
|
||||
float lerp = (nu + 1.0) / 2.0 * (float(SAMPLES_NU) - 1.0);
|
||||
float u_nu = floor(lerp);
|
||||
lerp = lerp - u_nu;
|
||||
float u_r = 0.5 / float(samplesR) + rho / sqrt(Rt2 - Rg2) * (1.0 - 1.0 / float(samplesR));
|
||||
float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / samplesMu);
|
||||
float u_mu_s = 0.5 / float(samplesMuS) +
|
||||
(atan(max(muSun, -0.1975) * tan(1.386)) * 0.9090909090909090 + 0.74) * 0.5 * (1.0 - 1.0 / float(samplesMuS));
|
||||
float t = (nu + 1.0) / 2.0 * (float(samplesNu) - 1.0);
|
||||
float u_nu = floor(t);
|
||||
t = t - u_nu;
|
||||
|
||||
return texture(
|
||||
table, vec3((u_nu + u_mu_s) * invSamplesNu, u_mu, u_r)) * (1.0 - lerp) +
|
||||
texture(table, vec3((u_nu + u_mu_s + 1.0) * invSamplesNu, u_mu, u_r)) * lerp;
|
||||
}
|
||||
|
||||
// Given the irradiance texture table, the cosine of zenith sun vector and the height of
|
||||
// the observer (ray's stating point x), calculates the mapping for u_r and u_muSun and
|
||||
// returns the value in the LUT
|
||||
// lut := OpenGL texture2D sampler (the irradiance texture deltaE)
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
// r := height of starting point vect(x)
|
||||
vec3 irradianceLUT(sampler2D lut, float muSun, float r) {
|
||||
// See Bruneton paper and Coliene to understand the mapping
|
||||
float u_muSun = (muSun + 0.2) / 1.2;
|
||||
float u_r = (r - Rg) * invRtMinusRg;
|
||||
return texture(lut, vec2(u_muSun, u_r)).rgb;
|
||||
vec4 v1 = texture(table, vec3((u_nu + u_mu_s) / float(samplesNu), u_mu, u_r));
|
||||
vec4 v2 = texture(table, vec3((u_nu + u_mu_s + 1.0) / float(samplesNu), u_mu, u_r));
|
||||
return mix(v1, v2, t);
|
||||
}
|
||||
|
||||
@@ -64,27 +64,37 @@ out vec4 renderTarget;
|
||||
|
||||
uniform int cullAtmosphere;
|
||||
|
||||
uniform float Rg;
|
||||
uniform float Rt;
|
||||
uniform float groundRadianceEmission;
|
||||
uniform float HR;
|
||||
uniform vec3 betaRayleigh;
|
||||
uniform float HO;
|
||||
uniform vec3 betaOzoneExtinction;
|
||||
uniform float HM;
|
||||
uniform vec3 betaMieExtinction;
|
||||
uniform float mieG;
|
||||
uniform float sunRadiance;
|
||||
uniform bool ozoneLayerEnabled;
|
||||
uniform int SAMPLES_R;
|
||||
uniform int SAMPLES_MU;
|
||||
uniform int SAMPLES_MU_S;
|
||||
uniform int SAMPLES_NU;
|
||||
uniform sampler2D transmittanceTexture;
|
||||
uniform sampler2D irradianceTexture;
|
||||
uniform sampler3D inscatterTexture;
|
||||
uniform sampler2D mainPositionTexture;
|
||||
uniform sampler2D mainNormalTexture;
|
||||
uniform sampler2D mainColorTexture;
|
||||
|
||||
uniform dmat4 inverseModelTransformMatrix;
|
||||
uniform dmat4 modelTransformMatrix;
|
||||
uniform dmat4 viewToWorldMatrix;
|
||||
uniform dmat4 projectionToModelTransformMatrix;
|
||||
|
||||
uniform vec4 viewport;
|
||||
uniform vec2 resolution;
|
||||
|
||||
uniform dvec3 camPosObj;
|
||||
uniform dvec3 sunDirectionObj;
|
||||
|
||||
uniform dvec3 sunWorld;
|
||||
uniform dvec3 viewDirWorld;
|
||||
uniform dvec3 sunModel;
|
||||
|
||||
/*******************************************************************************
|
||||
***** ALL CALCULATIONS FOR ECLIPSE ARE IN METERS AND IN WORLD SPACE SYSTEM ****
|
||||
*******************************************************************************/
|
||||
@@ -92,8 +102,10 @@ uniform dvec3 sunModel;
|
||||
const uint numberOfShadows = 1;
|
||||
|
||||
struct ShadowRenderingStruct {
|
||||
double xu, xp;
|
||||
double rs, rc;
|
||||
double xu;
|
||||
double xp;
|
||||
double rs;
|
||||
double rc;
|
||||
dvec3 sourceCasterVec;
|
||||
dvec3 casterPositionVec;
|
||||
bool isShadowing;
|
||||
@@ -113,15 +125,15 @@ float calcShadow(ShadowRenderingStruct shadowInfoArray[numberOfShadows], dvec3 p
|
||||
}
|
||||
|
||||
dvec3 pc = shadowInfoArray[0].casterPositionVec - position;
|
||||
dvec3 sc_norm = shadowInfoArray[0].sourceCasterVec;
|
||||
dvec3 pc_proj = dot(pc, sc_norm) * sc_norm;
|
||||
dvec3 d = pc - pc_proj;
|
||||
dvec3 scNorm = shadowInfoArray[0].sourceCasterVec;
|
||||
dvec3 pcProj = dot(pc, scNorm) * scNorm;
|
||||
dvec3 d = pc - pcProj;
|
||||
|
||||
float length_d = float(length(d));
|
||||
double length_pc_proj = length(pc_proj);
|
||||
double lengthPcProj = length(pcProj);
|
||||
|
||||
float r_p_pi = float(shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp);
|
||||
float r_u_pi = float(shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu);
|
||||
float r_p_pi = float(shadowInfoArray[0].rc * (lengthPcProj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp);
|
||||
float r_u_pi = float(shadowInfoArray[0].rc * (shadowInfoArray[0].xu - lengthPcProj) / shadowInfoArray[0].xu);
|
||||
|
||||
if (length_d < r_u_pi) {
|
||||
// umbra
|
||||
@@ -142,6 +154,33 @@ float calcShadow(ShadowRenderingStruct shadowInfoArray[numberOfShadows], dvec3 p
|
||||
}
|
||||
}
|
||||
|
||||
float opticalDepth(float localH, float r, float mu, float d, float Rg) {
|
||||
float invH = 1.0 / localH;
|
||||
float a = sqrt(0.5 * invH * r);
|
||||
vec2 a01 = a * vec2(mu, mu + d / r);
|
||||
vec2 a01s = sign(a01);
|
||||
vec2 a01sq = a01 * a01;
|
||||
float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0;
|
||||
vec2 y = a01s / (2.3193 * abs(a01) + sqrt(1.52 * a01sq + 4.0)) *
|
||||
vec2(1.0, exp(-d * invH * (d / (2.0 * r) + mu)));
|
||||
return sqrt(2.0 * M_PI * sqrt(Rt*Rt - Rg*Rg) * r) * exp((Rg-r)*invH) * (x + dot(y, vec2(1.0, -1.0)));
|
||||
}
|
||||
|
||||
vec3 analyticTransmittance(float r, float mu, float d) {
|
||||
vec3 ozone = vec3(0.0);
|
||||
if (ozoneLayerEnabled) {
|
||||
ozone = betaOzoneExtinction * 0.0000006 * opticalDepth(HO, r, mu, d, Rg);
|
||||
}
|
||||
return exp(-betaRayleigh * opticalDepth(HR, r, mu, d, Rg) - ozone -
|
||||
betaMieExtinction * opticalDepth(HM, r, mu, d, Rg));
|
||||
}
|
||||
|
||||
vec3 irradiance(sampler2D s, float r, float muSun) {
|
||||
float u_r = (r - Rg) / (Rt - Rg);
|
||||
float u_muSun = (muSun + 0.2) / 1.2;
|
||||
return texture(s, vec2(u_muSun, u_r)).rgb;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN WORLD SPACE SYSTEM //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -173,10 +212,11 @@ bool atmosphereIntersection(Ray ray, double atmRadius, out double offset,
|
||||
double l2 = dot(l, l);
|
||||
double r2 = atmRadius * atmRadius; // avoiding surface acne
|
||||
|
||||
offset = 0.0;
|
||||
maxLength = 0.0;
|
||||
|
||||
// Ray origin (eye position) is behind sphere
|
||||
if ((s < 0.0) && (l2 > r2)) {
|
||||
offset = 0.0;
|
||||
maxLength = 0.0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -184,13 +224,9 @@ bool atmosphereIntersection(Ray ray, double atmRadius, out double offset,
|
||||
|
||||
// Ray misses atmosphere
|
||||
if (m2 > r2) {
|
||||
offset = 0.0;
|
||||
maxLength = 0.0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We already now the ray hits the atmosphere
|
||||
|
||||
// If q = 0.0, there is only one intersection
|
||||
double q = sqrt(r2 - m2);
|
||||
|
||||
@@ -248,9 +284,9 @@ Ray calculateRayRenderableGlobe(vec2 st) {
|
||||
* the reflectance R[L]
|
||||
*/
|
||||
vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3 v, vec3 s,
|
||||
float r, out float mu, out vec3 attenuation, vec3 fragPosObj,
|
||||
out bool groundHit, double maxLength, double pixelDepth,
|
||||
vec3 spaceColor, float sunIntensity)
|
||||
float r, vec3 fragPosObj, double maxLength, double pixelDepth,
|
||||
vec3 spaceColor, float sunIntensity,
|
||||
out float mu, out vec3 attenuation, out bool groundHit)
|
||||
{
|
||||
const float INTERPOLATION_EPS = 0.004; // precision const from Brunetton
|
||||
|
||||
@@ -268,7 +304,11 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
// I.e. the next line has the scattering light for the "infinite" ray passing through
|
||||
// the atmosphere. If this ray hits something inside the atmosphere, we will subtract
|
||||
// the attenuated scattering light from that path in the current path
|
||||
vec4 inscatterRadiance = max(texture4D(inscatterTexture, r, mu, muSun, nu), 0.0);
|
||||
vec4 inscatterRadiance = max(
|
||||
texture4D(inscatterTexture, r, mu, muSun, nu, Rg, SAMPLES_MU, Rt, SAMPLES_R,
|
||||
SAMPLES_MU_S, SAMPLES_NU),
|
||||
0.0
|
||||
);
|
||||
|
||||
// After removing the initial path from camera pos to top of atmosphere (for an
|
||||
// observer in the space) we test if the light ray is hitting the atmosphere
|
||||
@@ -286,13 +326,14 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
// attenuation = analyticTransmittance(r, mu, t);
|
||||
// JCC: change from analytical to LUT transmittance to avoid
|
||||
// acme on planet surface when looking from far away. (11/02/2017)
|
||||
attenuation = transmittance(r, mu, t);
|
||||
attenuation = transmittance(transmittanceTexture, r, mu, t, Rg, Rt);
|
||||
|
||||
// Here we use the idea of S[L](a->b) = S[L](b->a), and get the S[L](x0, v, s)
|
||||
// Then we calculate S[L] = S[L]|x - T(x, x0)*S[L]|x0
|
||||
// The "infinite" ray hist something inside the atmosphere, so we need to remove
|
||||
// the unsused contribution to the final radiance.
|
||||
vec4 inscatterFromSurface = texture4D(inscatterTexture, r0, mu0, muSun0, nu);
|
||||
vec4 inscatterFromSurface = texture4D(inscatterTexture, r0, mu0, muSun0, nu, Rg,
|
||||
SAMPLES_MU, Rt, SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU);
|
||||
inscatterRadiance = max(inscatterRadiance - attenuation.rgbr * inscatterFromSurface, 0.0);
|
||||
|
||||
// We set the irradianceFactor to 1.0 so the reflected irradiance will be considered
|
||||
@@ -307,7 +348,7 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
// cos(PI-thetaH) = dist/r
|
||||
// cos(thetaH) = -dist/r
|
||||
// muHorizon = -sqrt(r^2-Rg^2)/r = -sqrt(1-(Rg/r)^2)
|
||||
float muHorizon = -sqrt(1.0 - Rg2 / r2);
|
||||
float muHorizon = -sqrt(1.0 - Rg*Rg / r2);
|
||||
|
||||
// In order to avoid precision problems near horizon, we interpolate between two
|
||||
// points: above and below horizon
|
||||
@@ -318,10 +359,10 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
|
||||
// Above Horizon
|
||||
mu = muHorizon - INTERPOLATION_EPS;
|
||||
// r0 = sqrt(r * r + t * t + 2.0f * r * t * mu);
|
||||
// r0 = sqrt(r * r + t * t + 2.0 * r * t * mu);
|
||||
// From cosine law where t = distance between x and x0
|
||||
// r0^2 = r^2 + t^2 - 2 * r * t * cos(PI-theta)
|
||||
// r0 = sqrt(r2 + t2 + 2.0f * r * t * mu);
|
||||
// r0 = sqrt(r2 + t2 + 2.0 * r * t * mu);
|
||||
float halfCosineLaw1 = r2 + (t * t);
|
||||
float halfCosineLaw2 = 2.0 * r * t;
|
||||
r0 = sqrt(halfCosineLaw1 + halfCosineLaw2 * mu);
|
||||
@@ -332,20 +373,24 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
// mu0 = (r*mu + t) / r0
|
||||
mu0 = (r * mu + t) * (1.0 / r0);
|
||||
|
||||
vec4 inScatterAboveX = texture4D(inscatterTexture, r, mu, muSun, nu);
|
||||
vec4 inScatterAboveXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu);
|
||||
vec4 inScatterAboveX = texture4D(inscatterTexture, r, mu, muSun, nu, Rg,
|
||||
SAMPLES_MU, Rt, SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU);
|
||||
vec4 inScatterAboveXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu, Rg,
|
||||
SAMPLES_MU, Rt, SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU);
|
||||
// Attention for the attenuation.r value applied to the S_Mie
|
||||
vec4 inScatterAbove = max(inScatterAboveX - attenuation.rgbr * inScatterAboveXs, 0.0);
|
||||
|
||||
// Below Horizon
|
||||
mu = muHorizon + INTERPOLATION_EPS;
|
||||
//r0 = sqrt(r2 + t2 + 2.0f * r * t * mu);
|
||||
//r0 = sqrt(r2 + t2 + 2.0 * r * t * mu);
|
||||
r0 = sqrt(halfCosineLaw1 + halfCosineLaw2 * mu);
|
||||
|
||||
mu0 = (r * mu + t) * (1.0 / r0);
|
||||
|
||||
vec4 inScatterBelowX = texture4D(inscatterTexture, r, mu, muSun, nu);
|
||||
vec4 inScatterBelowXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu);
|
||||
vec4 inScatterBelowX = texture4D(inscatterTexture, r, mu, muSun, nu, Rg,
|
||||
SAMPLES_MU, Rt, SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU);
|
||||
vec4 inScatterBelowXs = texture4D(inscatterTexture, r0, mu0, muSun0, nu, Rg,
|
||||
SAMPLES_MU, Rt, SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU);
|
||||
// Attention for the attenuation.r value applied to the S_Mie
|
||||
vec4 inScatterBelow = max(inScatterBelowX - attenuation.rgbr * inScatterBelowXs, 0.0);
|
||||
|
||||
@@ -370,13 +415,7 @@ vec3 inscatterRadiance(vec3 x, inout float t, inout float irradianceFactor, vec3
|
||||
// Finally we add the Lsun (all calculations are done with no Lsun so we can change it
|
||||
// on the fly with no precomputations)
|
||||
vec3 finalScatteringRadiance = radiance * sunIntensity;
|
||||
|
||||
if (groundHit) {
|
||||
return finalScatteringRadiance;
|
||||
}
|
||||
else {
|
||||
return spaceColor + finalScatteringRadiance;
|
||||
}
|
||||
return groundHit ? finalScatteringRadiance : spaceColor + finalScatteringRadiance;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -401,8 +440,6 @@ vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, vec3 attenuationXtoX0, vec3 gr
|
||||
vec3 normal, float irradianceFactor, float waterReflectance,
|
||||
float sunIntensity)
|
||||
{
|
||||
vec3 reflectedRadiance = vec3(0.0);
|
||||
|
||||
// First we obtain the ray's end point on the surface
|
||||
float r0 = length(x + t * v);
|
||||
|
||||
@@ -415,7 +452,7 @@ vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, vec3 attenuationXtoX0, vec3 gr
|
||||
|
||||
// Is direct Sun light arriving at x0? If not, there is no direct light from Sun (shadowed)
|
||||
vec3 transmittanceL0 =
|
||||
muSun < -sqrt(1.0 - (Rg2 / (r0 * r0))) ? vec3(0.0) : transmittance(r0, muSun);
|
||||
muSun < -sqrt(1.0 - (Rg*Rg / (r0 * r0))) ? vec3(0.0) : transmittance(transmittanceTexture, r0, muSun, Rg, Rt);
|
||||
|
||||
// E[L*] at x0
|
||||
vec3 irradianceReflected = irradiance(irradianceTexture, r0, muSun) * irradianceFactor;
|
||||
@@ -433,16 +470,14 @@ vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, vec3 attenuationXtoX0, vec3 gr
|
||||
// Fresnell Schlick's approximation
|
||||
float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0);
|
||||
// Walter BRDF approximation
|
||||
float waterBrdf = fresnel * pow(max(dot(h, normal), 0.0), 150.0);
|
||||
float waterBrdf = max(fresnel * pow(max(dot(h, normal), 0.0), 150.0), 0.0);
|
||||
// Adding Fresnell and Water BRDFs approximation to the final surface color
|
||||
// after adding the sunRadiance and the attenuation of the Sun through atmosphere
|
||||
groundRadiance += waterReflectance * max(waterBrdf, 0.0) * transmittanceL0 * sunIntensity;
|
||||
groundRadiance += waterReflectance * waterBrdf * transmittanceL0 * sunIntensity;
|
||||
}
|
||||
|
||||
// Finally, we attenuate the surface Radiance from the point x0 to the camera location
|
||||
reflectedRadiance = attenuationXtoX0 * groundRadiance;
|
||||
|
||||
// Returns reflectedRadiance = 0.0 if the ray doesn't hit the ground.
|
||||
vec3 reflectedRadiance = attenuationXtoX0 * groundRadiance;
|
||||
return reflectedRadiance;
|
||||
}
|
||||
|
||||
@@ -464,7 +499,7 @@ vec3 sunColor(vec3 v, vec3 s, float r, float mu, float irradianceFactor) {
|
||||
// JCC: Change this function to a impostor texture with gaussian decay color weighted
|
||||
// by the sunRadiance, transmittance and irradianceColor (11/03/2017)
|
||||
|
||||
// @TODO (abock, 2021-07-01) This value is hard-coded to our sun right now
|
||||
// @TODO (abock, 2021-07-01) This value is hard-coded to our sun+earth right now
|
||||
// Convert 0.3 degrees -> radians
|
||||
const float SunAngularSize = (0.3 * M_PI / 180.0);
|
||||
const float FuzzyFactor = 0.5; // How fuzzy should the edges be
|
||||
@@ -474,7 +509,7 @@ vec3 sunColor(vec3 v, vec3 s, float r, float mu, float irradianceFactor) {
|
||||
|
||||
float t = (angle - p1) / (p2 - p1);
|
||||
float scale = clamp(t, 0.0, 1.0);
|
||||
return scale * transmittance(r, mu) * sunRadiance * (1.0 - irradianceFactor);
|
||||
return scale * transmittance(transmittanceTexture, r, mu, Rg, Rt) * sunRadiance * (1.0 - irradianceFactor);
|
||||
}
|
||||
|
||||
void main() {
|
||||
@@ -588,24 +623,22 @@ void main() {
|
||||
bool groundHit = false;
|
||||
vec3 attenuation;
|
||||
|
||||
vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v, s, r, mu,
|
||||
attenuation, vec3(positionObjectsCoords), groundHit, maxLength, pixelDepth,
|
||||
color, sunIntensityInscatter);
|
||||
vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v, s, r,
|
||||
vec3(positionObjectsCoords), maxLength, pixelDepth, color, sunIntensityInscatter, mu,
|
||||
attenuation, groundHit);
|
||||
vec3 atmColor = vec3(0.0);
|
||||
if (groundHit) {
|
||||
float eclipseShadowPlanet = calcShadow(shadowDataArray, positionWorldCoords.xyz, true);
|
||||
float sunIntensityGround = sunRadiance * eclipseShadowPlanet;
|
||||
atmColor = groundColor(x, tF, v, s, attenuation, color, normal.xyz,
|
||||
irradianceFactor, normal.w, sunIntensityGround);
|
||||
atmColor = groundColor(x, tF, v, s, attenuation, color, normal.xyz, irradianceFactor,
|
||||
normal.w, sunIntensityGround);
|
||||
}
|
||||
else {
|
||||
// In order to get better performance, we are not tracing multiple rays per pixel
|
||||
// when the ray doesn't intersect the ground
|
||||
|
||||
atmColor = sunColor(v, s, r, mu, irradianceFactor);
|
||||
}
|
||||
|
||||
// Final Color of ATM plus terrain:
|
||||
vec4 finalRadiance = vec4(inscatterColor + atmColor, 1.0);
|
||||
renderTarget = finalRadiance;
|
||||
renderTarget = vec4(inscatterColor + atmColor, 1.0);;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
layout(location = 0) in vec2 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
gl_Position = vec4(in_position, 0.0, 1.0);
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -28,19 +28,45 @@
|
||||
|
||||
out vec4 renderTarget;
|
||||
|
||||
uniform float Rg;
|
||||
uniform float Rt;
|
||||
uniform float AverageGroundReflectance;
|
||||
uniform float HR;
|
||||
uniform vec3 betaRayleigh;
|
||||
uniform float HM;
|
||||
uniform vec3 betaMieScattering;
|
||||
uniform float mieG;
|
||||
uniform int SAMPLES_R;
|
||||
uniform int SAMPLES_MU;
|
||||
uniform int SAMPLES_MU_S;
|
||||
uniform int SAMPLES_NU;
|
||||
uniform sampler2D transmittanceTexture;
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
|
||||
uniform sampler2D deltaETexture;
|
||||
uniform sampler3D deltaSRTexture;
|
||||
uniform sampler3D deltaSMTexture;
|
||||
uniform int firstIteration;
|
||||
|
||||
uniform int firstIteraction;
|
||||
const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 16;
|
||||
|
||||
// -- Spherical Coordinates Steps. phi e [0,2PI] and theta e [0, PI]
|
||||
const float stepPhi = (2.0 * M_PI) / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
|
||||
const float stepTheta = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
|
||||
|
||||
// Given the irradiance texture table, the cosine of zenith sun vector and the height of
|
||||
// the observer (ray's stating point x), calculates the mapping for u_r and u_muSun and
|
||||
// returns the value in the LUT
|
||||
// lut := OpenGL texture2D sampler (the irradiance texture deltaE)
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
// r := height of starting point vect(x)
|
||||
vec3 irradianceLUT(sampler2D lut, float muSun, float r) {
|
||||
// See Bruneton paper and Coliene to understand the mapping
|
||||
float u_muSun = (muSun + 0.2) / 1.2;
|
||||
float u_r = (r - Rg) / (Rt - Rg);
|
||||
return texture(lut, vec2(u_muSun, u_r)).rgb;
|
||||
}
|
||||
|
||||
vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
// Be sure to not get a cosine or height out of bounds
|
||||
r = clamp(r, Rg, Rt);
|
||||
@@ -59,7 +85,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
float muSun2 = muSun * muSun;
|
||||
float sinThetaSinSigma = sqrt(1.0 - mu2) * sqrt(1.0 - muSun2);
|
||||
// cos(sigma + theta) = cos(theta)cos(sigma)-sin(theta)sin(sigma)
|
||||
// cos(ni) = nu = mu * muSun - sqrt(1.0f - mu*mu)*sqrt(1.0 - muSun*muSun) // sin(theta) = sqrt(1.0 - mu*mu)
|
||||
// cos(ni) = nu = mu * muSun - sqrt(1.0 - mu*mu)*sqrt(1.0 - muSun*muSun) // sin(theta) = sqrt(1.0 - mu*mu)
|
||||
// Now we make sure the angle between vec(s) and vec(v) is in the right range:
|
||||
nu = clamp(nu, muSun * mu - sinThetaSinSigma, muSun * mu + sinThetaSinSigma);
|
||||
|
||||
@@ -69,7 +95,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
// -cos(theta) = sqrt(r*r-Rg*Rg)/r
|
||||
float Rg2 = Rg * Rg;
|
||||
float r2 = r * r;
|
||||
float cosHorizon = -sqrt(r2 - Rg2)/r;
|
||||
float cosHorizon = -sqrt(r2 - Rg2) / r;
|
||||
|
||||
// Now we get vec(v) and vec(s) from mu, muSun and nu:
|
||||
// Assuming:
|
||||
@@ -97,6 +123,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
|
||||
// In order to integrate over 4PI, we scan the sphere using the spherical coordinates
|
||||
// previously defined
|
||||
vec3 radianceJAcc = vec3(0.0);
|
||||
for (int theta_i = 0; theta_i < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; theta_i++) {
|
||||
float theta = (float(theta_i) + 0.5) * stepTheta;
|
||||
float cosineTheta = cos(theta);
|
||||
@@ -131,7 +158,7 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
// float muGround = (r2 - distanceToGround*distanceToGround - Rg2)/(2*distanceToGround*Rg);
|
||||
// Access the Transmittance LUT in order to calculate the transmittance from the
|
||||
// ground point Rg, thorugh the atmosphere, at a distance: distanceToGround
|
||||
groundTransmittance = transmittance(Rg, muGround, distanceToGround);
|
||||
groundTransmittance = transmittance(transmittanceTexture, Rg, muGround, distanceToGround, Rg, Rt);
|
||||
}
|
||||
|
||||
for (int phi_i = 0; phi_i < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++phi_i) {
|
||||
@@ -161,43 +188,48 @@ vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
// We calculate the Rayleigh and Mie phase function for the new scattering angle:
|
||||
// cos(angle between vec(s) and vec(w)), ||s|| = ||w|| = 1
|
||||
float nuSW = dot(s, w);
|
||||
// The first iteraction is different from the others. In the first iteraction all
|
||||
// The first iteration is different from the others. In the first iteration all
|
||||
// the light InScattered is coming from the initial pre-computed single InScattered
|
||||
// light. We stored these values in the deltaS textures (Ray and Mie), and in order
|
||||
// to avoid problems with the high angle dependency in the phase functions, we don't
|
||||
// include the phase functions on those tables (that's why we calculate them now).
|
||||
if (firstIteraction == 1) {
|
||||
if (firstIteration == 1) {
|
||||
float phaseRaySW = rayleighPhaseFunction(nuSW);
|
||||
float phaseMieSW = miePhaseFunction(nuSW, mieG);
|
||||
// We can now access the values for the single InScattering in the textures deltaS textures.
|
||||
vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nuSW).rgb;
|
||||
vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nuSW).rgb;
|
||||
vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nuSW, Rg, SAMPLES_MU,
|
||||
Rt, SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU).rgb;
|
||||
vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nuSW, Rg, SAMPLES_MU,
|
||||
Rt, SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU).rgb;
|
||||
|
||||
// Initial InScattering including the phase functions
|
||||
radianceJ1 += singleRay * phaseRaySW + singleMie * phaseMieSW;
|
||||
}
|
||||
else {
|
||||
// On line 9 of the algorithm, the texture table deltaSR is updated, so when we
|
||||
// are not in the first iteraction, we are getting the updated result of deltaSR
|
||||
// are not in the first iteration, we are getting the updated result of deltaSR
|
||||
// (not the single inscattered light but the accumulated (higher order)
|
||||
// inscattered light.
|
||||
// w.z is the cosine(theta) = mu for vec(w)
|
||||
radianceJ1 += texture4D(deltaSRTexture, r, w.z, muSun, nuSW).rgb;
|
||||
radianceJ1 += texture4D(deltaSRTexture, r, w.z, muSun, nuSW, Rg, SAMPLES_MU, Rt,
|
||||
SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU).rgb;
|
||||
}
|
||||
|
||||
// Finally, we add the atmospheric scale height (See: Radiation Transfer on the
|
||||
// Atmosphere and Ocean from Thomas and Stamnes, pg 9-10.
|
||||
return radianceJ1 * (betaRayleigh * exp(-(r - Rg) / HR) * phaseRayleighWV +
|
||||
radianceJAcc += radianceJ1 * (betaRayleigh * exp(-(r - Rg) / HR) * phaseRayleighWV +
|
||||
betaMieScattering * exp(-(r - Rg) / HM) * phaseMieWV) * dw;
|
||||
}
|
||||
}
|
||||
|
||||
return radianceJAcc;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// InScattering Radiance to be calculated at different points in the ray path
|
||||
// Unmapping the variables from texture texels coordinates to mapped coordinates
|
||||
float mu, muSun, nu;
|
||||
unmappingMuMuSunNu(r, dhdH, mu, muSun, nu);
|
||||
unmappingMuMuSunNu(r, dhdH, SAMPLES_MU, Rg, Rt, SAMPLES_MU_S, SAMPLES_NU, mu, muSun, nu);
|
||||
|
||||
// Calculate the the light inScattered in direction
|
||||
// -vec(v) for the point at height r (vec(y) following Bruneton and Neyret's paper
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
|
||||
out vec4 renderTarget;
|
||||
|
||||
uniform int SAMPLES_R;
|
||||
uniform int SAMPLES_MU;
|
||||
uniform int SAMPLES_MU_S;
|
||||
uniform int SAMPLES_NU;
|
||||
uniform int layer;
|
||||
uniform sampler3D deltaSRTexture;
|
||||
uniform sampler3D deltaSMTexture;
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
|
||||
out vec4 renderTarget;
|
||||
|
||||
uniform int SAMPLES_R;
|
||||
uniform int SAMPLES_MU;
|
||||
uniform int SAMPLES_MU_S;
|
||||
uniform int SAMPLES_NU;
|
||||
uniform int layer;
|
||||
uniform sampler3D deltaSTexture;
|
||||
|
||||
@@ -35,10 +39,9 @@ void main() {
|
||||
vec2 p = gl_FragCoord.xy - vec2(0.5);
|
||||
|
||||
float nu = -1.0 + floor(p.x / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0) * 2.0;
|
||||
vec3 uvw = vec3(
|
||||
gl_FragCoord.xy,
|
||||
float(layer) + 0.5) / vec3(ivec3(SAMPLES_MU_S * SAMPLES_NU, SAMPLES_MU, SAMPLES_R)
|
||||
);
|
||||
vec3 uvw =
|
||||
vec3(gl_FragCoord.xy, float(layer) + 0.5) /
|
||||
vec3(ivec3(SAMPLES_MU_S * SAMPLES_NU, SAMPLES_MU, SAMPLES_R));
|
||||
|
||||
// See Bruneton and Neyret paper, "Angular Precision" paragraph to understanding why we
|
||||
// are dividing the S[L*] by the Rayleigh phase function.
|
||||
|
||||
@@ -29,6 +29,18 @@
|
||||
layout(location = 0) out vec4 renderTarget1;
|
||||
layout(location = 1) out vec4 renderTarget2;
|
||||
|
||||
uniform float Rg;
|
||||
uniform float Rt;
|
||||
uniform float HR;
|
||||
uniform vec3 betaRayleigh;
|
||||
uniform float HO;
|
||||
uniform float HM;
|
||||
uniform vec3 betaMieScattering;
|
||||
uniform bool ozoneLayerEnabled;
|
||||
uniform int SAMPLES_MU;
|
||||
uniform int SAMPLES_MU_S;
|
||||
uniform int SAMPLES_NU;
|
||||
uniform sampler2D transmittanceTexture;
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
|
||||
@@ -60,7 +72,9 @@ void integrand(float r, float mu, float muSun, float nu, float y, out vec3 S_R,
|
||||
if (muSun_i >= -sqrt(1.0 - Rg * Rg / (ri * ri))) {
|
||||
// It's the transmittance from the point y (ri) to the top of atmosphere in direction
|
||||
// of the sun (muSun_i) and the transmittance from the observer at x (r) to y (ri).
|
||||
vec3 transmittanceY = transmittance(r, mu, y) * transmittance(ri, muSun_i);
|
||||
vec3 transmittanceY =
|
||||
transmittance(transmittanceTexture, r, mu, y, Rg, Rt) *
|
||||
transmittance(transmittanceTexture, ri, muSun_i, Rg, Rt);
|
||||
// exp(-h/H)*T(x,v)
|
||||
if (ozoneLayerEnabled) {
|
||||
S_R = (exp(-(ri - Rg) / HO) + exp(-(ri - Rg) / HR)) * transmittanceY;
|
||||
@@ -83,7 +97,7 @@ void inscatter(float r, float mu, float muSun, float nu, out vec3 S_R, out vec3
|
||||
S_R = vec3(0.0);
|
||||
S_M = vec3(0.0);
|
||||
|
||||
float rayDist = rayDistance(r, mu);
|
||||
float rayDist = rayDistance(r, mu, Rt, Rg);
|
||||
float dy = rayDist / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
vec3 S_Ri;
|
||||
vec3 S_Mi;
|
||||
@@ -103,13 +117,10 @@ void inscatter(float r, float mu, float muSun, float nu, out vec3 S_R, out vec3
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 S_R; // First Order Rayleigh InScattering
|
||||
vec3 S_M; // First Order Mie InScattering
|
||||
|
||||
// From the layer interpolation (see C++ code for layer to r) and the textures
|
||||
// parameters (uv), we unmapping mu, muSun and nu.
|
||||
float mu, muSun, nu;
|
||||
unmappingMuMuSunNu(r, dhdH, mu, muSun, nu);
|
||||
unmappingMuMuSunNu(r, dhdH, SAMPLES_MU, Rg, Rt, SAMPLES_MU_S, SAMPLES_NU, mu, muSun, nu);
|
||||
|
||||
// Here we calculate the single inScattered light. Because this is a single
|
||||
// inscattering, the light that arrives at a point y in the path from the eye to the
|
||||
@@ -122,6 +133,8 @@ void main() {
|
||||
// S[L0] = P_R*S_R[L0] + P_M*S_M[L0]
|
||||
// In order to save memory, we just store the red component of S_M[L0], and later we use
|
||||
// the proportionality rule to calcule the other components.
|
||||
vec3 S_R; // First Order Rayleigh InScattering
|
||||
vec3 S_M; // First Order Mie InScattering
|
||||
inscatter(r, mu, muSun, nu, S_R, S_M);
|
||||
renderTarget1 = vec4(S_R, 1.0);
|
||||
renderTarget2 = vec4(S_M, 1.0);
|
||||
|
||||
@@ -28,6 +28,13 @@
|
||||
|
||||
out vec4 renderTarget;
|
||||
|
||||
uniform float Rg;
|
||||
uniform float Rt;
|
||||
uniform int SAMPLES_R;
|
||||
uniform int SAMPLES_MU;
|
||||
uniform int SAMPLES_MU_S;
|
||||
uniform int SAMPLES_NU;
|
||||
uniform sampler2D transmittanceTexture;
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
uniform sampler3D deltaJTexture;
|
||||
@@ -35,7 +42,7 @@ uniform sampler3D deltaJTexture;
|
||||
// The integrand here is the f(y) of the trapezoidal rule:
|
||||
vec3 integrand(float r, float mu, float muSun, float nu, float dist) {
|
||||
// We can calculate r_i by the cosine law: r_i^2=dist^2 + r^2 - 2*r*dist*cos(PI-theta)
|
||||
float r_i = sqrt(r * r + dist * dist + 2.0f * r * dist * mu);
|
||||
float r_i = sqrt(r * r + dist * dist + 2.0 * r * dist * mu);
|
||||
// r_i can be found using the dot product:
|
||||
// vec(y_i) dot vec(dist) = cos(theta_i) * ||vec(y_i)|| * ||vec(dist)||
|
||||
// But vec(y_i) = vec(x) + vec(dist), also: vec(x) dot vec(dist) = cos(theta) = mu
|
||||
@@ -46,12 +53,15 @@ vec3 integrand(float r, float mu, float muSun, float nu, float dist) {
|
||||
// But vec(y_i) = vec(x) + vec(dist), and vec(x) dot vec(s) = muSun, cos(sigma_i + theta_i) = nu
|
||||
float muSun_i = (r * muSun + dist * nu) / r_i;
|
||||
// The irradiance attenuated from point r until y (y-x = dist)
|
||||
return transmittance(r, mu, dist) * texture4D(deltaJTexture, r_i, mu_i, muSun_i, nu).rgb;
|
||||
return
|
||||
transmittance(transmittanceTexture, r, mu, dist, Rg, Rt) *
|
||||
texture4D(deltaJTexture, r_i, mu_i, muSun_i, nu, Rg, SAMPLES_MU, Rt, SAMPLES_R,
|
||||
SAMPLES_MU_S, SAMPLES_NU).rgb;
|
||||
}
|
||||
|
||||
vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
vec3 inScatteringRadiance = vec3(0.0);
|
||||
float dy = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
float dy = rayDistance(r, mu, Rt, Rg) / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
vec3 inScatteringRadiance_i = integrand(r, mu, muSun, nu, 0.0);
|
||||
|
||||
// In order to solve the integral from equation (11) we use the trapezoidal rule:
|
||||
@@ -71,7 +81,7 @@ void main() {
|
||||
float muSun = 0.0;
|
||||
float nu = 0.0;
|
||||
// Unmapping the variables from texture texels coordinates to mapped coordinates
|
||||
unmappingMuMuSunNu(r, dhdH, mu, muSun, nu);
|
||||
unmappingMuMuSunNu(r, dhdH, SAMPLES_MU, Rg, Rt, SAMPLES_MU_S, SAMPLES_NU, mu, muSun, nu);
|
||||
|
||||
// Write to texture deltaSR
|
||||
renderTarget = vec4(inscatter(r, mu, muSun, nu), 1.0);
|
||||
|
||||
@@ -28,16 +28,24 @@
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
void main() {
|
||||
// See Bruneton and Colliene to understand the mapping
|
||||
float muSun = -0.2 + (gl_FragCoord.x - 0.5) / (float(OTHER_TEXTURES.x) - 1.0) * 1.2;
|
||||
float r = Rg + (gl_FragCoord.y - 0.5) / (float(OTHER_TEXTURES.y) ) * RtMinusRg;
|
||||
uniform float Rg;
|
||||
uniform float Rt;
|
||||
uniform ivec2 OTHER_TEXTURES;
|
||||
uniform sampler2D transmittanceTexture;
|
||||
|
||||
// We are calculating the Irradiance for L0, i.e., only the radiance coming from Sun
|
||||
// direction is accounted:
|
||||
void main() {
|
||||
// See Bruneton and Collienne to understand the mapping
|
||||
float muSun = -0.2 + (gl_FragCoord.x - 0.5) / (float(OTHER_TEXTURES.x) - 1.0) * 1.2;
|
||||
float r = Rg + (gl_FragCoord.y - 0.5) / (float(OTHER_TEXTURES.y)) * (Rt - Rg);
|
||||
|
||||
// We are calculating the Irradiance for L0, i.e., only the radiance coming from the Sun
|
||||
// direction is accounted for:
|
||||
// E[L0](x,s) = L0*dot(w,n) or 0 (if v!=s or the sun is occluded).
|
||||
// Because we consider the Planet as a perfect sphere and we are considering only single
|
||||
// Because we consider the planet as a perfect sphere and we are considering only single
|
||||
// scattering here, the dot product dot(w,n) is equal to dot(s,n) that is equal to
|
||||
// dot(s, r/||r||) = muSun.
|
||||
renderTableColor = vec4(transmittance(r, muSun) * max(muSun, 0.0), 0.0);
|
||||
renderTableColor = vec4(
|
||||
transmittance(transmittanceTexture, r, muSun, Rg, Rt) * max(muSun, 0.0),
|
||||
0.0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -24,10 +24,9 @@
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
uniform ivec2 OTHER_TEXTURES;
|
||||
uniform sampler2D deltaETexture;
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -28,22 +28,32 @@
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
uniform int firstIteraction;
|
||||
uniform float Rg;
|
||||
uniform float Rt;
|
||||
uniform float mieG;
|
||||
uniform ivec2 SKY;
|
||||
uniform int SAMPLES_R;
|
||||
uniform int SAMPLES_MU;
|
||||
uniform int SAMPLES_MU_S;
|
||||
uniform int SAMPLES_NU;
|
||||
uniform int firstIteration;
|
||||
uniform sampler3D deltaSRTexture;
|
||||
uniform sampler3D deltaSMTexture;
|
||||
|
||||
const int IRRADIANCE_INTEGRAL_SAMPLES = 32;
|
||||
|
||||
// Spherical Coordinates Steps. phi e [0,2PI] and theta e [0, PI/2]
|
||||
const float stepPhi = (2.0 * M_PI) / float(IRRADIANCE_INTEGRAL_SAMPLES);
|
||||
const float stepTheta = M_PI / (2.0 * float(IRRADIANCE_INTEGRAL_SAMPLES));
|
||||
|
||||
void main() {
|
||||
// See Bruneton and Colliene to understand the mapping.
|
||||
// See Bruneton and Collienne to understand the mapping.
|
||||
float muSun = -0.2 + (gl_FragCoord.x - 0.5) / (float(SKY.x) - 1.0) * 1.2;
|
||||
float r = Rg + (gl_FragCoord.y - 0.5) / (float(SKY.y) - 1.0) * RtMinusRg;
|
||||
float r = Rg + (gl_FragCoord.y - 0.5) / (float(SKY.y) - 1.0) * (Rt - Rg);
|
||||
|
||||
// We know that muSun = cos(sigma) = s.z/||s||
|
||||
// But, ||s|| = 1, so s.z = muSun. Also,
|
||||
// ||s|| = 1, so s.x = sin(sigma) = sqrt(1-muSun^2) and s.y = 0.0f
|
||||
// ||s|| = 1, so s.x = sin(sigma) = sqrt(1-muSun^2) and s.y = 0.0
|
||||
vec3 s = vec3(max(sqrt(1.0 - muSun * muSun), 0.0), 0.0, muSun);
|
||||
|
||||
// In order to solve the integral from equation (15) we use the trapezoidal rule:
|
||||
@@ -60,30 +70,32 @@ void main() {
|
||||
vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
|
||||
float nu = dot(s, w);
|
||||
|
||||
// The first iteraction is different from the others, that's because in the first
|
||||
// iteraction all the light arriving are coming from the initial pre-computed
|
||||
// single scattered light. We stored these values in the deltaS textures (Ray and
|
||||
// Mie), and in order to avoid problems with the high angle dependency in the phase
|
||||
// functions, we don't include the phase functions on those tables (that's why we
|
||||
// calculate them now)
|
||||
if (firstIteraction == 1) {
|
||||
// The first iteration is different from the others as in the first iteration all
|
||||
// the light arriving is coming from the initial pre-computed single scattered
|
||||
// light. We stored these values in the deltaS textures (Ray and Mie), and in order
|
||||
// to avoid problems with the high angle dependency in the phase functions, we don't
|
||||
// include the phase functions on those tables (that's why we calculate them now)
|
||||
if (firstIteration == 1) {
|
||||
float phaseRay = rayleighPhaseFunction(nu);
|
||||
float phaseMie = miePhaseFunction(nu, mieG);
|
||||
vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nu).rgb;
|
||||
vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nu).rgb;
|
||||
vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nu, Rg, SAMPLES_MU, Rt,
|
||||
SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU).rgb;
|
||||
vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nu, Rg, SAMPLES_MU, Rt,
|
||||
SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU).rgb;
|
||||
// w.z is the cosine(theta) = mu for vec(w) and also vec(w) dot vec(n(xo))
|
||||
irradianceE += (singleRay * phaseRay + singleMie * phaseMie) * w.z * dw;
|
||||
}
|
||||
else {
|
||||
// On line 10 of the algorithm, the texture table deltaE is updated, so when we
|
||||
// are not in the first iteraction, we are getting the updated result of deltaE
|
||||
// are not in the first iteration, we are getting the updated result of deltaE
|
||||
// (not the single irradiance light but the accumulated (higher order) irradiance
|
||||
// light. w.z is the cosine(theta) = mu for vec(w) and also vec(w) dot vec(n(xo))
|
||||
irradianceE += texture4D(deltaSRTexture, r, w.z, muSun, nu).rgb * w.z * dw;
|
||||
irradianceE += texture4D(deltaSRTexture, r, w.z, muSun, nu, Rg, SAMPLES_MU, Rt,
|
||||
SAMPLES_R, SAMPLES_MU_S, SAMPLES_NU).rgb * w.z * dw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write the higher oder irradiance to texture deltaE
|
||||
// Write the higher order irradiance to texture deltaE
|
||||
renderTableColor = vec4(irradianceE, 0.0);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,19 @@
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
uniform float Rg;
|
||||
uniform float Rt;
|
||||
uniform float HR;
|
||||
uniform vec3 betaRayleigh;
|
||||
uniform float HO;
|
||||
uniform vec3 betaOzoneExtinction;
|
||||
uniform float HM;
|
||||
uniform vec3 betaMieExtinction;
|
||||
uniform bool ozoneLayerEnabled;
|
||||
uniform ivec2 TRANSMITTANCE;
|
||||
|
||||
const int TRANSMITTANCE_STEPS = 500;
|
||||
|
||||
// Optical depth by integration, from ray starting at point vec(x), i.e, height r and
|
||||
// angle mu (cosine of vec(v)) until top of atmosphere or planet's ground.
|
||||
// r := height of starting point vect(x)
|
||||
@@ -42,14 +55,14 @@ float opticalDepth(float r, float mu, float H) {
|
||||
// direction and starting and ending points.
|
||||
|
||||
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
|
||||
float cosZenithHorizon = -sqrt(1.0 - (Rg * Rg / r2));
|
||||
float cosZenithHorizon = -sqrt(1.0 - ((Rg * Rg) / r2));
|
||||
if (mu < cosZenithHorizon) {
|
||||
return 1e9;
|
||||
}
|
||||
|
||||
// Integrating using the Trapezoidal rule:
|
||||
// Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i)))
|
||||
float b_a = rayDistance(r, mu);
|
||||
float b_a = rayDistance(r, mu, Rt, Rg);
|
||||
float deltaStep = b_a / float(TRANSMITTANCE_STEPS);
|
||||
// cosine law
|
||||
float y_i = exp(-(r - Rg) / H);
|
||||
@@ -72,11 +85,11 @@ void main() {
|
||||
|
||||
// In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2)
|
||||
// So, extracting r from u_r in the above equation:
|
||||
float r = Rg + (u_r * u_r) * RtMinusRg;
|
||||
float r = Rg + (u_r * u_r) * (Rt - Rg);
|
||||
|
||||
// In the paper the Bruneton suggest mu = dot(v,x)/||x|| with ||v|| = 1.0
|
||||
// Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6))
|
||||
// But the below one is better. See Colliene.
|
||||
// But the below one is better. See Collienne.
|
||||
// One must remember that mu is defined from 0 to PI/2 + epsilon
|
||||
float muSun = -0.15 + tan(1.5 * u_mu) / tan(1.5) * 1.15;
|
||||
|
||||
|
||||
@@ -118,14 +118,7 @@ void RenderableCartesianAxes::initializeGL() {
|
||||
);
|
||||
|
||||
glGenVertexArrays(1, &_vaoId);
|
||||
glGenBuffers(1, &_vBufferId);
|
||||
glGenBuffers(1, &_iBufferId);
|
||||
|
||||
glBindVertexArray(_vaoId);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vBufferId);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferId);
|
||||
glEnableVertexAttribArray(0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
std::vector<Vertex> vertices({
|
||||
Vertex{0.f, 0.f, 0.f},
|
||||
@@ -140,7 +133,7 @@ void RenderableCartesianAxes::initializeGL() {
|
||||
0, 3
|
||||
};
|
||||
|
||||
glBindVertexArray(_vaoId);
|
||||
glGenBuffers(1, &_vBufferId);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vBufferId);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
@@ -149,8 +142,10 @@ void RenderableCartesianAxes::initializeGL() {
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr);
|
||||
|
||||
glGenBuffers(1, &_iBufferId);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferId);
|
||||
glBufferData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
@@ -158,6 +153,7 @@ void RenderableCartesianAxes::initializeGL() {
|
||||
indices.data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void RenderableCartesianAxes::deinitializeGL() {
|
||||
@@ -201,9 +197,9 @@ void RenderableCartesianAxes::render(const RenderData& data, RendererTasks&){
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnablei(GL_BLEND, 0);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glLineWidth(3.0);
|
||||
|
||||
glBindVertexArray(_vaoId);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferId);
|
||||
glDrawElements(GL_LINES, NVertexIndices, GL_UNSIGNED_INT, nullptr);
|
||||
glBindVertexArray(0);
|
||||
|
||||
|
||||
@@ -224,21 +224,21 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _blendMode(BlendModeInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
, _color(ColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, _size(SizeInfo, 8.f, 0.5f, 30.f)
|
||||
, _fontSize(FontSizeInfo, 50.f, 1.f, 100.f)
|
||||
, _size(SizeInfo, 8.f, 0.5f, 30.f)
|
||||
, _minMaxSize(MinMaxSizeInfo, glm::ivec2(8, 20), glm::ivec2(0), glm::ivec2(100))
|
||||
, _enableFadingEffect(EnableFadingEffectInfo, false)
|
||||
, _text(TextInfo, "")
|
||||
, _fadeDistances(FadeDistancesInfo, glm::vec2(1.f), glm::vec2(0.f), glm::vec2(100.f))
|
||||
, _enableFadingEffect(EnableFadingEffectInfo, false)
|
||||
, _fadeWidths(FadeWidthsInfo, glm::vec2(1.f), glm::vec2(0.f), glm::vec2(100.f))
|
||||
, _orientationOption(
|
||||
OrientationOptionInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
)
|
||||
, _fadeDistances(FadeDistancesInfo, glm::vec2(1.f), glm::vec2(0.f), glm::vec2(100.f))
|
||||
, _fadeUnitOption(
|
||||
FadeUnitOptionInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
)
|
||||
, _orientationOption(
|
||||
OrientationOptionInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
|
||||
@@ -255,21 +255,7 @@ void RenderablePlane::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
_shader->setUniform("multiplyColor", _multiplyColor);
|
||||
|
||||
bool usingFramebufferRenderer = global::renderEngine->rendererImplementation() ==
|
||||
RenderEngine::RendererImplementation::Framebuffer;
|
||||
|
||||
bool usingABufferRenderer = global::renderEngine->rendererImplementation() ==
|
||||
RenderEngine::RendererImplementation::ABuffer;
|
||||
|
||||
if (usingABufferRenderer) {
|
||||
_shader->setUniform(
|
||||
"additiveBlending",
|
||||
_blendMode == static_cast<int>(BlendMode::Additive)
|
||||
);
|
||||
}
|
||||
|
||||
bool additiveBlending =
|
||||
(_blendMode == static_cast<int>(BlendMode::Additive)) && usingFramebufferRenderer;
|
||||
bool additiveBlending = (_blendMode == static_cast<int>(BlendMode::Additive));
|
||||
if (additiveBlending) {
|
||||
glDepthMask(false);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
@@ -215,7 +215,10 @@ void RenderablePrism::updateVertexData() {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
float h = i * _length; // z value, 0 to _length
|
||||
|
||||
for (int j = 0, k = 0; j < _nShapeSegments && k < unitVertices.size(); ++j, k += 2) {
|
||||
for (int j = 0, k = 0;
|
||||
j < _nShapeSegments && k < static_cast<int>(unitVertices.size());
|
||||
++j, k += 2)
|
||||
{
|
||||
float ux = unitVertices[k];
|
||||
float uy = unitVertices[k + 1];
|
||||
|
||||
@@ -239,7 +242,10 @@ void RenderablePrism::updateVertexData() {
|
||||
_vertexArray.push_back(_length);
|
||||
}
|
||||
else {
|
||||
for (int j = 0, k = 0; j < _nLines && k < unitVerticesLines.size(); ++j, k += 2) {
|
||||
for (int j = 0, k = 0;
|
||||
j < _nLines && k < static_cast<int>(unitVerticesLines.size());
|
||||
++j, k += 2)
|
||||
{
|
||||
float ux = unitVerticesLines[k];
|
||||
float uy = unitVerticesLines[k + 1];
|
||||
|
||||
|
||||
@@ -398,24 +398,14 @@ void RenderableSphere::render(const RenderData& data, RendererTasks&) {
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
bool usingFramebufferRenderer = global::renderEngine->rendererImplementation() ==
|
||||
RenderEngine::RendererImplementation::Framebuffer;
|
||||
|
||||
bool usingABufferRenderer = global::renderEngine->rendererImplementation() ==
|
||||
RenderEngine::RendererImplementation::ABuffer;
|
||||
|
||||
if (usingABufferRenderer && _useAdditiveBlending) {
|
||||
_shader->setUniform("additiveBlending", true);
|
||||
}
|
||||
|
||||
if (usingFramebufferRenderer && _useAdditiveBlending) {
|
||||
if (_useAdditiveBlending) {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glDepthMask(false);
|
||||
}
|
||||
|
||||
_sphere->render();
|
||||
|
||||
if (usingFramebufferRenderer && _useAdditiveBlending) {
|
||||
if (_useAdditiveBlending) {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask(true);
|
||||
}
|
||||
|
||||
@@ -430,14 +430,8 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) {
|
||||
/*glm::ivec2 resolution = global::renderEngine.renderingResolution();
|
||||
_programObject->setUniform(_uniformCache.resolution, resolution);*/
|
||||
|
||||
const bool usingFramebufferRenderer =
|
||||
global::renderEngine->rendererImplementation() ==
|
||||
RenderEngine::RendererImplementation::Framebuffer;
|
||||
|
||||
if (usingFramebufferRenderer) {
|
||||
glDepthMask(false);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
}
|
||||
glDepthMask(false);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
const bool renderLines = (_appearance.renderingModes == RenderingModeLines) ||
|
||||
(_appearance.renderingModes == RenderingModeLinesPoints);
|
||||
@@ -508,10 +502,8 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
if (usingFramebufferRenderer) {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask(true);
|
||||
}
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask(true);
|
||||
|
||||
_programObject->deactivate();
|
||||
}
|
||||
|
||||
@@ -33,17 +33,20 @@ uniform vec3 yColor;
|
||||
uniform vec3 zColor;
|
||||
|
||||
Fragment getFragment() {
|
||||
Fragment frag;
|
||||
Fragment frag;
|
||||
|
||||
vec3 colorComponents = step(0.01, vs_positionModelSpace);
|
||||
// We compare against a small value as the first vertex doesn't have a positional
|
||||
// information (or rather it is 0) and we don't want to miss out on the color close to
|
||||
// the origin
|
||||
vec3 colorComponents = step(2e-32, vs_positionModelSpace);
|
||||
|
||||
frag.color.rgb = colorComponents.x * xColor +
|
||||
colorComponents.y * yColor +
|
||||
colorComponents.z * zColor;
|
||||
frag.color.a = 1.0;
|
||||
frag.color.rgb = colorComponents.x * xColor +
|
||||
colorComponents.y * yColor +
|
||||
colorComponents.z * zColor;
|
||||
frag.color.a = 1.0;
|
||||
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.gPosition = vs_positionViewSpace;
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
return frag;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.gPosition = vs_positionViewSpace;
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -34,13 +34,13 @@ uniform mat4 modelViewTransform;
|
||||
uniform mat4 projectionTransform;
|
||||
|
||||
void main() {
|
||||
vec4 positionViewSpace = modelViewTransform * vec4(in_position, 1.0);
|
||||
vec4 positionClipSpace = projectionTransform * positionViewSpace;
|
||||
vec4 positionScreenSpace = positionClipSpace;
|
||||
positionScreenSpace.z = 0.0;
|
||||
vs_positionModelSpace = in_position;
|
||||
vs_screenSpaceDepth = positionScreenSpace.w;
|
||||
vs_positionViewSpace = positionViewSpace;
|
||||
vec4 positionViewSpace = modelViewTransform * vec4(in_position, 1.0);
|
||||
vec4 positionClipSpace = projectionTransform * positionViewSpace;
|
||||
vec4 positionScreenSpace = positionClipSpace;
|
||||
positionScreenSpace.z = 0.0;
|
||||
vs_positionModelSpace = in_position;
|
||||
vs_screenSpaceDepth = positionScreenSpace.w;
|
||||
vs_positionViewSpace = positionViewSpace;
|
||||
|
||||
gl_Position = positionScreenSpace;
|
||||
gl_Position = positionScreenSpace;
|
||||
}
|
||||
|
||||
@@ -515,7 +515,6 @@ bool RenderableDUMeshes::readSpeckFile() {
|
||||
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
|
||||
std::string line;
|
||||
while (true) {
|
||||
std::streampos position = file.tellg();
|
||||
std::getline(file, line);
|
||||
|
||||
if (file.eof()) {
|
||||
@@ -534,16 +533,9 @@ bool RenderableDUMeshes::readSpeckFile() {
|
||||
|
||||
std::size_t found = line.find("mesh");
|
||||
if (found == std::string::npos) {
|
||||
//if (line.substr(0, 4) != "mesh") {
|
||||
// we read a line that doesn't belong to the header, so we have to jump back
|
||||
// before the beginning of the current line
|
||||
//file.seekg(position);
|
||||
//break;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
|
||||
//if (line.substr(0, 4) == "mesh") {
|
||||
// mesh lines are structured as follows:
|
||||
// mesh -t texnum -c colorindex -s style {
|
||||
// where textnum is the index of the texture;
|
||||
|
||||
@@ -1112,22 +1112,9 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&
|
||||
|
||||
bool additiveBlending = false;
|
||||
if (_pColorABlendEnabled) {
|
||||
const auto renderer = global::renderEngine->rendererImplementation();
|
||||
const bool usingFBufferRenderer = renderer ==
|
||||
RenderEngine::RendererImplementation::Framebuffer;
|
||||
|
||||
const bool usingABufferRenderer = renderer ==
|
||||
RenderEngine::RendererImplementation::ABuffer;
|
||||
|
||||
if (usingABufferRenderer) {
|
||||
_shaderProgram->setUniform("usingAdditiveBlending", _pColorABlendEnabled);
|
||||
}
|
||||
|
||||
additiveBlending = usingFBufferRenderer;
|
||||
if (additiveBlending) {
|
||||
glDepthMask(false);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
}
|
||||
additiveBlending = true;
|
||||
glDepthMask(false);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
}
|
||||
|
||||
glBindVertexArray(_vertexArrayObject);
|
||||
|
||||
@@ -56,6 +56,12 @@ namespace {
|
||||
"This value determines the size of the font that is used to render the date."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DisplayFormatInfo = {
|
||||
"DisplayFormat",
|
||||
"Display Format",
|
||||
"Choosing the format in which the camera location is displayed"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo SignificantDigitsInfo = {
|
||||
"SignificantDigits",
|
||||
"Significant Digits",
|
||||
@@ -69,6 +75,14 @@ namespace {
|
||||
// [[codegen::verbatim(FontSizeInfo.description)]]
|
||||
std::optional<float> fontSize;
|
||||
|
||||
enum class DisplayFormat {
|
||||
DecimalDegrees,
|
||||
DegreeMinuteSeconds
|
||||
};
|
||||
|
||||
// [[codegen::verbatim(DisplayFormatInfo.description)]]
|
||||
std::optional<DisplayFormat> displayFormat;
|
||||
|
||||
// [[codegen::verbatim(SignificantDigitsInfo.description)]]
|
||||
std::optional<int> significantDigits;
|
||||
};
|
||||
@@ -86,6 +100,7 @@ DashboardItemGlobeLocation::DashboardItemGlobeLocation(
|
||||
: DashboardItem(dictionary)
|
||||
, _fontName(FontNameInfo, KeyFontMono)
|
||||
, _fontSize(FontSizeInfo, DefaultFontSize, 10.f, 144.f, 1.f)
|
||||
, _displayFormat(DisplayFormatInfo)
|
||||
, _significantDigits(SignificantDigitsInfo, 4, 1, 12)
|
||||
, _font(global::fontManager->font(KeyFontMono, 10))
|
||||
{
|
||||
@@ -104,20 +119,54 @@ DashboardItemGlobeLocation::DashboardItemGlobeLocation(
|
||||
addProperty(_fontSize);
|
||||
|
||||
auto updateFormatString = [this]() {
|
||||
using namespace fmt::literals;
|
||||
|
||||
_formatString = fmt::format(
|
||||
"Position: {{:03.{0}f}}{{}}, {{:03.{0}f}}{{}} Altitude: {{:03.{0}f}} {{}}",
|
||||
_significantDigits.value()
|
||||
);
|
||||
switch (_displayFormat.value()) {
|
||||
case static_cast<int>(DisplayFormat::DecimalDegrees):
|
||||
_formatString = fmt::format(
|
||||
"Position: {{:03.{0}f}}, {{:03.{0}f}} "
|
||||
"Altitude: {{:03.{0}f}} {{}}",
|
||||
_significantDigits.value()
|
||||
);
|
||||
break;
|
||||
case static_cast<int>(DisplayFormat::DegreeMinuteSeconds):
|
||||
_formatString = fmt::format(
|
||||
"Position: {{}}d {{}}' {{:03.{0}f}}\" {{}}, "
|
||||
"{{}}d {{}}' {{:03.{0}f}}\" {{}} "
|
||||
"Altitude: {{:03.{0}f}} {{}}",
|
||||
_significantDigits.value()
|
||||
);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
_displayFormat.addOptions({
|
||||
{ static_cast<int>(DisplayFormat::DecimalDegrees), "Decimal Degrees" },
|
||||
{ static_cast<int>(DisplayFormat::DegreeMinuteSeconds), "Degree Minute Seconds" }
|
||||
});
|
||||
_displayFormat.onChange(updateFormatString);
|
||||
addProperty(_displayFormat);
|
||||
|
||||
if (p.displayFormat.has_value()) {
|
||||
switch (*p.displayFormat) {
|
||||
case Parameters::DisplayFormat::DecimalDegrees:
|
||||
_displayFormat = static_cast<int>(DisplayFormat::DecimalDegrees);
|
||||
break;
|
||||
case Parameters::DisplayFormat::DegreeMinuteSeconds:
|
||||
_displayFormat = static_cast<int>(DisplayFormat::DegreeMinuteSeconds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_displayFormat = static_cast<int>(DisplayFormat::DecimalDegrees);
|
||||
}
|
||||
|
||||
|
||||
_significantDigits = p.significantDigits.value_or(_significantDigits);
|
||||
_significantDigits.onChange(updateFormatString);
|
||||
addProperty(_significantDigits);
|
||||
updateFormatString();
|
||||
|
||||
_font = global::fontManager->font(_fontName, _fontSize);
|
||||
_buffer.resize(128);
|
||||
updateFormatString();
|
||||
}
|
||||
|
||||
void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
|
||||
@@ -149,12 +198,6 @@ void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
|
||||
double lat = glm::degrees(geo2.lat);
|
||||
double lon = glm::degrees(geo2.lon);
|
||||
|
||||
bool isNorth = lat > 0.0;
|
||||
lat = std::abs(lat);
|
||||
|
||||
bool isEast = lon > 0.0;
|
||||
lon = std::abs(lon);
|
||||
|
||||
double altitude = glm::length(
|
||||
cameraPositionModelSpace - posHandle.centerToReferenceSurface
|
||||
);
|
||||
@@ -168,13 +211,49 @@ void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
|
||||
std::pair<double, std::string> dist = simplifyDistance(altitude);
|
||||
|
||||
std::fill(_buffer.begin(), _buffer.end(), char(0));
|
||||
char* end = fmt::format_to(
|
||||
_buffer.data(),
|
||||
_formatString.c_str(),
|
||||
lat, isNorth ? "N" : "S",
|
||||
lon, isEast ? "E" : "W",
|
||||
dist.first, dist.second
|
||||
);
|
||||
char* end = nullptr;
|
||||
switch (_displayFormat.value()) {
|
||||
case static_cast<int>(DisplayFormat::DecimalDegrees):
|
||||
{
|
||||
end = fmt::format_to(
|
||||
_buffer.data(),
|
||||
_formatString, lat, lon, dist.first, dist.second
|
||||
);
|
||||
break;
|
||||
}
|
||||
case static_cast<int>(DisplayFormat::DegreeMinuteSeconds):
|
||||
{
|
||||
const bool isNorth = lat > 0.0;
|
||||
lat = std::abs(lat);
|
||||
|
||||
const bool isEast = lon > 0.0;
|
||||
lon = std::abs(lon);
|
||||
|
||||
const double latDeg = std::trunc(lat);
|
||||
const double latDegRemainder = lat - latDeg;
|
||||
const double latMin = std::trunc(latDegRemainder * 60.f);
|
||||
const double latMinRemainder = latDegRemainder * 60.f - latMin;
|
||||
const double latSec = latMinRemainder * 60.f;
|
||||
|
||||
const double lonDeg = std::trunc(lon);
|
||||
const double lonDegRemainder = lon - lonDeg;
|
||||
const double lonMin = std::trunc(lonDegRemainder * 60.f);
|
||||
const double lonMinRemainder = lonDegRemainder * 60.f - lonMin;
|
||||
const double lonSec = lonMinRemainder * 60.f;
|
||||
|
||||
|
||||
end = fmt::format_to(
|
||||
_buffer.data(),
|
||||
_formatString,
|
||||
latDeg, latMin, latSec, isNorth ? "N" : "S",
|
||||
lonDeg, lonMin, lonSec, isEast ? "E" : "W",
|
||||
dist.first, dist.second
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string_view text = std::string_view(_buffer.data(), end - _buffer.data());
|
||||
|
||||
RenderFont(*_font, penPosition, text);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <openspace/rendering/dashboarditem.h>
|
||||
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
@@ -49,9 +50,15 @@ public:
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
enum class DisplayFormat {
|
||||
DecimalDegrees = 0,
|
||||
DegreeMinuteSeconds
|
||||
};
|
||||
|
||||
properties::StringProperty _fontName;
|
||||
properties::FloatProperty _fontSize;
|
||||
|
||||
properties::OptionProperty _displayFormat;
|
||||
properties::IntProperty _significantDigits;
|
||||
|
||||
std::shared_ptr<ghoul::fontrendering::Font> _font;
|
||||
|
||||
@@ -203,8 +203,8 @@ GlobeLabelsComponent::GlobeLabelsComponent()
|
||||
: properties::PropertyOwner({ "Labels" })
|
||||
, _enabled(EnabledInfo, false)
|
||||
, _fontSize(FontSizeInfo, 30.f, 1.f, 300.f)
|
||||
, _minMaxSize(MinMaxSizeInfo, glm::ivec2(1, 1000), glm::ivec2(1), glm::ivec2(1000))
|
||||
, _size(SizeInfo, 2.5, 0, 30)
|
||||
, _minMaxSize(MinMaxSizeInfo, glm::ivec2(1, 1000), glm::ivec2(1), glm::ivec2(1000))
|
||||
, _heightOffset(HeightOffsetInfo, 100.f, 0.f, 10000.f)
|
||||
, _color(ColorInfo, glm::vec3(1.f, 1.f, 0.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, _opacity(OpacityInfo, 1.f, 0.f, 1.f)
|
||||
|
||||
@@ -156,7 +156,7 @@ void LayerManager::reset(bool includeDisabled) {
|
||||
|
||||
for (std::unique_ptr<LayerGroup>& layerGroup : _layerGroups) {
|
||||
for (Layer* layer : layerGroup->layers()) {
|
||||
if (layer->enabled() || includeDisabled) {
|
||||
if ((layer->enabled() || includeDisabled) && layer->tileProvider()) {
|
||||
tileprovider::reset(*layer->tileProvider());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,9 +228,7 @@ 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];
|
||||
defaultFBO = global::renderEngine->openglStateCache().defaultFramebuffer();
|
||||
//glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
|
||||
// Render to texture
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, t.fbo);
|
||||
@@ -252,7 +250,6 @@ Tile tile(TextTileProvider& t, const TileIndex& tileIndex) {
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
|
||||
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);
|
||||
|
||||
@@ -40,7 +40,10 @@ namespace {
|
||||
constexpr const int8_t LabelCacheFileVersion = 10;
|
||||
constexpr const int8_t ColorCacheFileVersion = 10;
|
||||
|
||||
constexpr bool startsWith(std::string_view lhs, std::string_view rhs) noexcept {
|
||||
bool startsWith(std::string lhs, std::string_view rhs) noexcept {
|
||||
for (size_t i = 0; i < lhs.size(); i++) {
|
||||
lhs[i] = static_cast<char>(tolower(lhs[i]));
|
||||
}
|
||||
return (rhs.size() <= lhs.size()) && (lhs.substr(0, rhs.size()) == rhs);
|
||||
}
|
||||
|
||||
@@ -50,7 +53,7 @@ namespace {
|
||||
// 3. Remove all spaces from the new beginning
|
||||
// 4. Remove all spaces from the end
|
||||
|
||||
while (!line.empty() && line[0] == ' ') {
|
||||
while (!line.empty() && (line[0] == ' ' || line[0] == '\t')) {
|
||||
line = line.substr(1);
|
||||
}
|
||||
|
||||
@@ -58,11 +61,11 @@ namespace {
|
||||
line = line.substr(1);
|
||||
}
|
||||
|
||||
while (!line.empty() && line[0] == ' ') {
|
||||
while (!line.empty() && (line[0] == ' ' || line[0] == '\t')) {
|
||||
line = line.substr(1);
|
||||
}
|
||||
|
||||
while (!line.empty() && line.back() == ' ') {
|
||||
while (!line.empty() && (line.back() == ' ' || line.back() == '\t')) {
|
||||
line = line.substr(0, line.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,8 +101,8 @@ SpiceTranslation::SpiceTranslation(const ghoul::Dictionary& dictionary)
|
||||
: _target(TargetInfo)
|
||||
, _observer(ObserverInfo)
|
||||
, _frame(FrameInfo, DefaultReferenceFrame)
|
||||
, _cachedFrame(DefaultReferenceFrame)
|
||||
, _fixedDate(FixedDateInfo)
|
||||
, _cachedFrame(DefaultReferenceFrame)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
|
||||
@@ -74,10 +74,10 @@ namespace {
|
||||
|
||||
struct [[codegen::Dictionary(DashboardItemInstruments)]] Parameters {
|
||||
// [[codegen::verbatim(ActiveColorInfo.description)]]
|
||||
std::optional<glm::dvec3> activeColor [[codegen::color()]];
|
||||
std::optional<glm::vec3> activeColor [[codegen::color()]];
|
||||
|
||||
// [[codegen::verbatim(FlashColorInfo.description)]]
|
||||
std::optional<glm::dvec3> flashColor [[codegen::color()]];
|
||||
std::optional<glm::vec3> flashColor [[codegen::color()]];
|
||||
};
|
||||
#include "dashboarditeminstruments_codegen.cpp"
|
||||
} // namespace
|
||||
@@ -105,8 +105,10 @@ DashboardItemInstruments::DashboardItemInstruments(const ghoul::Dictionary& dict
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_activeColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
_activeColor = p.activeColor.value_or(_activeColor);
|
||||
addProperty(_activeColor);
|
||||
_activeFlash.setViewOption(properties::Property::ViewOptions::Color);
|
||||
_activeFlash = p.flashColor.value_or(_activeFlash);
|
||||
addProperty(_activeFlash);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,8 +42,7 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
LabelParser::LabelParser(std::string name, std::string fileName,
|
||||
const ghoul::Dictionary& dictionary)
|
||||
LabelParser::LabelParser(std::string fileName, const ghoul::Dictionary& dictionary)
|
||||
: _fileName(std::move(fileName))
|
||||
{
|
||||
// get the different instrument types
|
||||
|
||||
@@ -31,8 +31,7 @@ namespace openspace {
|
||||
|
||||
class LabelParser : public SequenceParser {
|
||||
public:
|
||||
LabelParser(std::string name, std::string fileName,
|
||||
const ghoul::Dictionary& translationDictionary);
|
||||
LabelParser(std::string fileName, const ghoul::Dictionary& translationDictionary);
|
||||
|
||||
bool create() override;
|
||||
|
||||
|
||||
@@ -253,21 +253,13 @@ void ProjectionComponent::initialize(const std::string& identifier,
|
||||
break;
|
||||
case Parameters::Type::ImageSequence:
|
||||
parsers.push_back(
|
||||
std::make_unique<LabelParser>(
|
||||
identifier,
|
||||
std::move(source),
|
||||
translations
|
||||
)
|
||||
std::make_unique<LabelParser>(std::move(source), translations)
|
||||
);
|
||||
break;
|
||||
case Parameters::Type::Hybrid:
|
||||
// first read labels
|
||||
parsers.push_back(
|
||||
std::make_unique<LabelParser>(
|
||||
identifier,
|
||||
std::move(source),
|
||||
translations
|
||||
)
|
||||
std::make_unique<LabelParser>(std::move(source), translations)
|
||||
);
|
||||
|
||||
if (p.eventFile.has_value()) {
|
||||
@@ -297,11 +289,7 @@ void ProjectionComponent::initialize(const std::string& identifier,
|
||||
case Parameters::Type::ImageAndInstrumentTimes:
|
||||
{
|
||||
parsers.push_back(
|
||||
std::make_unique<LabelParser>(
|
||||
identifier,
|
||||
std::move(source),
|
||||
translations
|
||||
)
|
||||
std::make_unique<LabelParser>(std::move(source), translations)
|
||||
);
|
||||
|
||||
if (!p.timesSequence.has_value()) {
|
||||
|
||||
@@ -228,7 +228,7 @@ bool HttpSynchronization::trySyncFromUrl(std::string listUrl) {
|
||||
return !_shouldCancel;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(sizeDataMutex);
|
||||
std::lock_guard guard(sizeDataMutex);
|
||||
|
||||
sizeData[line] = { p.totalBytesKnown, p.totalBytes, p.downloadedBytes };
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ void UrlSynchronization::start() {
|
||||
&startedAllDownloads, &nDownloads](HttpRequest::Progress p)
|
||||
{
|
||||
if (p.totalBytesKnown) {
|
||||
std::lock_guard<std::mutex> guard(fileSizeMutex);
|
||||
std::lock_guard guard(fileSizeMutex);
|
||||
fileSizes[url] = p.totalBytes;
|
||||
|
||||
if (!_nTotalBytesKnown && startedAllDownloads &&
|
||||
|
||||
@@ -236,9 +236,9 @@ GlobalRotation = { 0.0, 0.0, 0.0 }
|
||||
MasterRotation = { 0.0, 0.0, 0.0 }
|
||||
ScreenSpaceRotation = { 0.0, 0.0, 0.0 }
|
||||
|
||||
RenderingMethod = "Framebuffer"
|
||||
OpenGLDebugContext = {
|
||||
Activate = true,
|
||||
PrintStacktrace = false,
|
||||
FilterIdentifier = {
|
||||
{ Type = "Other", Source = "API", Identifier = 131185 },
|
||||
-- API_ID_RECOMPILE_FRAGMENT_SHADER performance warning has been generated. Fragment shader recompiled due to state change
|
||||
|
||||
@@ -108,7 +108,6 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/properties/vector/vec3property.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/properties/vector/vec4property.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/query/query.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/rendering/abufferrenderer.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/rendering/dashboard.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/rendering/dashboard_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/rendering/dashboarditem.cpp
|
||||
@@ -284,7 +283,6 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/properties/vector/vec3property.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/properties/vector/vec4property.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/query/query.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/abufferrenderer.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/dashboard.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/dashboarditem.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/dashboardtextitem.h
|
||||
@@ -298,7 +296,6 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/raycasterlistener.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/raycastermanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderable.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderer.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderengine.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/screenspacerenderable.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/texturecomponent.h
|
||||
@@ -464,10 +461,6 @@ endif ()
|
||||
set_openspace_compile_settings(openspace-core)
|
||||
target_link_libraries(openspace-core PUBLIC Ghoul spice external-curl)
|
||||
|
||||
if (OPENSPACE_WITH_ABUFFER_RENDERER)
|
||||
target_compile_definitions(openspace-core PUBLIC "OPENSPACE_WITH_ABUFFER_RENDERER")
|
||||
endif ()
|
||||
|
||||
# Just in case, create the bin directory
|
||||
add_custom_command(
|
||||
TARGET openspace-core
|
||||
|
||||
@@ -161,15 +161,6 @@ namespace {
|
||||
// resolution ('framebuffer'). This value defaults to 'window'
|
||||
std::optional<Scaling> onScreenTextScaling;
|
||||
|
||||
// List from RenderEngine::setRendererFromString
|
||||
enum class RenderingMethod {
|
||||
Framebuffer,
|
||||
ABuffer
|
||||
};
|
||||
// The renderer that is use after startup. The renderer 'ABuffer' requires support
|
||||
// for at least OpenGL 4.3
|
||||
std::optional<RenderingMethod> renderingMethod;
|
||||
|
||||
// Toggles whether the master in a multi-application setup should be rendering or
|
||||
// just managing the state of the network. This is desired in cases where the
|
||||
// master computer does not have the resources to render a scene
|
||||
@@ -178,16 +169,16 @@ namespace {
|
||||
// Applies a global view rotation. Use this to rotate the position of the focus
|
||||
// node away from the default location on the screen. This setting persists even
|
||||
// when a new focus node is selected. Defined using roll, pitch, yaw in radians
|
||||
std::optional<glm::dvec3> globalRotation;
|
||||
std::optional<glm::vec3> globalRotation;
|
||||
|
||||
// Applies a view rotation for only the master node, defined using roll, pitch yaw
|
||||
// in radians. This can be used to compensate the master view direction for tilted
|
||||
// display systems in clustered immersive environments
|
||||
std::optional<glm::dvec3> masterRotation;
|
||||
std::optional<glm::vec3> masterRotation;
|
||||
|
||||
// Applies a global rotation for all screenspace renderables. Defined using roll,
|
||||
// pitch, yaw in radians
|
||||
std::optional<glm::dvec3> screenSpaceRotation;
|
||||
std::optional<glm::vec3> screenSpaceRotation;
|
||||
|
||||
// If this value is set to 'true' the ingame console is disabled, locking the
|
||||
// system down against random access
|
||||
@@ -232,6 +223,11 @@ namespace {
|
||||
// Determines whether the OpenGL context should be a debug context
|
||||
bool activate;
|
||||
|
||||
// If this is set to 'true', everytime an OpenGL error is logged, the full
|
||||
// stacktrace leading to the error is printed as well, making debugging under
|
||||
// production situations much easier
|
||||
std::optional<bool> printStacktrace;
|
||||
|
||||
// Determines whether the OpenGL debug callbacks are performed synchronously.
|
||||
// If set to 'true' the callbacks are in the same thread as the context and in
|
||||
// the scope of the OpenGL function that triggered the message. The default
|
||||
@@ -415,18 +411,6 @@ void parseLuaState(Configuration& configuration) {
|
||||
c.globalRotation = p.globalRotation.value_or(c.globalRotation);
|
||||
c.masterRotation = p.masterRotation.value_or(c.masterRotation);
|
||||
c.screenSpaceRotation = p.screenSpaceRotation.value_or(c.screenSpaceRotation);
|
||||
if (p.renderingMethod.has_value()) {
|
||||
switch (*p.renderingMethod) {
|
||||
case Parameters::RenderingMethod::Framebuffer:
|
||||
c.renderingMethod = "Framebuffer";
|
||||
break;
|
||||
case Parameters::RenderingMethod::ABuffer:
|
||||
c.renderingMethod = "ABuffer";
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
c.isConsoleDisabled = p.disableInGameConsole.value_or(c.isConsoleDisabled);
|
||||
if (p.logging.has_value()) {
|
||||
if (p.logging->logLevel.has_value()) {
|
||||
@@ -499,6 +483,9 @@ void parseLuaState(Configuration& configuration) {
|
||||
if (p.openGLDebugContext.has_value()) {
|
||||
const Parameters::OpenGLDebugContext& l = *p.openGLDebugContext;
|
||||
c.openGLDebugContext.isActive = l.activate;
|
||||
c.openGLDebugContext.printStacktrace = l.printStacktrace.value_or(
|
||||
c.openGLDebugContext.printStacktrace
|
||||
);
|
||||
c.openGLDebugContext.isSynchronous = l.synchronous.value_or(
|
||||
c.openGLDebugContext.isSynchronous
|
||||
);
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/logging/visualstudiooutputlog.h>
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <ghoul/misc/stacktrace.h>
|
||||
#include <ghoul/misc/stringconversion.h>
|
||||
#include <ghoul/opengl/debugcontext.h>
|
||||
#include <ghoul/opengl/shaderpreprocessor.h>
|
||||
@@ -560,6 +561,15 @@ void OpenSpaceEngine::initializeGL() {
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
|
||||
if (global::configuration->openGLDebugContext.printStacktrace) {
|
||||
std::string stackString = "Stacktrace\n";
|
||||
std::vector<std::string> stack = ghoul::stackTrace();
|
||||
for (size_t i = 0; i < stack.size(); i++) {
|
||||
stackString += fmt::format("{}: {}\n", i, stack[i]);
|
||||
}
|
||||
LDEBUGC(category, stackString);
|
||||
}
|
||||
};
|
||||
ghoul::opengl::debug::setDebugCallback(callback);
|
||||
}
|
||||
|
||||
@@ -197,6 +197,7 @@ void NavigationHandler::deinitialize() {
|
||||
}
|
||||
|
||||
void NavigationHandler::setFocusNode(SceneGraphNode* node) {
|
||||
ghoul_assert(node, "Focus node must not be nullptr");
|
||||
_orbitalNavigator.setFocusNode(node);
|
||||
_camera->setPositionVec3(anchorNode()->worldPosition());
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ void ParallelPeer::sendAuthentication() {
|
||||
}
|
||||
|
||||
void ParallelPeer::queueInMessage(const ParallelConnection::Message& message) {
|
||||
std::lock_guard<std::mutex> unqlock(_receiveBufferMutex);
|
||||
std::lock_guard unqlock(_receiveBufferMutex);
|
||||
_receiveBuffer.push_back(message);
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ void ParallelPeer::handleMessage(const ParallelConnection::Message& message) {
|
||||
}
|
||||
|
||||
void ParallelPeer::analyzeTimeDifference(double messageTimestamp) {
|
||||
std::lock_guard<std::mutex> latencyLock(_latencyMutex);
|
||||
std::lock_guard latencyLock(_latencyMutex);
|
||||
|
||||
const double timeDiff = global::windowDelegate->applicationTime() - messageTimestamp;
|
||||
if (_latencyDiffs.empty()) {
|
||||
@@ -235,7 +235,7 @@ void ParallelPeer::analyzeTimeDifference(double messageTimestamp) {
|
||||
}
|
||||
|
||||
double ParallelPeer::convertTimestamp(double messageTimestamp) {
|
||||
std::lock_guard<std::mutex> latencyLock(_latencyMutex);
|
||||
std::lock_guard latencyLock(_latencyMutex);
|
||||
return messageTimestamp + _initialTimeDiff + _bufferTime;
|
||||
}
|
||||
|
||||
@@ -495,7 +495,7 @@ void ParallelPeer::sendScript(std::string script) {
|
||||
void ParallelPeer::resetTimeOffset() {
|
||||
global::navigationHandler->keyframeNavigator().clearKeyframes();
|
||||
global::timeManager->clearKeyframes();
|
||||
std::lock_guard<std::mutex> latencyLock(_latencyMutex);
|
||||
std::lock_guard latencyLock(_latencyMutex);
|
||||
_latencyDiffs.clear();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1067,7 +1067,6 @@ void FramebufferRenderer::updateDeferredcastData() {
|
||||
|
||||
std::filesystem::path vsPath = caster->deferredcastVSPath();
|
||||
std::filesystem::path fsPath = caster->deferredcastFSPath();
|
||||
std::filesystem::path deferredShaderPath = caster->deferredcastPath();
|
||||
|
||||
ghoul::Dictionary dict;
|
||||
dict.setValue("rendererData", _rendererData);
|
||||
@@ -1086,17 +1085,10 @@ void FramebufferRenderer::updateDeferredcastData() {
|
||||
_deferredcastPrograms[caster] = ghoul::opengl::ProgramObject::Build(
|
||||
"Deferred " + std::to_string(data.id) + " raycast",
|
||||
vsPath,
|
||||
deferredShaderPath,
|
||||
fsPath,
|
||||
dict
|
||||
);
|
||||
|
||||
_deferredcastPrograms[caster]->setIgnoreSubroutineUniformLocationError(
|
||||
ghoul::opengl::ProgramObject::IgnoreError::Yes
|
||||
);
|
||||
_deferredcastPrograms[caster]->setIgnoreUniformLocationError(
|
||||
ghoul::opengl::ProgramObject::IgnoreError::Yes
|
||||
);
|
||||
|
||||
caster->initializeCachedVariables(*_deferredcastPrograms[caster]);
|
||||
}
|
||||
catch (ghoul::RuntimeError& e) {
|
||||
@@ -1262,7 +1254,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
TracyGpuZone("Apply TMO")
|
||||
GLDebugGroup group("Apply TMO");
|
||||
|
||||
applyTMO(blackoutFactor, glm::ivec4(viewport[0], viewport[1], viewport[2], viewport[3]));
|
||||
applyTMO(blackoutFactor, viewport);
|
||||
}
|
||||
|
||||
if (_enableFXAA) {
|
||||
|
||||
@@ -283,7 +283,7 @@ void LoadingScreen::render() {
|
||||
glm::vec2 messageLl = glm::vec2(0.f);
|
||||
glm::vec2 messageUr = glm::vec2(0.f);
|
||||
if (_showMessage) {
|
||||
std::lock_guard<std::mutex> guard(_messageMutex);
|
||||
std::lock_guard guard(_messageMutex);
|
||||
|
||||
const glm::vec2 bboxMessage = _messageFont->boundingBox(_message);
|
||||
|
||||
@@ -298,7 +298,7 @@ void LoadingScreen::render() {
|
||||
}
|
||||
|
||||
if (_showNodeNames) {
|
||||
std::lock_guard<std::mutex> guard(_itemsMutex);
|
||||
std::lock_guard guard(_itemsMutex);
|
||||
|
||||
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
|
||||
|
||||
@@ -485,7 +485,7 @@ void LoadingScreen::render() {
|
||||
}
|
||||
|
||||
void LoadingScreen::postMessage(std::string message) {
|
||||
std::lock_guard<std::mutex> guard(_messageMutex);
|
||||
std::lock_guard guard(_messageMutex);
|
||||
_message = std::move(message);
|
||||
}
|
||||
|
||||
@@ -535,7 +535,7 @@ void LoadingScreen::updateItem(const std::string& itemIdentifier,
|
||||
// also would create any of the text information
|
||||
return;
|
||||
}
|
||||
std::lock_guard<std::mutex> guard(_itemsMutex);
|
||||
std::lock_guard guard(_itemsMutex);
|
||||
|
||||
auto it = std::find_if(
|
||||
_items.begin(),
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
#include <openspace/openspace.h>
|
||||
#include <openspace/engine/configuration.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/mission/missionmanager.h>
|
||||
#include <openspace/rendering/abufferrenderer.h>
|
||||
#include <openspace/rendering/dashboard.h>
|
||||
#include <openspace/rendering/deferredcastermanager.h>
|
||||
#include <openspace/rendering/helper.h>
|
||||
@@ -302,57 +302,27 @@ RenderEngine::RenderEngine()
|
||||
addProperty(_showVersionInfo);
|
||||
addProperty(_showCameraInfo);
|
||||
|
||||
_enableFXAA.onChange([this]() {
|
||||
if (_renderer) {
|
||||
_renderer->enableFXAA(_enableFXAA);
|
||||
}
|
||||
});
|
||||
_enableFXAA.onChange([this]() { _renderer.enableFXAA(_enableFXAA); });
|
||||
addProperty(_enableFXAA);
|
||||
|
||||
_disableHDRPipeline.onChange([this]() {
|
||||
if (_renderer) {
|
||||
_renderer->setDisableHDR(_disableHDRPipeline);
|
||||
}
|
||||
_renderer.setDisableHDR(_disableHDRPipeline);
|
||||
});
|
||||
addProperty(_disableHDRPipeline);
|
||||
|
||||
_hdrExposure.onChange([this]() {
|
||||
if (_renderer) {
|
||||
_renderer->setHDRExposure(_hdrExposure);
|
||||
}
|
||||
});
|
||||
_hdrExposure.onChange([this]() { _renderer.setHDRExposure(_hdrExposure); });
|
||||
addProperty(_hdrExposure);
|
||||
|
||||
_gamma.onChange([this]() {
|
||||
if (_renderer) {
|
||||
_renderer->setGamma(_gamma);
|
||||
}
|
||||
});
|
||||
_gamma.onChange([this]() { _renderer.setGamma(_gamma); });
|
||||
addProperty(_gamma);
|
||||
|
||||
_hue.onChange([this]() {
|
||||
if (_renderer) {
|
||||
const float h = _hue / 360.f;
|
||||
_renderer->setHue(h);
|
||||
}
|
||||
});
|
||||
|
||||
_hue.onChange([this]() { _renderer.setHue(_hue / 360.f); });
|
||||
addProperty(_hue);
|
||||
|
||||
_saturation.onChange([this]() {
|
||||
if (_renderer) {
|
||||
_renderer->setSaturation(_saturation);
|
||||
}
|
||||
});
|
||||
|
||||
_saturation.onChange([this]() { _renderer.setSaturation(_saturation); });
|
||||
addProperty(_saturation);
|
||||
|
||||
_value.onChange([this]() {
|
||||
if (_renderer) {
|
||||
_renderer->setValue(_value);
|
||||
}
|
||||
});
|
||||
|
||||
_value.onChange([this]() { _renderer.setValue(_value); });
|
||||
addProperty(_value);
|
||||
|
||||
addProperty(_globalBlackOutFactor);
|
||||
@@ -414,39 +384,16 @@ RenderEngine::RenderEngine()
|
||||
|
||||
RenderEngine::~RenderEngine() {} // NOLINT
|
||||
|
||||
void RenderEngine::setRendererFromString(const std::string& renderingMethod) {
|
||||
ZoneScoped
|
||||
|
||||
_rendererImplementation = rendererFromString(renderingMethod);
|
||||
|
||||
std::unique_ptr<Renderer> newRenderer = nullptr;
|
||||
switch (_rendererImplementation) {
|
||||
case RendererImplementation::Framebuffer:
|
||||
newRenderer = std::make_unique<FramebufferRenderer>();
|
||||
break;
|
||||
case RendererImplementation::ABuffer:
|
||||
#ifdef OPENSPACE_WITH_ABUFFER_RENDERER
|
||||
newRenderer = std::make_unique<ABufferRenderer>();
|
||||
#endif // OPENSPACE_WITH_ABUFFER_RENDERER
|
||||
break;
|
||||
case RendererImplementation::Invalid:
|
||||
LFATAL(fmt::format("Rendering method '{}' not available", renderingMethod));
|
||||
return;
|
||||
}
|
||||
|
||||
setRenderer(std::move(newRenderer));
|
||||
}
|
||||
|
||||
void RenderEngine::initialize() {
|
||||
ZoneScoped
|
||||
|
||||
// We have to perform these initializations here as the OsEng has not been initialized
|
||||
// in our constructor
|
||||
_globalRotation = static_cast<glm::vec3>(global::configuration->globalRotation);
|
||||
_screenSpaceRotation =
|
||||
static_cast<glm::vec3>(global::configuration->screenSpaceRotation);
|
||||
_masterRotation = static_cast<glm::vec3>(global::configuration->masterRotation);
|
||||
_globalRotation = global::configuration->globalRotation;
|
||||
_screenSpaceRotation = global::configuration->screenSpaceRotation;
|
||||
_masterRotation = global::configuration->masterRotation;
|
||||
_disableMasterRendering = global::configuration->isRenderingOnMasterDisabled;
|
||||
_screenshotUseDate = global::configuration->shouldUseScreenshotDate;
|
||||
|
||||
#ifdef GHOUL_USE_DEVIL
|
||||
ghoul::io::TextureReader::ref().addReader(
|
||||
@@ -499,8 +446,6 @@ void RenderEngine::initialize() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_screenshotUseDate = global::configuration->shouldUseScreenshotDate;
|
||||
}
|
||||
|
||||
void RenderEngine::initializeGL() {
|
||||
@@ -508,21 +453,10 @@ void RenderEngine::initializeGL() {
|
||||
|
||||
LTRACE("RenderEngine::initializeGL(begin)");
|
||||
|
||||
std::string renderingMethod = global::configuration->renderingMethod;
|
||||
if (renderingMethod == "ABuffer") {
|
||||
using Version = ghoul::systemcapabilities::Version;
|
||||
|
||||
// The default rendering method has a requirement of OpenGL 4.3, so if we are
|
||||
// below that, we will fall back to frame buffer operation
|
||||
if (OpenGLCap.openGLVersion() < Version{ 4,3,0 }) {
|
||||
LINFO("Falling back to framebuffer implementation due to OpenGL limitations");
|
||||
renderingMethod = "Framebuffer";
|
||||
}
|
||||
}
|
||||
|
||||
LINFO(fmt::format("Setting renderer from string: {}", renderingMethod));
|
||||
setRendererFromString(renderingMethod);
|
||||
|
||||
_renderer.setResolution(renderingResolution());
|
||||
_renderer.enableFXAA(_enableFXAA);
|
||||
_renderer.setHDRExposure(_hdrExposure);
|
||||
_renderer.initialize();
|
||||
|
||||
// set the close clip plane and the far clip plane to extreme values while in
|
||||
// development
|
||||
@@ -532,45 +466,15 @@ void RenderEngine::initializeGL() {
|
||||
// initialized window
|
||||
_horizFieldOfView = static_cast<float>(global::windowDelegate->getHorizFieldOfView());
|
||||
|
||||
configuration::Configuration::FontSizes fontSize = global::configuration->fontSize;
|
||||
{
|
||||
ZoneScopedN("Font: FrameInfo")
|
||||
TracyGpuZone("Font: FrameInfo")
|
||||
_fontFrameInfo = global::fontManager->font(
|
||||
KeyFontMono,
|
||||
global::configuration->fontSize.frameInfo
|
||||
);
|
||||
}
|
||||
{
|
||||
ZoneScopedN("Font: Shutdown")
|
||||
TracyGpuZone("Font: Shutdown")
|
||||
_fontShutdown = global::fontManager->font(
|
||||
KeyFontMono,
|
||||
global::configuration->fontSize.shutdown
|
||||
);
|
||||
}
|
||||
{
|
||||
ZoneScopedN("Font: CameraInfo")
|
||||
TracyGpuZone("Font: CameraInfo")
|
||||
_fontCameraInfo = global::fontManager->font(
|
||||
KeyFontMono,
|
||||
global::configuration->fontSize.cameraInfo
|
||||
);
|
||||
}
|
||||
{
|
||||
ZoneScopedN("Font: VersionInfo")
|
||||
TracyGpuZone("Font: VersionInfo")
|
||||
_fontVersionInfo = global::fontManager->font(
|
||||
KeyFontMono,
|
||||
global::configuration->fontSize.versionInfo
|
||||
);
|
||||
}
|
||||
{
|
||||
ZoneScopedN("Font: Log")
|
||||
TracyGpuZone("Font: Log")
|
||||
_fontLog = global::fontManager->font(
|
||||
KeyFontLight,
|
||||
global::configuration->fontSize.log
|
||||
);
|
||||
ZoneScopedN("Fonts")
|
||||
TracyGpuZone("Fonts")
|
||||
_fontFrameInfo = global::fontManager->font(KeyFontMono, fontSize.frameInfo);
|
||||
_fontShutdown = global::fontManager->font(KeyFontMono, fontSize.shutdown);
|
||||
_fontCameraInfo = global::fontManager->font(KeyFontMono, fontSize.cameraInfo);
|
||||
_fontVersionInfo = global::fontManager->font(KeyFontMono, fontSize.versionInfo);
|
||||
_fontLog = global::fontManager->font(KeyFontLight, fontSize.log);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -588,7 +492,7 @@ void RenderEngine::initializeGL() {
|
||||
void RenderEngine::deinitializeGL() {
|
||||
ZoneScoped
|
||||
|
||||
_renderer = nullptr;
|
||||
_renderer.deinitialize();
|
||||
}
|
||||
|
||||
void RenderEngine::updateScene() {
|
||||
@@ -633,7 +537,7 @@ void RenderEngine::updateRenderer() {
|
||||
const bool windowResized = global::windowDelegate->windowHasResized();
|
||||
|
||||
if (windowResized) {
|
||||
_renderer->setResolution(renderingResolution());
|
||||
_renderer.setResolution(renderingResolution());
|
||||
|
||||
using FR = ghoul::fontrendering::FontRenderer;
|
||||
FR::defaultRenderer().setFramebufferSize(fontResolution());
|
||||
@@ -643,7 +547,7 @@ void RenderEngine::updateRenderer() {
|
||||
static_cast<float>(global::windowDelegate->getHorizFieldOfView());
|
||||
}
|
||||
|
||||
_renderer->update();
|
||||
_renderer.update();
|
||||
}
|
||||
|
||||
void RenderEngine::updateScreenSpaceRenderables() {
|
||||
@@ -737,15 +641,23 @@ void RenderEngine::render(const glm::mat4& sceneMatrix, const glm::mat4& viewMat
|
||||
_lastFrameTime = now + std::chrono::microseconds(static_cast<int>(delta));
|
||||
}
|
||||
|
||||
const bool masterEnabled = delegate.isMaster() ? !_disableMasterRendering : true;
|
||||
if (masterEnabled && !delegate.isGuiWindow() && _globalBlackOutFactor > 0.f) {
|
||||
_renderer->render(
|
||||
const bool renderingEnabled = delegate.isMaster() ? !_disableMasterRendering : true;
|
||||
if (renderingEnabled && !delegate.isGuiWindow() && _globalBlackOutFactor > 0.f) {
|
||||
_renderer.render(
|
||||
_scene,
|
||||
_camera,
|
||||
_globalBlackOutFactor
|
||||
);
|
||||
}
|
||||
|
||||
// The CEF webbrowser fix has to be called at least once per frame and we are doing
|
||||
// that in the renderer::render method. So if we disable the rendering, that fix is
|
||||
// no longer called as we lose access to the Web UI. Since we are calling the fix
|
||||
// many times anyway, we can just add one call to it here and not lose much
|
||||
if (global::callback::webBrowserPerformanceHotfix) {
|
||||
(*global::callback::webBrowserPerformanceHotfix)();
|
||||
}
|
||||
|
||||
if (_showFrameInformation) {
|
||||
ZoneScopedN("Show Frame Information")
|
||||
|
||||
@@ -776,7 +688,7 @@ void RenderEngine::render(const glm::mat4& sceneMatrix, const glm::mat4& viewMat
|
||||
RenderFont(*_fontFrameInfo, penPosition, res);
|
||||
}
|
||||
|
||||
if (masterEnabled && !delegate.isGuiWindow() && _globalBlackOutFactor > 0.f) {
|
||||
if (renderingEnabled && !delegate.isGuiWindow() && _globalBlackOutFactor > 0.f) {
|
||||
ZoneScopedN("Render Screenspace Renderable")
|
||||
|
||||
std::vector<ScreenSpaceRenderable*> ssrs;
|
||||
@@ -968,14 +880,6 @@ void RenderEngine::setCamera(Camera* camera) {
|
||||
_camera = camera;
|
||||
}
|
||||
|
||||
const Renderer& RenderEngine::renderer() const {
|
||||
return *_renderer;
|
||||
}
|
||||
|
||||
RenderEngine::RendererImplementation RenderEngine::rendererImplementation() const {
|
||||
return _rendererImplementation;
|
||||
}
|
||||
|
||||
ghoul::opengl::OpenGLStateCache& RenderEngine::openglStateCache() {
|
||||
if (_openglStateCache == nullptr) {
|
||||
_openglStateCache = ghoul::opengl::OpenGLStateCache::instance();
|
||||
@@ -1127,39 +1031,10 @@ unsigned int RenderEngine::latestScreenshotNumber() const {
|
||||
return _latestScreenshotNumber;
|
||||
}
|
||||
|
||||
void RenderEngine::preRaycast(ghoul::opengl::ProgramObject& programObject) {
|
||||
_renderer->preRaycast(programObject);
|
||||
}
|
||||
|
||||
void RenderEngine::postRaycast(ghoul::opengl::ProgramObject& programObject) {
|
||||
_renderer->postRaycast(programObject);
|
||||
}
|
||||
|
||||
void RenderEngine::setRenderer(std::unique_ptr<Renderer> renderer) {
|
||||
ZoneScoped
|
||||
|
||||
if (_renderer) {
|
||||
_renderer->deinitialize();
|
||||
}
|
||||
|
||||
_renderer = std::move(renderer);
|
||||
_renderer->setResolution(renderingResolution());
|
||||
_renderer->enableFXAA(_enableFXAA);
|
||||
_renderer->setHDRExposure(_hdrExposure);
|
||||
_renderer->initialize();
|
||||
}
|
||||
|
||||
scripting::LuaLibrary RenderEngine::luaLibrary() {
|
||||
return {
|
||||
"",
|
||||
{
|
||||
{
|
||||
"setRenderer",
|
||||
&luascriptfunctions::setRenderer,
|
||||
{},
|
||||
"string",
|
||||
"Sets the renderer (ABuffer or FrameBuffer)"
|
||||
},
|
||||
{
|
||||
"addScreenSpaceRenderable",
|
||||
&luascriptfunctions::addScreenSpaceRenderable,
|
||||
@@ -1266,24 +1141,6 @@ std::vector<ScreenSpaceRenderable*> RenderEngine::screenSpaceRenderables() const
|
||||
return res;
|
||||
}
|
||||
|
||||
RenderEngine::RendererImplementation RenderEngine::rendererFromString(
|
||||
const std::string& renderingMethod) const
|
||||
{
|
||||
const std::map<std::string, RenderEngine::RendererImplementation> RenderingMethods = {
|
||||
#ifdef OPENSPACE_WITH_ABUFFER_RENDERER
|
||||
{ "ABuffer", RendererImplementation::ABuffer },
|
||||
#endif // OPENSPACE_WITH_ABUFFER_RENDERER
|
||||
{ "Framebuffer", RendererImplementation::Framebuffer }
|
||||
};
|
||||
|
||||
if (RenderingMethods.find(renderingMethod) != RenderingMethods.end()) {
|
||||
return RenderingMethods.at(renderingMethod);
|
||||
}
|
||||
else {
|
||||
return RendererImplementation::Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderEngine::renderCameraInformation() {
|
||||
ZoneScoped
|
||||
|
||||
|
||||
@@ -26,30 +26,6 @@
|
||||
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* setRenderer(string):
|
||||
* Set renderer
|
||||
*/
|
||||
int setRenderer(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setRenderer");
|
||||
|
||||
const int type = lua_type(L, -1);
|
||||
if (type != LUA_TSTRING) {
|
||||
return ghoul::lua::luaError(L, "Expected argument of type 'string'");
|
||||
}
|
||||
|
||||
const std::string& renderer = ghoul::lua::value<std::string>(
|
||||
L,
|
||||
1,
|
||||
ghoul::lua::PopValue::Yes
|
||||
);
|
||||
global::renderEngine->setRendererFromString(renderer);
|
||||
|
||||
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int addScreenSpaceRenderable(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::addScreenSpaceRenderable");
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <ghoul/misc/defer.h>
|
||||
#include <ghoul/misc/easing.h>
|
||||
|
||||
@@ -654,7 +655,12 @@ int addSceneGraphNode(lua_State* L) {
|
||||
global::renderEngine->scene()->initializeNode(node);
|
||||
}
|
||||
catch (const documentation::SpecificationError& e) {
|
||||
LERRORC("Scene", ghoul::to_string(e.result));
|
||||
std::string cat =
|
||||
d.hasValue<std::string>("Identifier") ?
|
||||
d.value<std::string>("Identifier") :
|
||||
"Scene";
|
||||
LERRORC(cat, ghoul::to_string(e.result));
|
||||
|
||||
return ghoul::lua::luaError(
|
||||
L,
|
||||
fmt::format("Error loading scene graph node: {}", e.what())
|
||||
@@ -698,6 +704,15 @@ int removeSceneGraphNode(lua_State* L) {
|
||||
// Remove the node and all its children
|
||||
std::function<void(SceneGraphNode*)> removeNode =
|
||||
[&removeNode](SceneGraphNode* localNode) {
|
||||
|
||||
if (localNode == global::navigationHandler->anchorNode()) {
|
||||
global::navigationHandler->setFocusNode(sceneGraph()->root());
|
||||
}
|
||||
|
||||
if (localNode == global::navigationHandler->orbitalNavigator().aimNode()) {
|
||||
global::navigationHandler->orbitalNavigator().setAimNode("");
|
||||
}
|
||||
|
||||
std::vector<SceneGraphNode*> children = localNode->children();
|
||||
|
||||
ghoul::mm_unique_ptr<SceneGraphNode> n = localNode->parent()->detachChild(
|
||||
@@ -847,6 +862,15 @@ int removeSceneGraphNodesFromRegex(lua_State* L) {
|
||||
// Remove all marked nodes
|
||||
std::function<void(SceneGraphNode*)> removeNode =
|
||||
[&removeNode, &markedList](SceneGraphNode* localNode) {
|
||||
|
||||
if (localNode == global::navigationHandler->anchorNode()) {
|
||||
global::navigationHandler->setFocusNode(sceneGraph()->root());
|
||||
}
|
||||
|
||||
if (localNode == global::navigationHandler->orbitalNavigator().aimNode()) {
|
||||
global::navigationHandler->orbitalNavigator().setAimNode("");
|
||||
}
|
||||
|
||||
std::vector<SceneGraphNode*> children = localNode->children();
|
||||
|
||||
ghoul::mm_unique_ptr<SceneGraphNode> n = localNode->parent()->detachChild(
|
||||
|
||||
@@ -66,7 +66,7 @@ void MultiThreadedSceneInitializer::initializeNode(SceneGraphNode* node) {
|
||||
}
|
||||
|
||||
node->initialize();
|
||||
std::lock_guard<std::mutex> g(_mutex);
|
||||
std::lock_guard g(_mutex);
|
||||
_initializedNodes.push_back(node);
|
||||
_initializingNodes.erase(node);
|
||||
|
||||
@@ -94,19 +94,19 @@ void MultiThreadedSceneInitializer::initializeNode(SceneGraphNode* node) {
|
||||
);
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> g(_mutex);
|
||||
std::lock_guard g(_mutex);
|
||||
_initializingNodes.insert(node);
|
||||
_threadPool.enqueue(initFunction);
|
||||
}
|
||||
|
||||
std::vector<SceneGraphNode*> MultiThreadedSceneInitializer::takeInitializedNodes() {
|
||||
std::lock_guard<std::mutex> g(_mutex);
|
||||
std::lock_guard g(_mutex);
|
||||
std::vector<SceneGraphNode*> nodes = std::move(_initializedNodes);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
bool MultiThreadedSceneInitializer::isInitializing() const {
|
||||
std::lock_guard<std::mutex> g(_mutex);
|
||||
std::lock_guard g(_mutex);
|
||||
return !_initializingNodes.empty();
|
||||
}
|
||||
|
||||
|
||||
@@ -423,6 +423,13 @@ void ScriptEngine::addBaseLibrary() {
|
||||
"string",
|
||||
"Checks whether the provided file exists."
|
||||
},
|
||||
{
|
||||
"readFile",
|
||||
&luascriptfunctions::readFile,
|
||||
{},
|
||||
"string",
|
||||
"Reads a file from disk and return its contents"
|
||||
},
|
||||
{
|
||||
"directoryExists",
|
||||
&luascriptfunctions::directoryExists,
|
||||
@@ -687,7 +694,7 @@ void ScriptEngine::preSync(bool isMaster) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(_slaveScriptsMutex);
|
||||
std::lock_guard guard(_slaveScriptsMutex);
|
||||
while (!_incomingScripts.empty()) {
|
||||
QueueItem item = std::move(_incomingScripts.front());
|
||||
_incomingScripts.pop();
|
||||
@@ -721,7 +728,7 @@ void ScriptEngine::encode(SyncBuffer* syncBuffer) {
|
||||
void ScriptEngine::decode(SyncBuffer* syncBuffer) {
|
||||
ZoneScoped
|
||||
|
||||
std::lock_guard<std::mutex> guard(_slaveScriptsMutex);
|
||||
std::lock_guard guard(_slaveScriptsMutex);
|
||||
size_t nScripts;
|
||||
syncBuffer->decode(nScripts);
|
||||
|
||||
@@ -750,7 +757,7 @@ void ScriptEngine::postSync(bool isMaster) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::lock_guard<std::mutex> guard(_slaveScriptsMutex);
|
||||
std::lock_guard guard(_slaveScriptsMutex);
|
||||
while (!_slaveScriptQueue.empty()) {
|
||||
try {
|
||||
runScript(_slaveScriptQueue.front());
|
||||
|
||||
@@ -30,37 +30,11 @@
|
||||
namespace openspace::luascriptfunctions {
|
||||
|
||||
int printInternal(ghoul::logging::LogLevel level, lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::printInternal");
|
||||
|
||||
using ghoul::lua::luaTypeToString;
|
||||
|
||||
const int type = lua_type(L, 1);
|
||||
switch (type) {
|
||||
case LUA_TNONE:
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
case LUA_TTABLE:
|
||||
case LUA_TFUNCTION:
|
||||
case LUA_TUSERDATA:
|
||||
case LUA_TTHREAD:
|
||||
log(
|
||||
level,
|
||||
"print",
|
||||
fmt::format("Function parameter was of type '{}'", luaTypeToString(type))
|
||||
);
|
||||
break;
|
||||
case LUA_TNIL:
|
||||
break;
|
||||
case LUA_TBOOLEAN:
|
||||
log(level, "print", std::to_string(ghoul::lua::value<bool>(L, 1)));
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
log(level, "print", std::to_string(ghoul::lua::value<double>(L, 1)));
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
log(level, "print", ghoul::lua::value<std::string>(L, 1));
|
||||
break;
|
||||
const int nArguments = lua_gettop(L);
|
||||
for (int i = 1; i <= nArguments; i++) {
|
||||
log(level, "print", ghoul::lua::luaValueToString(L, i));
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
lua_pop(L, nArguments);
|
||||
|
||||
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
|
||||
return 0;
|
||||
@@ -197,6 +171,32 @@ int fileExists(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* readFile(string):
|
||||
* Reads a file from disk and return its contents
|
||||
*/
|
||||
int readFile(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::readFile");
|
||||
|
||||
const std::string& file = ghoul::lua::value<std::string>(
|
||||
L,
|
||||
1,
|
||||
ghoul::lua::PopValue::Yes
|
||||
);
|
||||
std::filesystem::path p = absPath(file);
|
||||
if (!std::filesystem::is_regular_file(p)) {
|
||||
return ghoul::lua::luaError(L, fmt::format("Could not open file {}", file));
|
||||
}
|
||||
|
||||
std::ifstream f(p);
|
||||
std::stringstream buffer;
|
||||
buffer << f.rdbuf();
|
||||
|
||||
ghoul::lua::push(L, buffer.str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup LuaScripts
|
||||
* directoryExists(string):
|
||||
|
||||
@@ -42,14 +42,15 @@ Camera::Camera(const Camera& o)
|
||||
{}
|
||||
|
||||
void Camera::setPositionVec3(glm::dvec3 pos) {
|
||||
std::lock_guard<std::mutex> _lock(_mutex);
|
||||
_position = std::move(pos);
|
||||
|
||||
_cachedCombinedViewMatrix.isDirty = true;
|
||||
if (!glm::any(glm::isnan(pos))) {
|
||||
std::lock_guard _lock(_mutex);
|
||||
_position = std::move(pos);
|
||||
_cachedCombinedViewMatrix.isDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::setRotation(glm::dquat rotation) {
|
||||
std::lock_guard<std::mutex> _lock(_mutex);
|
||||
std::lock_guard _lock(_mutex);
|
||||
_rotation = std::move(rotation);
|
||||
_cachedViewDirection.isDirty = true;
|
||||
_cachedLookupVector.isDirty = true;
|
||||
@@ -58,14 +59,14 @@ void Camera::setRotation(glm::dquat rotation) {
|
||||
}
|
||||
|
||||
void Camera::setScaling(float scaling) {
|
||||
std::lock_guard<std::mutex> _lock(_mutex);
|
||||
std::lock_guard _lock(_mutex);
|
||||
_scaling = scaling;
|
||||
_cachedViewScaleMatrix.isDirty = true;
|
||||
_cachedCombinedViewMatrix.isDirty = true;
|
||||
}
|
||||
|
||||
void Camera::setMaxFov(float fov) {
|
||||
std::lock_guard<std::mutex> _lock(_mutex);
|
||||
std::lock_guard _lock(_mutex);
|
||||
_maxFov = fov;
|
||||
_cachedSinMaxFov.isDirty = true;
|
||||
}
|
||||
@@ -75,7 +76,7 @@ void Camera::setParent(SceneGraphNode* parent) {
|
||||
}
|
||||
|
||||
void Camera::rotate(glm::dquat rotation) {
|
||||
std::lock_guard<std::mutex> _lock(_mutex);
|
||||
std::lock_guard _lock(_mutex);
|
||||
_rotation = std::move(rotation) * static_cast<glm::dquat>(_rotation);
|
||||
|
||||
_cachedViewDirection.isDirty = true;
|
||||
@@ -224,20 +225,20 @@ Camera::SgctInternal::SgctInternal(const SgctInternal& o)
|
||||
{}
|
||||
|
||||
void Camera::SgctInternal::setSceneMatrix(glm::mat4 sceneMatrix) {
|
||||
std::lock_guard<std::mutex> _lock(_mutex);
|
||||
std::lock_guard _lock(_mutex);
|
||||
|
||||
_sceneMatrix = std::move(sceneMatrix);
|
||||
}
|
||||
|
||||
void Camera::SgctInternal::setViewMatrix(glm::mat4 viewMatrix) {
|
||||
std::lock_guard<std::mutex> _lock(_mutex);
|
||||
std::lock_guard _lock(_mutex);
|
||||
|
||||
_viewMatrix = std::move(viewMatrix);
|
||||
_cachedViewProjectionMatrix.isDirty = true;
|
||||
}
|
||||
|
||||
void Camera::SgctInternal::setProjectionMatrix(glm::mat4 projectionMatrix) {
|
||||
std::lock_guard<std::mutex> _lock(_mutex);
|
||||
std::lock_guard _lock(_mutex);
|
||||
|
||||
_projectionMatrix = std::move(projectionMatrix);
|
||||
_cachedViewProjectionMatrix.isDirty = true;
|
||||
@@ -257,7 +258,7 @@ const glm::mat4& Camera::SgctInternal::projectionMatrix() const {
|
||||
|
||||
const glm::mat4& Camera::SgctInternal::viewProjectionMatrix() const {
|
||||
//if (_cachedViewProjectionMatrix.isDirty) {
|
||||
std::lock_guard<std::mutex> _lock(_mutex);
|
||||
std::lock_guard _lock(_mutex);
|
||||
_cachedViewProjectionMatrix.datum = _projectionMatrix * _viewMatrix;
|
||||
_cachedViewProjectionMatrix.isDirty = false;
|
||||
//}
|
||||
|
||||
@@ -32,9 +32,11 @@ namespace {
|
||||
constexpr const char* _loggerCat = "Coordinateconversion";
|
||||
|
||||
// J2000 Galactic reference frame
|
||||
constexpr double A0 = glm::radians(192.8595); // Equatorial coordinates of the Galactic north pole
|
||||
// Equatorial coordinates of the Galactic north pole
|
||||
constexpr double A0 = glm::radians(192.8595);
|
||||
constexpr double D0 = glm::radians(27.1284);
|
||||
constexpr double L0 = glm::radians(122.9320); // Galactic longitude of the equatorial north pole
|
||||
// Galactic longitude of the equatorial north pole
|
||||
constexpr double L0 = glm::radians(122.9320);
|
||||
|
||||
void parseString(const std::string& str, int& hoursOrDegrees, int& minutes,
|
||||
double& seconds)
|
||||
|
||||
@@ -245,7 +245,7 @@ AsyncHttpDownload::AsyncHttpDownload(AsyncHttpDownload&& d)
|
||||
{}
|
||||
|
||||
void AsyncHttpDownload::start(HttpRequest::RequestOptions opt) {
|
||||
std::lock_guard<std::mutex> guard(_stateChangeMutex);
|
||||
std::lock_guard guard(_stateChangeMutex);
|
||||
if (hasStarted()) {
|
||||
return;
|
||||
}
|
||||
@@ -286,7 +286,7 @@ void AsyncHttpDownload::download(HttpRequest::RequestOptions opt) {
|
||||
_httpRequest.onProgress([this](HttpRequest::Progress p) {
|
||||
// Return a non-zero value to cancel download
|
||||
// if onProgress returns false.
|
||||
//std::lock_guard<std::mutex> guard(_mutex);
|
||||
//std::lock_guard guard(_mutex);
|
||||
const bool shouldContinue = callOnProgress(p);
|
||||
if (!shouldContinue) {
|
||||
return 1;
|
||||
|
||||
@@ -41,7 +41,7 @@ SynchronizationWatcher::WatchHandle SynchronizationWatcher::watchSynchronization
|
||||
[this, synchronization, watchHandle, cb = std::move(callback)]
|
||||
(ResourceSynchronization::State state)
|
||||
{
|
||||
std::lock_guard<std::mutex> g(_mutex);
|
||||
std::lock_guard g(_mutex);
|
||||
_pendingNotifications.push_back({ synchronization, state, watchHandle, cb });
|
||||
}
|
||||
);
|
||||
|
||||
@@ -315,19 +315,19 @@ TEST_CASE("Configuration: isRenderingOnMasterDisabled", "[configuration]") {
|
||||
TEST_CASE("Configuration: globalRotation", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(GlobalRotation = { 1.0, 2.0, 3.0 })";
|
||||
const Configuration c = loadConfiguration("globalRotation", Extra);
|
||||
CHECK(c.globalRotation == glm::dvec3(1.0, 2.0, 3.0));
|
||||
CHECK(c.globalRotation == glm::vec3(1.0, 2.0, 3.0));
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: screenSpaceRotation", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(ScreenSpaceRotation = { 1.0, 2.0, 3.0 })";
|
||||
const Configuration c = loadConfiguration("screenSpaceRotation", Extra);
|
||||
CHECK(c.screenSpaceRotation == glm::dvec3(1.0, 2.0, 3.0));
|
||||
CHECK(c.screenSpaceRotation == glm::vec3(1.0, 2.0, 3.0));
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: masterRotation", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(MasterRotation = { 1.0, 2.0, 3.0 })";
|
||||
const Configuration c = loadConfiguration("masterRotation", Extra);
|
||||
CHECK(c.masterRotation == glm::dvec3(1.0, 2.0, 3.0));
|
||||
CHECK(c.masterRotation == glm::vec3(1.0, 2.0, 3.0));
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: isConsoleDisabled", "[configuration]") {
|
||||
@@ -381,12 +381,6 @@ ModuleConfigurations = {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: renderingMethod", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(RenderingMethod = "ABuffer")";
|
||||
const Configuration c = loadConfiguration("renderingMethod", Extra);
|
||||
CHECK(c.renderingMethod == "ABuffer");
|
||||
}
|
||||
|
||||
TEST_CASE("Configuration: openGLDebugContext", "[configuration]") {
|
||||
Configuration defaultConf;
|
||||
{
|
||||
@@ -394,6 +388,7 @@ TEST_CASE("Configuration: openGLDebugContext", "[configuration]") {
|
||||
constexpr const char Extra[] = R"(OpenGLDebugContext = { Activate = true })";
|
||||
const Configuration c = loadConfiguration("openGLDebugContext1", Extra);
|
||||
CHECK(c.openGLDebugContext.isActive == true);
|
||||
CHECK(c.openGLDebugContext.printStacktrace == false);
|
||||
CHECK(
|
||||
c.openGLDebugContext.isSynchronous ==
|
||||
defaultConf.openGLDebugContext.isSynchronous
|
||||
@@ -457,6 +452,7 @@ OpenGLDebugContext = { Activate = true, Synchronous = true }
|
||||
constexpr const char Extra[] = R"(
|
||||
OpenGLDebugContext = {
|
||||
Activate = true,
|
||||
PrintStacktrace = true,
|
||||
FilterIdentifier = {
|
||||
{ Identifier = 1, Source = "API", Type = "Error" },
|
||||
{ Identifier = 2, Source = "Window System", Type = "Deprecated" },
|
||||
@@ -473,6 +469,7 @@ OpenGLDebugContext = {
|
||||
)";
|
||||
const Configuration c = loadConfiguration("openGLDebugContext3", Extra);
|
||||
CHECK(c.openGLDebugContext.isActive == true);
|
||||
CHECK(c.openGLDebugContext.printStacktrace == true);
|
||||
CHECK(
|
||||
c.openGLDebugContext.isSynchronous ==
|
||||
defaultConf.openGLDebugContext.isSynchronous
|
||||
@@ -521,6 +518,7 @@ OpenGLDebugContext = { Activate = true, FilterSeverity = { "High", "Medium" } }
|
||||
)";
|
||||
const Configuration c = loadConfiguration("openGLDebugContext4", Extra);
|
||||
CHECK(c.openGLDebugContext.isActive == true);
|
||||
CHECK(c.openGLDebugContext.printStacktrace == false);
|
||||
CHECK(
|
||||
c.openGLDebugContext.isSynchronous ==
|
||||
defaultConf.openGLDebugContext.isSynchronous
|
||||
|
||||
Reference in New Issue
Block a user