mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-05 19:19:39 -06:00
solve merge conflict
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -44,6 +44,7 @@ include/openspace/version.h
|
||||
data/scene/67P/obj/67P_rotated_5_130.obj
|
||||
data/spice/NewHorizonsKernels/
|
||||
data/spice/RosettaKernels/
|
||||
data/scene/plutoprojectionhybrid/textures/
|
||||
data/scene/plutoprojectionhybrid/textures/Shenk_180.jpg
|
||||
data/scene/plutoprojectionhybrid/textures/barycenter.png
|
||||
data/scene/plutoprojectionhybrid/textures/defaultProj.png
|
||||
@@ -105,6 +106,7 @@ data/scene/newhorizons/models/NewHorizonsCleanModel.obj
|
||||
data/scene/newhorizons/textures/NHTextureFlipCol.jpg
|
||||
data/scene/newhorizons/textures/goldfoilbump.tif
|
||||
data/scene/newhorizons/textures/labels.png
|
||||
data/scene/pluto/textures/
|
||||
data/scene/pluto/textures/Shenk_180.jpg
|
||||
data/scene/pluto/textures/pluto_highres_180.jpg
|
||||
data/scene/plutoprojectionhybrid/assets/core_v9h_obs_getmets_v8_time_fix_nofrcd_mld.txt
|
||||
|
||||
@@ -36,7 +36,7 @@ set(GHOUL_BASE_DIR "${OPENSPACE_BASE_DIR}/ext/ghoul")
|
||||
|
||||
include(${OPENSPACE_CMAKE_EXT_DIR}/support_macros.cmake)
|
||||
include(${OPENSPACE_CMAKE_EXT_DIR}/module_common.cmake)
|
||||
include(${GHOUL_BASE_DIR}/ext/CopySharedLibraries.cmake)
|
||||
include(${GHOUL_BASE_DIR}/support/cmake/CopySharedLibraries.cmake)
|
||||
|
||||
test_compiler_compatibility()
|
||||
cleanup_project()
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
set(APPLICATION_NAME Launcher)
|
||||
set(APPLICATION_LINK_TO_OPENSPACE ON)
|
||||
|
||||
include (${GHOUL_BASE_DIR}/ext/handle_external_library.cmake)
|
||||
include (${GHOUL_BASE_DIR}/support/cmake/handle_external_library.cmake)
|
||||
|
||||
set(application_path ${OPENSPACE_APPS_DIR}/Launcher)
|
||||
|
||||
|
||||
@@ -130,4 +130,4 @@ return {
|
||||
},
|
||||
GuiName = "/Solar/67PTrail"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
51
data/scene/toyvolume/toyvolume.mod
Normal file
51
data/scene/toyvolume/toyvolume.mod
Normal file
@@ -0,0 +1,51 @@
|
||||
return {
|
||||
{
|
||||
Name = "ToyVolume 1",
|
||||
Parent = "Sun",
|
||||
Ephemeris = {
|
||||
Type = "Static",
|
||||
Position = {0, 0, 0, 0}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableToyVolume",
|
||||
Color = {1.0, 0.0, 0.0, 0.7},
|
||||
Translation = {0, 0, 0},
|
||||
Rotation = {0.5, 0, 0},
|
||||
ScalingExponent = 11
|
||||
},
|
||||
GuiName = "/Volumes/ToyVolume1"
|
||||
},
|
||||
{
|
||||
Name = "ToyVolume 2",
|
||||
Parent = "Earth",
|
||||
Ephemeris = {
|
||||
Type = "Static",
|
||||
Position = {0, 0, 0, 0}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableToyVolume",
|
||||
Color = {1.0, 0.8, 0.0, 0.7},
|
||||
Translation = {0.0, 0.0, 0.0},
|
||||
Scaling = {5.0, 2.5, 5.0},
|
||||
ScalingExponent = 6
|
||||
},
|
||||
GuiName = "/Volumes/ToyVolume2"
|
||||
},
|
||||
{
|
||||
Name = "ToyVolume 3",
|
||||
Parent = "Earth",
|
||||
Ephemeris = {
|
||||
Type = "Static",
|
||||
Translation = {0, 0, 0, 0}
|
||||
},
|
||||
Renderable = {
|
||||
Type = "RenderableToyVolume",
|
||||
Scaling = {2.0, 2.0, 2.0},
|
||||
Rotation = {3.14/2.0, 0, 0},
|
||||
Color = {1.0, 1.0, 1.0, 0.7},
|
||||
Translation = {0.0, 0.0, 0.0},
|
||||
ScalingExponent = 6
|
||||
},
|
||||
GuiName = "/Volumes/ToyVolume3"
|
||||
}
|
||||
}
|
||||
@@ -125,4 +125,4 @@ return {
|
||||
},
|
||||
GuiName = "/Solar/VestaTrail"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Submodule ext/ghoul updated: ae36394e9c...f31ddda5d7
@@ -34,8 +34,11 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
#include <openspace/rendering/volume.h>
|
||||
#include <openspace/rendering/renderer.h>
|
||||
#include <openspace/rendering/raycasterlistener.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
namespace ghoul {
|
||||
|
||||
@@ -54,7 +57,7 @@ class RenderableVolume;
|
||||
class Camera;
|
||||
class Scene;
|
||||
|
||||
class ABufferRenderer : public Renderer {
|
||||
class ABufferRenderer : public Renderer, public RaycasterListener {
|
||||
public:
|
||||
ABufferRenderer();
|
||||
virtual ~ABufferRenderer();
|
||||
@@ -69,42 +72,52 @@ public:
|
||||
void update();
|
||||
void render(float blackoutFactor, bool doPerformanceMeasurements) override;
|
||||
|
||||
|
||||
/**
|
||||
* Update render data
|
||||
* Responsible for calling renderEngine::setRenderData
|
||||
*/
|
||||
virtual void updateRendererData() override;
|
||||
|
||||
virtual void raycastersChanged(VolumeRaycaster& raycaster, bool attached) override;
|
||||
private:
|
||||
|
||||
void clear();
|
||||
void updateResolution();
|
||||
ghoul::Dictionary createResolveDictionary();
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> createResolveProgram(const ghoul::Dictionary& dict);
|
||||
void updateRaycastData();
|
||||
void updateResolveDictionary();
|
||||
|
||||
Camera* _camera;
|
||||
Scene* _scene;
|
||||
glm::ivec2 _resolution;
|
||||
|
||||
bool _dirtyResolution;
|
||||
bool _dirtyRendererData;
|
||||
bool _dirtyRaycastData;
|
||||
bool _dirtyResolveDictionary;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _resolveProgram;
|
||||
|
||||
/**
|
||||
* When a volume is attached or detached from the scene graph,
|
||||
* the resolve program needs to be recompiled.
|
||||
* The #_volumes vector keeps track of which volumes that can
|
||||
* be rendered using the current resolve program.
|
||||
* 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::vector<Volume*> _volumes;
|
||||
std::map<VolumeRaycaster*, RaycastData> _raycastData;
|
||||
std::map<VolumeRaycaster*, std::unique_ptr<ghoul::opengl::ProgramObject>> _boundsPrograms;
|
||||
std::vector<std::string> _helperPaths;
|
||||
|
||||
GLuint _screenQuad;
|
||||
GLuint _anchorPointerTexture;
|
||||
GLuint _anchorPointerTextureInitializer;
|
||||
GLuint _atomicCounterBuffer;
|
||||
GLuint _fragmentBuffer;
|
||||
GLuint _fragmentTexture;
|
||||
GLuint _vertexPositionBuffer;
|
||||
int _nAaSamples;
|
||||
ghoul::Dictionary _resolveDictionary;
|
||||
|
||||
GLuint _screenQuad;
|
||||
GLuint _anchorPointerTexture;
|
||||
GLuint _anchorPointerTextureInitializer;
|
||||
GLuint _atomicCounterBuffer;
|
||||
GLuint _fragmentBuffer;
|
||||
GLuint _fragmentTexture;
|
||||
GLuint _vertexPositionBuffer;
|
||||
int _nAaSamples;
|
||||
|
||||
ghoul::Dictionary _rendererData;
|
||||
}; // ABufferRenderer
|
||||
|
||||
@@ -32,8 +32,9 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <openspace/rendering/volume.h>
|
||||
#include <openspace/rendering/raycasterlistener.h>
|
||||
#include <openspace/rendering/renderer.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
namespace ghoul {
|
||||
class Dictionary;
|
||||
@@ -53,13 +54,16 @@ class RenderableVolume;
|
||||
class Camera;
|
||||
class Scene;
|
||||
|
||||
class FramebufferRenderer : public Renderer {
|
||||
class FramebufferRenderer : public Renderer, public RaycasterListener {
|
||||
public:
|
||||
FramebufferRenderer();
|
||||
virtual ~FramebufferRenderer();
|
||||
|
||||
void initialize() override;
|
||||
void deinitialize() override;
|
||||
|
||||
void updateResolution();
|
||||
void updateRaycastData();
|
||||
|
||||
void setCamera(Camera* camera) override;
|
||||
void setScene(Scene* scene) override;
|
||||
@@ -73,11 +77,34 @@ public:
|
||||
* Responsible for calling renderEngine::setRenderData
|
||||
*/
|
||||
virtual void updateRendererData() override;
|
||||
|
||||
virtual void raycastersChanged(VolumeRaycaster& raycaster, bool attached) override;
|
||||
private:
|
||||
|
||||
std::map<VolumeRaycaster*, RaycastData> _raycastData;
|
||||
std::map<VolumeRaycaster*, std::unique_ptr<ghoul::opengl::ProgramObject>> _exitPrograms;
|
||||
std::map<VolumeRaycaster*, std::unique_ptr<ghoul::opengl::ProgramObject>> _raycastPrograms;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _resolveProgram;
|
||||
|
||||
GLuint _screenQuad;
|
||||
GLuint _vertexPositionBuffer;
|
||||
GLuint _mainColorTexture;
|
||||
GLuint _mainDepthTexture;
|
||||
GLuint _exitColorTexture;
|
||||
GLuint _mainFramebuffer;
|
||||
GLuint _exitDepthTexture;
|
||||
GLuint _exitFramebuffer;
|
||||
|
||||
bool _dirtyRaycastData;
|
||||
bool _dirtyResolution;
|
||||
|
||||
Camera* _camera;
|
||||
Scene* _scene;
|
||||
glm::vec2 _resolution;
|
||||
glm::vec2 _resolution;
|
||||
int _nAaSamples;
|
||||
|
||||
ghoul::Dictionary _rendererData;
|
||||
}; // FramebufferRenderer
|
||||
} // openspace
|
||||
|
||||
|
||||
39
include/openspace/rendering/raycasterlistener.h
Normal file
39
include/openspace/rendering/raycasterlistener.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* 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 __RAYCASTERLISTENER_H__
|
||||
#define __RAYCASTERLISTENER_H__
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class VolumeRaycaster;
|
||||
|
||||
class RaycasterListener {
|
||||
public:
|
||||
virtual void raycastersChanged(VolumeRaycaster& raycaster, bool attached) = 0;
|
||||
}; // RaycasterListener
|
||||
|
||||
} // openspace
|
||||
|
||||
#endif // __RAYCASTERLISTENER_H__
|
||||
53
include/openspace/rendering/raycastermanager.h
Normal file
53
include/openspace/rendering/raycastermanager.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* 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 __RAYCASTERMANAGER_H__
|
||||
#define __RAYCASTERMANAGER_H__
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class VolumeRaycaster;
|
||||
class RaycasterListener;
|
||||
|
||||
class RaycasterManager {
|
||||
public:
|
||||
RaycasterManager();
|
||||
~RaycasterManager();
|
||||
void attachRaycaster(VolumeRaycaster& raycaster);
|
||||
void detachRaycaster(VolumeRaycaster& raycaster);
|
||||
bool isAttached(VolumeRaycaster& raycaster);
|
||||
const std::vector<VolumeRaycaster*>& raycasters();
|
||||
|
||||
void addListener(RaycasterListener& listener);
|
||||
void removeListener(RaycasterListener& listener);
|
||||
private:
|
||||
std::vector<VolumeRaycaster*> _raycasters;
|
||||
std::vector<RaycasterListener*> _listeners;
|
||||
}; // Volume
|
||||
|
||||
} // openspace
|
||||
|
||||
#endif // __RAYCASTERMANAGER_H__
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
@@ -29,7 +30,6 @@
|
||||
#include <openspace/properties/scalarproperty.h>
|
||||
#include <openspace/util/powerscaledscalar.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/rendering/volume.h>
|
||||
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
@@ -45,8 +45,7 @@ namespace ghoul {
|
||||
namespace openspace {
|
||||
|
||||
// Forward declare to minimize dependencies
|
||||
struct RenderData;
|
||||
struct UpdateData;
|
||||
|
||||
class Camera;
|
||||
class PowerScaledCoordinate;
|
||||
|
||||
@@ -67,9 +66,9 @@ public:
|
||||
void setBoundingSphere(const PowerScaledScalar& boundingSphere);
|
||||
const PowerScaledScalar& getBoundingSphere();
|
||||
|
||||
virtual void render(const RenderData& data) = 0;
|
||||
virtual void render(const RenderData& data);
|
||||
virtual void render(const RenderData& data, RendererTasks& rendererTask);
|
||||
virtual void update(const UpdateData& data);
|
||||
virtual std::vector<Volume*> volumesToRender(const RenderData& data) const;
|
||||
|
||||
bool isVisible() const;
|
||||
|
||||
@@ -80,12 +79,12 @@ public:
|
||||
bool getBody(std::string& body);
|
||||
void setBody(std::string& body);
|
||||
|
||||
protected:
|
||||
void setPscUniforms(ghoul::opengl::ProgramObject* program, const Camera* camera, const PowerScaledCoordinate& position);
|
||||
void onEnabledChange(std::function<void(bool)> callback);
|
||||
|
||||
static void setPscUniforms(ghoul::opengl::ProgramObject& program, const Camera& camera, const PowerScaledCoordinate& position);
|
||||
|
||||
private:
|
||||
properties::BoolProperty _enabled;
|
||||
|
||||
PowerScaledScalar boundingSphere_;
|
||||
std::string _startTime;
|
||||
std::string _endTime;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
|
||||
|
||||
namespace ghoul {
|
||||
namespace fontrendering {
|
||||
class Font;
|
||||
@@ -49,6 +50,7 @@ class Camera;
|
||||
class SyncBuffer;
|
||||
class Scene;
|
||||
class Renderer;
|
||||
class RaycasterManager;
|
||||
class ScreenLog;
|
||||
class ScreenSpaceRenderable;
|
||||
|
||||
@@ -77,6 +79,7 @@ public:
|
||||
Camera* camera() const;
|
||||
Renderer* renderer() const;
|
||||
RendererImplementation rendererImplementation() const;
|
||||
RaycasterManager& raycasterManager();
|
||||
|
||||
// sgct wrapped functions
|
||||
bool initializeGL();
|
||||
@@ -156,6 +159,8 @@ private:
|
||||
|
||||
Camera* _mainCamera;
|
||||
Scene* _sceneGraph;
|
||||
RaycasterManager* _raycasterManager;
|
||||
|
||||
std::unique_ptr<Renderer> _renderer;
|
||||
RendererImplementation _rendererImplementation;
|
||||
ghoul::Dictionary _rendererData;
|
||||
|
||||
125
include/openspace/rendering/volumeraycaster.h
Normal file
125
include/openspace/rendering/volumeraycaster.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* 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 __VOLUMERAYCASTER_H__
|
||||
#define __VOLUMERAYCASTER_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
namespace ghoul {
|
||||
namespace opengl {
|
||||
class Texture;
|
||||
class ProgramObject;
|
||||
}
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class RenderData;
|
||||
class RaycastData;
|
||||
|
||||
class VolumeRaycaster {
|
||||
public:
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~VolumeRaycaster() {};
|
||||
|
||||
/**
|
||||
* Render the volume's entry points (front face of the bounding geometry)
|
||||
*/
|
||||
virtual void renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) = 0;
|
||||
|
||||
/**
|
||||
* Render the volume's exit points (back face of the bounding geometry)
|
||||
*/
|
||||
virtual void renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) = 0;
|
||||
|
||||
/**
|
||||
* Prepare the volume for the ABuffer's resolve step.
|
||||
* Make sure textures are up to date, bind them to texture units, set program uniforms etc.
|
||||
*/
|
||||
virtual void preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {};
|
||||
|
||||
/**
|
||||
* Clean up for the volume after the ABuffer's resolve step.
|
||||
* Make sure texture units are deinitialized, etc.
|
||||
*/
|
||||
virtual void postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {};
|
||||
|
||||
/**
|
||||
* Return a path the file to use as vertex shader
|
||||
*
|
||||
* The shader preprocessor will have acceess to
|
||||
* A #{namespace} variable (unique per helper file)
|
||||
*/
|
||||
virtual std::string getBoundsVsPath() const = 0;
|
||||
|
||||
/*
|
||||
* Return a path to a file with the functions, uniforms and fragment shader in variables
|
||||
* required to generate the fragment color and depth.
|
||||
*
|
||||
* Should define the function:
|
||||
* Fragment getFragment()
|
||||
*
|
||||
* The shader preprocessor will have acceess to
|
||||
* A #{namespace} variable (unique per helper file)
|
||||
*/
|
||||
virtual std::string getBoundsFsPath() const = 0 ;
|
||||
|
||||
/**
|
||||
* Return a path to a file with all the uniforms, functions etc
|
||||
* required to perform ray casting through this volume.
|
||||
*
|
||||
* The header should define the following two functions:
|
||||
* vec4 sample#{id}(vec3 samplePos, vec3 dir, float occludingAlpha, inout float maxStepSize)
|
||||
* (return color of sample)
|
||||
* float stepSize#{id}(vec3 samplePos, vec3 dir)
|
||||
* (return the preferred step size at this sample position)
|
||||
*
|
||||
* The shader preprocessor will have acceess to
|
||||
* An #{id} variable (unique per volume)
|
||||
* A #{namespace} variable (unique per helper file)
|
||||
*/
|
||||
virtual std::string getRaycastPath() const = 0;
|
||||
|
||||
/**
|
||||
* Return a path to a glsl file with helper functions required for the
|
||||
* transformation and raycast steps.
|
||||
* This file will be included once per shader program generated,
|
||||
* regardless of how many volumes say they require the file.
|
||||
* Ideal to avoid redefinitions of helper functions.
|
||||
*
|
||||
* The shader preprocessor will have access to the #{namespace} variable (unique per helper file)
|
||||
* which should be a prefix to all symbols defined by the helper
|
||||
*/
|
||||
virtual std::string getHelperPath() const = 0;
|
||||
|
||||
}; // Raycaster
|
||||
|
||||
} // openspace
|
||||
|
||||
#endif // __VOLUMERAYCASTER_H__
|
||||
@@ -41,7 +41,6 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class Volume;
|
||||
class SceneGraphNode;
|
||||
|
||||
// Notifications:
|
||||
@@ -83,12 +82,8 @@ public:
|
||||
/*
|
||||
* Render visible SceneGraphNodes using the provided camera
|
||||
*/
|
||||
void render(const RenderData& data);
|
||||
void render(const RenderData& data, RendererTasks& tasks);
|
||||
|
||||
/*
|
||||
* Return a vector of volumes to render and their acciciated render data
|
||||
*/
|
||||
std::vector<std::pair<Volume*, RenderData>> volumesToRender(const RenderData& data) const;
|
||||
/*
|
||||
* Returns the root SceneGraphNode
|
||||
*/
|
||||
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
|
||||
void update(const UpdateData& data);
|
||||
void evaluate(const Camera* camera, const psc& parentPosition = psc());
|
||||
void render(const RenderData& data);
|
||||
void render(const RenderData& data, RendererTasks& tasks);
|
||||
void updateCamera(Camera* camera) const;
|
||||
|
||||
//void addNode(SceneGraphNode* child);
|
||||
@@ -90,7 +90,6 @@ public:
|
||||
void setRenderable(Renderable* renderable);
|
||||
const Renderable* renderable() const;
|
||||
Renderable* renderable();
|
||||
std::vector<std::pair<Volume*, RenderData>> volumesToRender(const RenderData& data) const;
|
||||
|
||||
// @TODO Remove once the scalegraph is in effect ---abock
|
||||
void setEphemeris(Ephemeris* eph) {
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class VolumeRaycaster;
|
||||
|
||||
struct InitializeData {
|
||||
|
||||
};
|
||||
@@ -47,6 +49,21 @@ struct RenderData {
|
||||
bool doPerformanceMeasurement;
|
||||
};
|
||||
|
||||
struct RaycasterTask {
|
||||
VolumeRaycaster* raycaster;
|
||||
RenderData renderData;
|
||||
};
|
||||
|
||||
struct RendererTasks {
|
||||
std::vector<RaycasterTask> raycasterTasks;
|
||||
};
|
||||
|
||||
struct RaycastData {
|
||||
int id;
|
||||
std::string namespaceName;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // __UPDATESTRUCTURES_H__
|
||||
|
||||
@@ -96,4 +96,4 @@ create_new_module(
|
||||
"Base"
|
||||
base_module
|
||||
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
|
||||
)
|
||||
)
|
||||
|
||||
@@ -67,6 +67,7 @@ namespace openspace {
|
||||
{
|
||||
Vertex vv;
|
||||
memcpy(vv.location, v.location, sizeof(GLfloat) * 3);
|
||||
vv.location[3] = 0.0;
|
||||
memcpy(vv.tex, v.tex, sizeof(GLfloat) * 2);
|
||||
memcpy(vv.normal, v.normal, sizeof(GLfloat) * 3);
|
||||
_vertices.push_back(vv);
|
||||
|
||||
@@ -162,7 +162,7 @@ void RenderableConstellationBounds::render(const RenderData& data) {
|
||||
glm::mat4 viewMatrix = data.camera.viewMatrix();
|
||||
glm::mat4 projectionMatrix = data.camera.projectionMatrix();
|
||||
|
||||
setPscUniforms(_program.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_program.get(), data.camera, data.position);
|
||||
|
||||
_program->setUniform("exponent", _distance);
|
||||
_program->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
|
||||
@@ -200,7 +200,7 @@ void RenderableModel::render(const RenderData& data) {
|
||||
_programObject->setUniform("sun_pos", _sunPosition.vec3());
|
||||
_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_programObject->setUniform("ModelTransform", transform);
|
||||
setPscUniforms(_programObject.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_programObject.get(), data.camera, data.position);
|
||||
|
||||
_programObject->setUniform("_performShading", _performShading);
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ void RenderablePath::render(const RenderData& data) {
|
||||
_programObject->setUniform("ModelTransform", transform);
|
||||
_programObject->setUniform("color", _lineColor);
|
||||
_programObject->setUniform("lastPosition", _lastPosition);
|
||||
setPscUniforms(_programObject.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_programObject.get(), data.camera, data.position);
|
||||
|
||||
if (_drawLine) {
|
||||
glLineWidth(_lineWidth);
|
||||
|
||||
@@ -206,7 +206,7 @@ void RenderablePlane::render(const RenderData& data) {
|
||||
|
||||
_shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_shader->setUniform("ModelTransform", transform);
|
||||
setPscUniforms(_shader.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_shader.get(), data.camera, data.position);
|
||||
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
|
||||
@@ -213,7 +213,7 @@ void RenderablePlanet::render(const RenderData& data)
|
||||
_programObject->setUniform("transparency", _alpha);
|
||||
_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_programObject->setUniform("ModelTransform", transform);
|
||||
setPscUniforms(_programObject.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_programObject.get(), data.camera, data.position);
|
||||
|
||||
_programObject->setUniform("_performShading", _performShading);
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ void RenderableSphere::render(const RenderData& data) {
|
||||
_shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_shader->setUniform("ModelTransform", transform);
|
||||
|
||||
setPscUniforms(_shader.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_shader.get(), data.camera, data.position);
|
||||
_shader->setUniform("alpha", _transparency);
|
||||
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
|
||||
@@ -212,7 +212,7 @@ void RenderableSphericalGrid::render(const RenderData& data){
|
||||
_gridProgram->setIgnoreUniformLocationError(IgnoreError::Yes);
|
||||
_gridProgram->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_gridProgram->setUniform("ModelTransform", transform);
|
||||
setPscUniforms(_gridProgram, &data.camera, data.position);
|
||||
setPscUniforms(*_gridProgram, data.camera, data.position);
|
||||
_gridProgram->setUniform("gridColor", _gridColor);
|
||||
|
||||
glLineWidth(0.5f);
|
||||
|
||||
@@ -203,7 +203,7 @@ void RenderableStars::render(const RenderData& data) {
|
||||
_program->setUniform("scaleFactor", _scaleFactor);
|
||||
_program->setUniform("minBillboardSize", _minBillboardSize);
|
||||
|
||||
setPscUniforms(_program.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_program.get(), data.camera, data.position);
|
||||
_program->setUniform("scaling", scaling);
|
||||
|
||||
ghoul::opengl::TextureUnit psfUnit;
|
||||
|
||||
@@ -155,7 +155,7 @@ void RenderableTrail::render(const RenderData& data) {
|
||||
// setup the data to the shader
|
||||
_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_programObject->setUniform("ModelTransform", transform);
|
||||
setPscUniforms(_programObject.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_programObject.get(), data.camera, data.position);
|
||||
|
||||
_programObject->setUniform("color", _lineColor);
|
||||
_programObject->setUniform("nVertices", static_cast<unsigned int>(_vertexArray.size()));
|
||||
|
||||
@@ -72,5 +72,7 @@ create_new_module(
|
||||
endif ()
|
||||
set_property(TARGET cdf PROPERTY FOLDER "External")
|
||||
endif ()
|
||||
|
||||
# Boost
|
||||
find_package(Boost REQUIRED)
|
||||
target_include_directories(openspace-module-kameleon SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
|
||||
#include_external_library(${onscreengui_module} Imgui ${CMAKE_CURRENT_SOURCE_DIR}/ext/kameleon)
|
||||
|
||||
@@ -140,7 +140,7 @@ void RenderableCrawlingLine::render(const RenderData& data) {
|
||||
|
||||
_program->setUniform("_alpha", alpha);
|
||||
_program->setUniform("color", _lineColor);
|
||||
setPscUniforms(_program.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_program.get(), data.camera, data.position);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
|
||||
@@ -549,7 +549,7 @@ void RenderableFov::render(const RenderData& data) {
|
||||
// setup the data to the shader
|
||||
_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_programObject->setUniform("ModelTransform", glm::mat4(1));
|
||||
setPscUniforms(_programObject.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_programObject.get(), data.camera, data.position);
|
||||
|
||||
if (openspace::ImageSequencer2::ref().isReady())
|
||||
_drawFOV = ImageSequencer2::ref().instrumentActive(_instrumentID);
|
||||
|
||||
@@ -331,7 +331,7 @@ void RenderableModelProjection::render(const RenderData& data) {
|
||||
_viewProjection = data.camera.viewProjectionMatrix();
|
||||
_programObject->setUniform("ViewProjection", _viewProjection);
|
||||
_programObject->setUniform("ModelTransform", _transform);
|
||||
setPscUniforms(_programObject.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_programObject.get(), data.camera, data.position);
|
||||
|
||||
textureBind();
|
||||
_geometry->render();
|
||||
|
||||
@@ -147,7 +147,7 @@ void RenderablePlaneProjection::render(const RenderData& data) {
|
||||
|
||||
_shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_shader->setUniform("ModelTransform", transform);
|
||||
setPscUniforms(_shader.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_shader.get(), data.camera, data.position);
|
||||
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
|
||||
@@ -541,7 +541,7 @@ void RenderablePlanetProjection::render(const RenderData& data){
|
||||
_programObject->setUniform("ViewProjection" , data.camera.viewProjectionMatrix());
|
||||
_programObject->setUniform("ModelTransform" , _transform);
|
||||
_programObject->setUniform("boresight" , _boresight);
|
||||
setPscUniforms(_programObject.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_programObject.get(), data.camera, data.position);
|
||||
|
||||
textureBind();
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ void RenderableShadowCylinder::render(const RenderData& data){
|
||||
_shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_shader->setUniform("ModelTransform", _transform);
|
||||
_shader->setUniform("shadowColor", _shadowColor);
|
||||
setPscUniforms(_shader.get(), &data.camera, data.position);
|
||||
setPscUniforms(*_shader.get(), data.camera, data.position);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, static_cast<GLsizei>(_vertices.size()));
|
||||
|
||||
43
modules/toyvolume/CMakeLists.txt
Normal file
43
modules/toyvolume/CMakeLists.txt
Normal file
@@ -0,0 +1,43 @@
|
||||
#########################################################################################
|
||||
# #
|
||||
# OpenSpace #
|
||||
# #
|
||||
# Copyright (c) 2014-2016 #
|
||||
# #
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of this #
|
||||
# software and associated documentation files (the "Software"), to deal in the Software #
|
||||
# without restriction, including without limitation the rights to use, copy, modify, #
|
||||
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to #
|
||||
# permit persons to whom the Software is furnished to do so, subject to the following #
|
||||
# conditions: #
|
||||
# #
|
||||
# The above copyright notice and this permission notice shall be included in all copies #
|
||||
# or substantial portions of the Software. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
|
||||
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A #
|
||||
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT #
|
||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF #
|
||||
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE #
|
||||
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #
|
||||
#########################################################################################
|
||||
|
||||
include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
|
||||
|
||||
set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletoyvolume.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/toyvolumeraycaster.h
|
||||
)
|
||||
source_group("Header Files" FILES ${HEADER_FILES})
|
||||
|
||||
set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletoyvolume.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/toyvolumeraycaster.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
create_new_module(
|
||||
"ToyVolume"
|
||||
toyvolume_module
|
||||
${HEADER_FILES} ${SOURCE_FILES}
|
||||
)
|
||||
1
modules/toyvolume/include.cmake
Normal file
1
modules/toyvolume/include.cmake
Normal file
@@ -0,0 +1 @@
|
||||
set (DEFAULT_MODULE ON)
|
||||
140
modules/toyvolume/rendering/renderabletoyvolume.cpp
Normal file
140
modules/toyvolume/rendering/renderabletoyvolume.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/toyvolume/rendering/renderabletoyvolume.h>
|
||||
#include <modules/toyvolume/rendering/toyvolumeraycaster.h>
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
|
||||
|
||||
namespace {
|
||||
const std::string GlslRayCastPath = "${MODULES}/toyvolume/shaders/rayCast.glsl";
|
||||
const std::string GlslBoundsVsPath = "${MODULES}/toyvolume/shaders/boundsVs.glsl";
|
||||
const std::string GlslBoundsFsPath = "${MODULES}/toyvolume/shaders/boundsFs.glsl";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
RenderableToyVolume::RenderableToyVolume(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _scalingExponent("scalingExponent", "Scaling Exponent", 1, -10, 20)
|
||||
, _stepSize("stepSize", "Step Size", 0.02, 0.01, 1)
|
||||
, _scaling("scaling", "Scaling", glm::vec3(1.0, 1.0, 1.0), glm::vec3(0.0), glm::vec3(10.0))
|
||||
, _translation("translation", "Translation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0), glm::vec3(10.0))
|
||||
, _rotation("rotation", "Euler rotation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0), glm::vec3(6.28))
|
||||
, _color("color", "Color", glm::vec4(1.0, 0.0, 0.0, 0.1), glm::vec4(0.0), glm::vec4(1.0)) {
|
||||
|
||||
float scalingExponent, stepSize;
|
||||
glm::vec3 scaling, translation, rotation;
|
||||
glm::vec4 color;
|
||||
if (dictionary.getValue("ScalingExponent", scalingExponent)) {
|
||||
_scalingExponent = scalingExponent;
|
||||
}
|
||||
if (dictionary.getValue("Scaling", scaling)) {
|
||||
_scaling = scaling;
|
||||
}
|
||||
if (dictionary.getValue("Translation", translation)) {
|
||||
_translation = translation;
|
||||
}
|
||||
if (dictionary.getValue("Rotation", rotation)) {
|
||||
_rotation = rotation;
|
||||
}
|
||||
if (dictionary.getValue("Color", color)) {
|
||||
_color = color;
|
||||
}
|
||||
if (dictionary.getValue("StepSize", stepSize)) {
|
||||
_stepSize = stepSize;
|
||||
}
|
||||
}
|
||||
|
||||
RenderableToyVolume::~RenderableToyVolume() {}
|
||||
|
||||
bool RenderableToyVolume::initialize() {
|
||||
_raycaster = std::make_unique<ToyVolumeRaycaster>(ToyVolumeRaycaster(_color));
|
||||
_raycaster->initialize();
|
||||
|
||||
OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get());
|
||||
|
||||
std::function<void(bool)> onChange = [&](bool enabled) {
|
||||
if (enabled) {
|
||||
OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get());
|
||||
}
|
||||
else {
|
||||
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
|
||||
}
|
||||
};
|
||||
|
||||
onEnabledChange(onChange);
|
||||
|
||||
addProperty(_scaling);
|
||||
addProperty(_scalingExponent);
|
||||
addProperty(_stepSize);
|
||||
addProperty(_translation);
|
||||
addProperty(_rotation);
|
||||
addProperty(_color);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderableToyVolume::deinitialize() {
|
||||
if (_raycaster) {
|
||||
OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get());
|
||||
_raycaster = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderableToyVolume::isReady() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderableToyVolume::update(const UpdateData& data) {
|
||||
if (_raycaster) {
|
||||
|
||||
glm::mat4 transform = glm::translate(glm::mat4(1.0), static_cast<glm::vec3>(_translation) * std::pow(10.0f, static_cast<float>(_scalingExponent)));
|
||||
glm::vec3 eulerRotation = static_cast<glm::vec3>(_rotation);
|
||||
transform = glm::rotate(transform, eulerRotation.x, glm::vec3(1, 0, 0));
|
||||
transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0, 1, 0));
|
||||
transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0, 0, 1));
|
||||
transform = glm::scale(transform, static_cast<glm::vec3>(_scaling) * std::pow(10.0f, static_cast<float>(_scalingExponent)));
|
||||
|
||||
_raycaster->setColor(_color);
|
||||
_raycaster->setStepSize(_stepSize);
|
||||
_raycaster->setModelTransform(transform);
|
||||
_raycaster->setTime(data.time);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableToyVolume::render(const RenderData& data, RendererTasks& tasks) {
|
||||
RaycasterTask task{ _raycaster.get(), data };
|
||||
tasks.raycasterTasks.push_back(task);
|
||||
}
|
||||
|
||||
}
|
||||
62
modules/toyvolume/rendering/renderabletoyvolume.h
Normal file
62
modules/toyvolume/rendering/renderabletoyvolume.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* 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 __RENDERABLETOYVOLUME_H__
|
||||
#define __RENDERABLETOYVOLUME_H__
|
||||
|
||||
#include <openspace/properties/vectorproperty.h>
|
||||
#include <openspace/util/boxgeometry.h>
|
||||
#include <openspace/util/blockplaneintersectiongeometry.h>
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <modules/toyvolume/rendering/toyvolumeraycaster.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct RenderData;
|
||||
|
||||
class RenderableToyVolume : public Renderable {
|
||||
public:
|
||||
RenderableToyVolume(const ghoul::Dictionary& dictionary);
|
||||
~RenderableToyVolume();
|
||||
|
||||
bool initialize() override;
|
||||
bool deinitialize() override;
|
||||
bool isReady() const override;
|
||||
void render(const RenderData& data, RendererTasks& tasks) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
private:
|
||||
properties::Vec3Property _scaling;
|
||||
properties::IntProperty _scalingExponent;
|
||||
properties::FloatProperty _stepSize;
|
||||
properties::Vec3Property _translation;
|
||||
properties::Vec3Property _rotation;
|
||||
properties::Vec4Property _color;
|
||||
|
||||
std::unique_ptr<ToyVolumeRaycaster> _raycaster;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __RENDERABLETOYVOLUME_H__
|
||||
131
modules/toyvolume/rendering/toyvolumeraycaster.cpp
Normal file
131
modules/toyvolume/rendering/toyvolumeraycaster.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/toyvolume/rendering/toyvolumeraycaster.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <sstream>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
namespace {
|
||||
const std::string GlslRaycastPath = "${MODULES}/toyvolume/shaders/raycast.glsl";
|
||||
const std::string GlslBoundsVsPath = "${MODULES}/toyvolume/shaders/boundsVs.glsl";
|
||||
const std::string GlslBoundsFsPath = "${MODULES}/toyvolume/shaders/boundsFs.glsl";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
ToyVolumeRaycaster::ToyVolumeRaycaster(glm::vec4 color)
|
||||
: _boundingBox(glm::vec3(1.0))
|
||||
, _color(color) {}
|
||||
|
||||
ToyVolumeRaycaster::~ToyVolumeRaycaster() {}
|
||||
|
||||
void ToyVolumeRaycaster::initialize() {
|
||||
_boundingBox.initialize();
|
||||
}
|
||||
|
||||
void ToyVolumeRaycaster::deinitialize() {
|
||||
}
|
||||
|
||||
void ToyVolumeRaycaster::renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) {
|
||||
program.setUniform("modelTransform", _modelTransform);
|
||||
program.setUniform("viewProjection", data.camera.viewProjectionMatrix());
|
||||
Renderable::setPscUniforms(program, data.camera, data.position);
|
||||
|
||||
// Cull back face
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
// Render bounding geometry
|
||||
_boundingBox.render();
|
||||
}
|
||||
|
||||
void ToyVolumeRaycaster::renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) {
|
||||
// Uniforms
|
||||
program.setUniform("modelTransform", _modelTransform);
|
||||
program.setUniform("viewProjection", data.camera.viewProjectionMatrix());
|
||||
Renderable::setPscUniforms(program, data.camera, data.position);
|
||||
|
||||
// Cull front face
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_FRONT);
|
||||
|
||||
// Render bounding geometry
|
||||
_boundingBox.render();
|
||||
|
||||
// Restore defaults
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
|
||||
void ToyVolumeRaycaster::preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {
|
||||
std::string colorUniformName = "color" + std::to_string(data.id);
|
||||
std::string timeUniformName = "time" + std::to_string(data.id);
|
||||
std::string stepSizeUniformName = "maxStepSize" + std::to_string(data.id);
|
||||
program.setUniform(colorUniformName, _color);
|
||||
program.setUniform(stepSizeUniformName, _stepSize);
|
||||
program.setUniform(timeUniformName, static_cast<float>(std::fmod(_time, 3600.0)));
|
||||
}
|
||||
|
||||
void ToyVolumeRaycaster::postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {
|
||||
// For example: release texture units
|
||||
}
|
||||
|
||||
std::string ToyVolumeRaycaster::getBoundsVsPath() const {
|
||||
return GlslBoundsVsPath;
|
||||
}
|
||||
|
||||
std::string ToyVolumeRaycaster::getBoundsFsPath() const {
|
||||
return GlslBoundsFsPath;
|
||||
}
|
||||
|
||||
std::string ToyVolumeRaycaster::getRaycastPath() const {
|
||||
return GlslRaycastPath;
|
||||
}
|
||||
|
||||
std::string ToyVolumeRaycaster::getHelperPath() const {
|
||||
return ""; // no helper file
|
||||
}
|
||||
|
||||
void ToyVolumeRaycaster::setColor(glm::vec4 color) {
|
||||
_color = color;
|
||||
}
|
||||
|
||||
void ToyVolumeRaycaster::setModelTransform(glm::mat4 transform) {
|
||||
_modelTransform = transform;
|
||||
}
|
||||
|
||||
void ToyVolumeRaycaster::setTime(double time) {
|
||||
_time = time;
|
||||
}
|
||||
|
||||
void ToyVolumeRaycaster::setStepSize(float stepSize) {
|
||||
_stepSize = stepSize;
|
||||
}
|
||||
|
||||
}
|
||||
80
modules/toyvolume/rendering/toyvolumeraycaster.h
Normal file
80
modules/toyvolume/rendering/toyvolumeraycaster.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* 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 __TOYVOLUMERAYCASTER_H__
|
||||
#define __TOYVOLUMERAYCASTER_H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
#include <openspace/util/boxgeometry.h>
|
||||
#include <openspace/util/blockplaneintersectiongeometry.h>
|
||||
|
||||
namespace ghoul {
|
||||
namespace opengl {
|
||||
class Texture;
|
||||
class ProgramObject;
|
||||
}
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class RenderData;
|
||||
class RaycastData;
|
||||
|
||||
class ToyVolumeRaycaster : public VolumeRaycaster {
|
||||
public:
|
||||
|
||||
ToyVolumeRaycaster(glm::vec4 color);
|
||||
|
||||
virtual ~ToyVolumeRaycaster();
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
void renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override;
|
||||
void renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override;
|
||||
void preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override;
|
||||
void postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override;
|
||||
|
||||
std::string getBoundsVsPath() const override;
|
||||
std::string getBoundsFsPath() const override;
|
||||
std::string getRaycastPath() const override;
|
||||
std::string getHelperPath() const override;
|
||||
|
||||
void setColor(glm::vec4 color);
|
||||
void setModelTransform(glm::mat4 transform);
|
||||
void setTime(double time);
|
||||
void setStepSize(float time);
|
||||
private:
|
||||
BoxGeometry _boundingBox;
|
||||
glm::vec4 _color;
|
||||
glm::mat4 _modelTransform;
|
||||
float _stepSize;
|
||||
double _time;
|
||||
|
||||
}; // ToyVolumeRaycaster
|
||||
|
||||
} // openspace
|
||||
|
||||
#endif // __TOYVOLUMERAYCASTER_H__
|
||||
40
modules/toyvolume/shaders/boundsFs.glsl
Normal file
40
modules/toyvolume/shaders/boundsFs.glsl
Normal file
@@ -0,0 +1,40 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
in vec3 vPosition;
|
||||
in vec4 worldPosition;
|
||||
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
#include "fragment.glsl"
|
||||
|
||||
Fragment getFragment() {
|
||||
vec4 fragColor = vec4(vPosition+0.5, 1.0);
|
||||
vec4 position = worldPosition;
|
||||
float depth = pscDepth(position);
|
||||
|
||||
Fragment frag;
|
||||
frag.color = fragColor;
|
||||
frag.depth = depth;
|
||||
return frag;
|
||||
}
|
||||
47
modules/toyvolume/shaders/boundsVs.glsl
Normal file
47
modules/toyvolume/shaders/boundsVs.glsl
Normal file
@@ -0,0 +1,47 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec4 vertPosition;
|
||||
|
||||
uniform mat4 viewProjection;
|
||||
uniform mat4 modelTransform;
|
||||
|
||||
out vec3 vPosition;
|
||||
out vec4 worldPosition;
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
void main() {
|
||||
vPosition = vertPosition.xyz;
|
||||
worldPosition = modelTransform*vertPosition;
|
||||
|
||||
vec4 position = pscTransform(worldPosition, mat4(1.0));
|
||||
|
||||
// project the position to view space
|
||||
gl_Position = viewProjection * position;
|
||||
|
||||
gl_Position.z = 1.0;
|
||||
}
|
||||
58
modules/toyvolume/shaders/raycast.glsl
Normal file
58
modules/toyvolume/shaders/raycast.glsl
Normal file
@@ -0,0 +1,58 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2016 *
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
|
||||
uniform vec4 color#{id};
|
||||
uniform float time#{id};
|
||||
uniform float maxStepSize#{id} = 0.02;
|
||||
|
||||
vec4 sample#{id}(vec3 samplePos, vec3 dir, vec4 foregroundColor, inout float maxStepSize) {
|
||||
maxStepSize = maxStepSize#{id};
|
||||
|
||||
// Generate an arbitrary procedural volume.
|
||||
// In real situations, the sample function would sample a
|
||||
// 3D texture to retrieve the color contribution of a given point.
|
||||
|
||||
vec3 fromCenter = vec3(0.5, 0.5, 0.5) - samplePos;
|
||||
|
||||
vec4 c = color#{id};
|
||||
float r = length(fromCenter);
|
||||
c.a *= (1.0 - smoothstep(0.4, 0.45, r));
|
||||
c.a *= (1.0 - smoothstep(0.35, 0.3, r));
|
||||
c.a *= (1.0 - smoothstep(0.1, 0.2, abs(fromCenter.y)));
|
||||
|
||||
float theta = atan(fromCenter.x, fromCenter.z);
|
||||
float angularRatio = (theta + 3.1415) / 6.283;
|
||||
|
||||
angularRatio = mod(angularRatio + time#{id}*0.01, 1.0);
|
||||
|
||||
c.a *= smoothstep(0.0, 0.2, clamp(angularRatio, 0.0, 1.0));
|
||||
c.a *= smoothstep(1.0, 0.8, clamp(angularRatio, 0.0, 1.0));
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
float stepSize#{id}(vec3 samplePos, vec3 dir) {
|
||||
return maxStepSize#{id};
|
||||
}
|
||||
44
modules/toyvolume/toyvolumemodule.cpp
Normal file
44
modules/toyvolume/toyvolumemodule.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/toyvolume/toyvolumemodule.h>
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
|
||||
#include <ghoul/misc/assert.h>
|
||||
|
||||
#include <modules/toyvolume/rendering/renderabletoyvolume.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
ToyVolumeModule::ToyVolumeModule() : OpenSpaceModule("ToyVolume") {}
|
||||
|
||||
void ToyVolumeModule::internalInitialize() {
|
||||
auto fRenderable = FactoryManager::ref().factory<Renderable>();
|
||||
ghoul_assert(fRenderable, "No renderable factory existed");
|
||||
fRenderable->registerClass<RenderableToyVolume>("RenderableToyVolume");
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
40
modules/toyvolume/toyvolumemodule.h
Normal file
40
modules/toyvolume/toyvolumemodule.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* 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 __TOYVOLUMEMODULE_H__
|
||||
#define __TOYVOLUMEMODULE_H__
|
||||
|
||||
#include <openspace/util/openspacemodule.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class ToyVolumeModule : public OpenSpaceModule {
|
||||
public:
|
||||
ToyVolumeModule();
|
||||
void internalInitialize() override;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __TOYVOLUMEMODULE_H__
|
||||
@@ -88,4 +88,82 @@ vec4 z_normalization(vec4 v_in) {
|
||||
return v_out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the length of a vector.
|
||||
* Supporting huge vectors, where the square of any of the components is too large to represent as a float.
|
||||
*/
|
||||
float safeLength(vec4 v) {
|
||||
float m = max(max(max(abs(v.x), abs(v.y)), abs(v.z)), abs(v.w));
|
||||
if (m > 0.0) {
|
||||
return length(v / m) * m;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float safeLength(vec3 v) {
|
||||
float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
|
||||
if (m > 0.0) {
|
||||
return length(v / m) * m;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float safeLength(vec2 v) {
|
||||
float m = max(abs(v.x), abs(v.y));
|
||||
if (m > 0.0) {
|
||||
return length(v / m) * m;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a vector
|
||||
* Supporting huge vectors, where the square of any of the components is too large to represent as a float.
|
||||
*/
|
||||
vec3 safeNormalize(vec3 v) {
|
||||
float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
|
||||
return normalize(v / m);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a psc vector to a float
|
||||
*/
|
||||
vec3 pscToLinear(vec4 position) {
|
||||
return pow(k, position.w) * position.xyz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a psc scalar to a float
|
||||
*/
|
||||
float pscToLinear(vec2 position) {
|
||||
return pow(k, position.y) * position.x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive floating point distance [0, 10^27]
|
||||
* (size of observable universe)
|
||||
* to a float in the range [-1, 1], suitable for depth buffer storage.
|
||||
* Note: This needs to be a monotonic function, so that the value can
|
||||
* still be used for depth comparison.
|
||||
*/
|
||||
float normalizeFloat(float input) {
|
||||
if (input > 1.0) {
|
||||
return input / pow(10, 27);
|
||||
} else {
|
||||
return input - 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
float denormalizeFloat(float input) {
|
||||
if (input < 0.0) {
|
||||
return input + 1.0;
|
||||
} else {
|
||||
return input * pow(10, 27);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -47,11 +47,15 @@ vec4 psc_normlization(vec4 invec) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
float pscDepth(vec4 position) {
|
||||
// For now: simply convert power scaled coordinates to a linear scale.
|
||||
// TODO: get rid of power scaled coordinates and use scale graph instead.
|
||||
return (position.w + log(abs(position.z) + 1/pow(k, position.w))/log(k)) / 27.0;
|
||||
// return (position.w + log(abs(position.z) + 1/pow(k, position.w))/log(k)) / 27.0;
|
||||
return safeLength(pscToLinear(position));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,7 @@ struct ABufferFragment {
|
||||
// -------DEPTH-------
|
||||
// depth 32 bits
|
||||
// -------DATA--------
|
||||
// type 8 bits 0: geometry, >0: volume, <0: reserved
|
||||
// type 8 bits (signed char) 0: geometry, >0: volume entry, <0: volume exit
|
||||
// msaa 8 bits
|
||||
// reserved 16 bits
|
||||
// ----COMPOSITION----
|
||||
@@ -104,13 +104,22 @@ float _depth_(ABufferFragment frag) {
|
||||
* Type
|
||||
*/
|
||||
void _type_(inout ABufferFragment frag, int type) {
|
||||
uint val = uint(type);
|
||||
uint val;
|
||||
if (type < 0) {
|
||||
val = uint(-type) + 128;
|
||||
} else {
|
||||
val = type;
|
||||
}
|
||||
bitinsert(frag.data, val, mask_type, shift_type);
|
||||
}
|
||||
|
||||
int _type_(ABufferFragment frag) {
|
||||
uint val = bitextract(frag.data, mask_type, shift_type);
|
||||
return int(val);
|
||||
if (val > 127) {
|
||||
return 128 - int(val);
|
||||
} else {
|
||||
return int(val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,16 +25,15 @@
|
||||
#ifndef _ABUFFERRESOURCES_GLSL_
|
||||
#define _ABUFFERRESOURCES_GLSL_
|
||||
|
||||
#include "abufferfragment.glsl"
|
||||
#define MAX_LAYERS #{rendererData.maxLayers}
|
||||
|
||||
#include "abufferfragment.glsl"
|
||||
ABufferFragment fragments[MAX_LAYERS];
|
||||
|
||||
layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture;
|
||||
layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture;
|
||||
layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer;
|
||||
|
||||
ABufferFragment fragments[MAX_LAYERS];
|
||||
uint indices[MAX_LAYERS];
|
||||
const uint NULL_POINTER = 0;
|
||||
|
||||
void storeFragment(uint index, ABufferFragment aBufferFrag) {
|
||||
@@ -50,17 +49,15 @@ ABufferFragment loadFragment(uint index) {
|
||||
|
||||
/**
|
||||
* Load fragments into the #fragments array.
|
||||
* Also set #indices to the used indices.
|
||||
*/
|
||||
uint loadFragments() {
|
||||
uint currentIndex = imageLoad(anchorPointerTexture, ivec2(gl_FragCoord.xy)).x;
|
||||
int nFrags = 0;
|
||||
while (currentIndex != NULL_POINTER && nFrags < MAX_LAYERS) {
|
||||
ABufferFragment frag = loadFragment(currentIndex);
|
||||
indices[nFrags] = currentIndex;
|
||||
fragments[nFrags] = frag;
|
||||
nFrags++;
|
||||
currentIndex = _next_(frag);
|
||||
nFrags++;
|
||||
}
|
||||
return nFrags;
|
||||
}
|
||||
|
||||
60
shaders/abuffer/boundsabuffer.frag
Normal file
60
shaders/abuffer/boundsabuffer.frag
Normal file
@@ -0,0 +1,60 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 - 2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "fragment.glsl"
|
||||
#include <#{fragmentPath}>
|
||||
#include "abufferfragment.glsl"
|
||||
#include "abufferresources.glsl"
|
||||
|
||||
uniform bool _exit_;
|
||||
out vec4 _out_color_;
|
||||
|
||||
void main() {
|
||||
Fragment frag = getFragment();
|
||||
|
||||
int sampleMask = gl_SampleMaskIn[0];
|
||||
|
||||
uint newHead = atomicCounterIncrement(atomicCounterBuffer);
|
||||
uint prevHead = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), newHead);
|
||||
|
||||
ABufferFragment aBufferFrag;
|
||||
_color_(aBufferFrag, frag.color);
|
||||
_depth_(aBufferFrag, frag.depth);
|
||||
|
||||
int fragmentType = #{fragmentType};
|
||||
|
||||
if (_exit_) {
|
||||
fragmentType *= -1;
|
||||
}
|
||||
|
||||
_type_(aBufferFrag, fragmentType);
|
||||
_msaa_(aBufferFrag, gl_SampleMaskIn[0]);
|
||||
|
||||
_next_(aBufferFrag, prevHead);
|
||||
|
||||
storeFragment(newHead, aBufferFrag);
|
||||
discard;
|
||||
}
|
||||
35
shaders/abuffer/raycasterdata.glsl
Normal file
35
shaders/abuffer/raycasterdata.glsl
Normal file
@@ -0,0 +1,35 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 - 2016 *
|
||||
* *
|
||||
* 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 _RAYCASTERDATA_GLSL_
|
||||
#define _RAYCASTERDATA_GLSL_
|
||||
|
||||
struct RaycasterData {
|
||||
vec3 position;
|
||||
vec3 direction;
|
||||
float scale;
|
||||
float previousJitterDistance;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -35,6 +35,9 @@ void main() {
|
||||
int sampleMask = gl_SampleMaskIn[0];
|
||||
|
||||
uint newHead = atomicCounterIncrement(atomicCounterBuffer);
|
||||
if (newHead >= #{rendererData.maxTotalFragments}) {
|
||||
discard; // ABuffer is full!
|
||||
}
|
||||
uint prevHead = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), newHead);
|
||||
|
||||
ABufferFragment aBufferFrag;
|
||||
|
||||
@@ -27,32 +27,52 @@
|
||||
#include "abufferfragment.glsl"
|
||||
#include "abufferresources.glsl"
|
||||
#include "fragment.glsl"
|
||||
#include "PowerScaling/powerScalingMath.hglsl"
|
||||
#include "blending.glsl"
|
||||
#include "rand.glsl"
|
||||
|
||||
layout (location = 0) out vec4 finalColor;
|
||||
|
||||
uniform float blackoutFactor;
|
||||
uniform int nAaSamples;
|
||||
|
||||
void sortFragments(uint nFrags) {
|
||||
ABufferFragment tmp;
|
||||
uint i, j;
|
||||
|
||||
// Insertion sort
|
||||
for(i = 1; i < nFrags; ++i) {
|
||||
tmp = fragments[i];
|
||||
for(j = i; j > 0 && _depth_(tmp) < _depth_(fragments[j-1]); --j) {
|
||||
fragments[j] = fragments[j-1];
|
||||
}
|
||||
fragments[j] = tmp;
|
||||
}
|
||||
}
|
||||
#define RAYCASTING_ENABLED #{raycastingEnabled}
|
||||
#define N_RAYCASTERS #{nRaycasters}
|
||||
#define ALPHA_LIMIT 0.99
|
||||
#define RAYCAST_MAX_STEPS 1000
|
||||
#define INT_MAX 2147483647
|
||||
|
||||
vec4 blend(vec4 front, vec4 back) {
|
||||
vec4 result;
|
||||
result.a = front.a + (1.0 - front.a) * back.a;
|
||||
result.rgb = ((front.rgb * front.a) + (back.rgb * back.a * (1.0 - front.a))) / result.a;
|
||||
result = clamp(result, 0.0, 1.0);
|
||||
return result;
|
||||
/////////////////////////
|
||||
#if RAYCASTING_ENABLED
|
||||
|
||||
#include "raycasterdata.glsl"
|
||||
|
||||
RaycasterData raycasterData[N_RAYCASTERS];
|
||||
// Include all ray caster helpers
|
||||
#for id, helperPath in helperPaths
|
||||
#include <#{helperPath}>
|
||||
#endfor
|
||||
|
||||
// Include all ray casters
|
||||
#for id, raycaster in raycasters
|
||||
#include <#{raycaster.raycastPath}>
|
||||
#endfor
|
||||
|
||||
#endif
|
||||
/////////////////////////
|
||||
|
||||
void sortFragments(uint nFrags) {
|
||||
ABufferFragment tmp;
|
||||
uint i, j;
|
||||
|
||||
// Insertion sort
|
||||
for(i = 1; i < nFrags; ++i) {
|
||||
tmp = fragments[i];
|
||||
for(j = i; j > 0 && _depth_(tmp) < _depth_(fragments[j-1]); --j) {
|
||||
fragments[j] = fragments[j-1];
|
||||
}
|
||||
fragments[j] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
uint countSamples(uint mask) {
|
||||
@@ -66,39 +86,172 @@ uint countSamples(uint mask) {
|
||||
+ ((mask >> 7) & 1);
|
||||
}
|
||||
|
||||
uint reduceFragments(uint nFrags) {
|
||||
uint outputIndex = 0;
|
||||
for (uint inputIndex = 0; inputIndex < nFrags; inputIndex++, outputIndex++) {
|
||||
|
||||
ABufferFragment frag = fragments[inputIndex];
|
||||
uint accumulatedMask = _msaa_(fragments[inputIndex]);
|
||||
uint newMask = _msaa_(fragments[inputIndex]);
|
||||
int type = _type_(fragments[inputIndex]);
|
||||
|
||||
// Accumulate sample mask
|
||||
for (uint j = inputIndex + 1;
|
||||
j < nFrags && ((newMask = _msaa_(fragments[j])) & accumulatedMask) == 0 && _type_(fragments[j]) == type;
|
||||
j++) {
|
||||
accumulatedMask |= newMask;
|
||||
inputIndex = j;
|
||||
}
|
||||
uint nSamples = countSamples(accumulatedMask);
|
||||
vec4 color = _color_(fragments[inputIndex]); // TODO: Possibly weigh all samples together?
|
||||
|
||||
// Adjust the alpha by the ratio of accumulated samples
|
||||
float alpha = float(nSamples) / float(nAaSamples);
|
||||
color.a *= alpha;
|
||||
|
||||
ABufferFragment outputFragment = fragments[inputIndex];
|
||||
_color_(outputFragment, color);
|
||||
|
||||
fragments[outputIndex] = outputFragment;
|
||||
}
|
||||
|
||||
// return number of outputted fragments
|
||||
return outputIndex;
|
||||
}
|
||||
|
||||
#if RAYCASTING_ENABLED
|
||||
|
||||
/**
|
||||
* Iterate through list of sorted fragments,
|
||||
* and retrieve raycasting position, direction, scale
|
||||
*/
|
||||
void retrieveRaycasterData(uint nFrags) {
|
||||
float entryDepths[N_RAYCASTERS];
|
||||
for (int i = 0; i < N_RAYCASTERS; i++) {
|
||||
entryDepths[i] = -1;
|
||||
}
|
||||
for (int i = 0; i < nFrags; i++) {
|
||||
int type = _type_(fragments[i]); // - 1;
|
||||
vec4 color = _color_(fragments[i]);
|
||||
float depth = _depth_(fragments[i]);
|
||||
if (type > 0) { // enter raycaster
|
||||
int raycasterId = type - 1;
|
||||
if (entryDepths[raycasterId] < 0) { // first entry
|
||||
raycasterData[raycasterId].position = color.rgb;
|
||||
raycasterData[raycasterId].previousJitterDistance = 0;
|
||||
entryDepths[raycasterId] = depth;
|
||||
raycasterData[raycasterId].scale = -1;
|
||||
}
|
||||
} else if (type < 0) { // exit raycaster
|
||||
int raycasterId = -type - 1;
|
||||
vec3 localDirection = color.xyz - raycasterData[raycasterId].position;
|
||||
raycasterData[raycasterId].direction = safeNormalize(localDirection);
|
||||
raycasterData[raycasterId].scale = safeLength(localDirection) / (depth - entryDepths[raycasterId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform raycasting
|
||||
*/
|
||||
void raycast(float raycastDepth, uint raycasterMask, inout vec4 finalColor) {
|
||||
float nextStepSize = raycastDepth;
|
||||
float currentStepSize = 0.0;
|
||||
float jitterFactor = 0.5 + 0.5 * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0
|
||||
|
||||
#for index, raycaster in raycasters
|
||||
if ((raycasterMask & #{raycaster.bitmask}) != 0) {
|
||||
RaycasterData data = raycasterData[#{index}];
|
||||
float maxStepSizeLocal = stepSize#{raycaster.id}(data.position, data.direction);
|
||||
float maxStepSize = maxStepSizeLocal / data.scale;
|
||||
nextStepSize = min(nextStepSize, maxStepSize);
|
||||
}
|
||||
#endfor
|
||||
|
||||
float currentDepth = 0.0;
|
||||
|
||||
for (int steps = 0; finalColor.a < ALPHA_LIMIT && steps < RAYCAST_MAX_STEPS; ++steps) {
|
||||
bool exceededDepth = currentDepth + nextStepSize * jitterFactor > raycastDepth;
|
||||
bool shortStepSize = nextStepSize < raycastDepth / 10000000000.0;
|
||||
|
||||
if (exceededDepth || shortStepSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentStepSize = nextStepSize;
|
||||
currentDepth += currentStepSize;
|
||||
nextStepSize = raycastDepth - currentDepth;
|
||||
|
||||
#for index, raycaster in raycasters
|
||||
if ((raycasterMask & #{raycaster.bitmask}) != 0) {
|
||||
RaycasterData data = raycasterData[#{raycaster.id}];
|
||||
float stepSizeLocal = currentStepSize * data.scale;
|
||||
float jitteredStepSizeLocal = stepSizeLocal * jitterFactor;
|
||||
|
||||
vec3 jitteredPosition = data.position + data.direction*jitteredStepSizeLocal;
|
||||
raycasterData[#{raycaster.id}].position += data.direction * stepSizeLocal;
|
||||
|
||||
float maxStepSizeLocal;
|
||||
|
||||
vec4 raycasterContribution = sample#{raycaster.id}(jitteredPosition, data.direction, finalColor, maxStepSizeLocal);
|
||||
float sampleDistance = jitteredStepSizeLocal + data.previousJitterDistance;
|
||||
|
||||
blendStep(finalColor, raycasterContribution, sampleDistance);
|
||||
|
||||
raycasterData[#{raycaster.id}].previousJitterDistance = stepSizeLocal - jitteredStepSizeLocal;
|
||||
float maxStepSize = maxStepSizeLocal/data.scale;
|
||||
nextStepSize = min(nextStepSize, maxStepSize);
|
||||
}
|
||||
#endfor
|
||||
}
|
||||
}
|
||||
#endif // RAYCASTING_ENABLED
|
||||
|
||||
void main() {
|
||||
finalColor = vec4(0.0);
|
||||
uint nFrags = loadFragments();
|
||||
|
||||
sortFragments(nFrags);
|
||||
|
||||
int realFrags = 0;
|
||||
uint nOriginalFrags = loadFragments();
|
||||
uint raycasterMask = 0;
|
||||
|
||||
sortFragments(nOriginalFrags);
|
||||
|
||||
uint nFrags = reduceFragments(nOriginalFrags);
|
||||
#if RAYCASTING_ENABLED
|
||||
retrieveRaycasterData(nFrags);
|
||||
#endif
|
||||
|
||||
for (uint i = 0; i < nFrags; i++) {
|
||||
ABufferFragment frag = fragments[i];
|
||||
|
||||
uint accumulatedMask = _msaa_(fragments[i]);
|
||||
uint newMask = _msaa_(fragments[i]);
|
||||
int type = _type_(frag);
|
||||
|
||||
vec4 color = vec4(0.0);
|
||||
float totalAlpha = 0.0;
|
||||
|
||||
for (uint j = i + 1;
|
||||
j < nFrags
|
||||
&& ((newMask = _msaa_(fragments[j])) & accumulatedMask) == 0;
|
||||
j++) {
|
||||
|
||||
accumulatedMask |= newMask;
|
||||
i = j;
|
||||
if (type == 0) { // geometry fragment
|
||||
vec4 color = _color_(frag);
|
||||
blend(finalColor, color);
|
||||
}
|
||||
|
||||
uint nSamples = countSamples(accumulatedMask);
|
||||
color = _color_(fragments[i]); // TODO: Possibly weigh all samples together?
|
||||
color.a *= float(nSamples) / float(nAaSamples);
|
||||
|
||||
finalColor = blend(finalColor, color);
|
||||
#if RAYCASTING_ENABLED
|
||||
else if (type > 0) { // enter volume
|
||||
int raycasterId = type - 1;
|
||||
// only enter volume if a valid scale was detected
|
||||
if (raycasterData[raycasterId].scale > 0) {
|
||||
raycasterMask |= (1 << (raycasterId));
|
||||
}
|
||||
} else { // exit volume
|
||||
int raycasterId = -type - 1;
|
||||
raycasterMask &= INT_MAX - (1 << (raycasterId));
|
||||
}
|
||||
// Ray cast to next fragment
|
||||
if (i + 1 < nFrags && raycasterMask != 0) {
|
||||
float startDepth = _depth_(fragments[i]);
|
||||
float endDepth = _depth_(fragments[i + 1]);
|
||||
raycast(endDepth - startDepth, raycasterMask, finalColor);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
finalColor.a *= blackoutFactor;
|
||||
// finalColor is expressed with premultiplied alpha
|
||||
finalColor.rgb *= blackoutFactor;
|
||||
|
||||
// Render everything on a black background
|
||||
finalColor.a = 1.0;
|
||||
}
|
||||
|
||||
50
shaders/blending.glsl
Normal file
50
shaders/blending.glsl
Normal file
@@ -0,0 +1,50 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2016 *
|
||||
* *
|
||||
* 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 _BLENDING_GLSL_
|
||||
#define _BLENDING_GLSL_
|
||||
|
||||
/**
|
||||
* Blend in src behind dst
|
||||
* dst is premultiplied
|
||||
* src is expressed in straight RGBA
|
||||
*/
|
||||
void blend(inout vec4 dst, vec4 src) {
|
||||
dst.rgb = dst.rgb + (1.0 - dst.a) * src.a * src.rgb;
|
||||
dst.a = dst.a + (1.0 - dst.a) * src.a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blend in src behind dst
|
||||
* dst is premultiplied
|
||||
* src is expressed in straight RGBA
|
||||
* stepSize = 0: alpha becomes 0
|
||||
* stepSize = 1: alpha becomes src.a
|
||||
*/
|
||||
void blendStep(inout vec4 dst, vec4 src, float stepSize) {
|
||||
src.a = 1.0 - pow(1.0 - src.a, stepSize);
|
||||
blend(dst, src);
|
||||
}
|
||||
|
||||
#endif
|
||||
37
shaders/framebuffer/exitframebuffer.frag
Normal file
37
shaders/framebuffer/exitframebuffer.frag
Normal file
@@ -0,0 +1,37 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
|
||||
#include "PowerScaling/powerScalingMath.hglsl"
|
||||
#include <#{fragmentPath}>
|
||||
|
||||
out vec4 _out_color_;
|
||||
|
||||
void main() {
|
||||
Fragment f = getFragment();
|
||||
_out_color_ = f.color;
|
||||
gl_FragDepth = normalizeFloat(f.depth);
|
||||
}
|
||||
151
shaders/framebuffer/raycastframebuffer.frag
Normal file
151
shaders/framebuffer/raycastframebuffer.frag
Normal file
@@ -0,0 +1,151 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform sampler2D exitColorTexture;
|
||||
uniform sampler2D exitDepthTexture;
|
||||
uniform sampler2DMS mainDepthTexture;
|
||||
|
||||
#include "blending.glsl"
|
||||
#include "rand.glsl"
|
||||
#include "PowerScaling/powerScalingMath.hglsl"
|
||||
#include <#{fragmentPath}>
|
||||
|
||||
#for id, helperPath in helperPaths
|
||||
#include <#{helperPath}>
|
||||
#endfor
|
||||
|
||||
#include <#{raycastPath}>
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
|
||||
#define ALPHA_LIMIT 0.99
|
||||
#define RAYCAST_MAX_STEPS 1000
|
||||
#define MAX_AA_SAMPLES 8
|
||||
|
||||
uniform int nAaSamples;
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 texCoord = vec2(gl_FragCoord.x / #{rendererData.windowWidth},
|
||||
gl_FragCoord.y / #{rendererData.windowHeight});
|
||||
|
||||
|
||||
vec4 exitColorTexture = texture(exitColorTexture, texCoord);
|
||||
if (exitColorTexture.a < 1.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// fetch exit point from texture
|
||||
vec3 exitPos = exitColorTexture.rgb;
|
||||
float exitDepth = denormalizeFloat(texture(exitDepthTexture, texCoord).x);
|
||||
|
||||
|
||||
|
||||
float jitterFactor = 0.5 + 0.5 * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0
|
||||
|
||||
// fetch entry point from rendered fragment
|
||||
Fragment f = getFragment();
|
||||
vec3 entryPos = f.color.xyz;
|
||||
float entryDepth = f.depth;
|
||||
|
||||
vec3 position = entryPos;
|
||||
vec3 diff = exitPos - entryPos;
|
||||
|
||||
vec3 direction = normalize(diff);
|
||||
float raycastDepth = length(diff);
|
||||
|
||||
float raycastDepths[MAX_AA_SAMPLES];
|
||||
|
||||
int i, j;
|
||||
float tmp;
|
||||
|
||||
for (i = 0; i < nAaSamples; i++) {
|
||||
float geoDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), i).x);
|
||||
float geoRatio = clamp((geoDepth - entryDepth) / (exitDepth - entryDepth), 0.0, 1.0);
|
||||
raycastDepths[i] = geoRatio * raycastDepth;
|
||||
}
|
||||
|
||||
for(i = 1; i < nAaSamples; ++i) {
|
||||
tmp = raycastDepths[i];
|
||||
for(j = i; j > 0 && tmp < raycastDepths[j - 1]; --j) {
|
||||
raycastDepths[j] = raycastDepths[j-1];
|
||||
}
|
||||
raycastDepths[j] = tmp;
|
||||
}
|
||||
|
||||
|
||||
finalColor = vec4(0.0);
|
||||
float currentDepth = 0.0;
|
||||
// todo: shorten depth if geometry is intersecting!
|
||||
float nextStepSize = stepSize#{id}(position, direction);
|
||||
float currentStepSize;
|
||||
float previousJitterDistance = 0.0;
|
||||
|
||||
int steps = 0;
|
||||
|
||||
float aaOpacity = 1.0;
|
||||
int sampleIndex = 0;
|
||||
float opacityDecay = 1.0 / nAaSamples;
|
||||
|
||||
for (steps = 0; finalColor.a < ALPHA_LIMIT && steps < RAYCAST_MAX_STEPS; ++steps) {
|
||||
|
||||
|
||||
while (sampleIndex < nAaSamples && currentDepth + nextStepSize * jitterFactor > raycastDepths[sampleIndex]) {
|
||||
sampleIndex++;
|
||||
aaOpacity -= opacityDecay;
|
||||
}
|
||||
bool shortStepSize = nextStepSize < raycastDepth / 10000000000.0;
|
||||
|
||||
if (sampleIndex >= nAaSamples || shortStepSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
currentStepSize = nextStepSize;
|
||||
currentDepth += currentStepSize;
|
||||
|
||||
float jitteredStepSize = currentStepSize * jitterFactor;
|
||||
vec3 jitteredPosition = position + direction*jitteredStepSize;
|
||||
position += direction * currentStepSize;
|
||||
|
||||
vec4 raycasterContribution = sample#{id}(jitteredPosition, direction, finalColor, nextStepSize);
|
||||
|
||||
float sampleDistance = aaOpacity * (jitteredStepSize + previousJitterDistance);
|
||||
|
||||
blendStep(finalColor, raycasterContribution, sampleDistance);
|
||||
|
||||
previousJitterDistance = currentStepSize - jitteredStepSize;
|
||||
|
||||
float maxStepSize = raycastDepths[nAaSamples - 1] - currentDepth;
|
||||
|
||||
nextStepSize = min(nextStepSize, maxStepSize);
|
||||
|
||||
}
|
||||
|
||||
finalColor.rgb /= finalColor.a;
|
||||
gl_FragDepth = normalizeFloat(entryDepth);
|
||||
}
|
||||
33
shaders/framebuffer/renderframebuffer.frag
Normal file
33
shaders/framebuffer/renderframebuffer.frag
Normal file
@@ -0,0 +1,33 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <#{fragmentPath}>
|
||||
|
||||
out vec4 _out_color_;
|
||||
|
||||
void main() {
|
||||
Fragment f = getFragment();
|
||||
_out_color_ = f.color;
|
||||
gl_FragDepth = normalizeFloat(f.depth);
|
||||
}
|
||||
45
shaders/framebuffer/resolveframebuffer.frag
Normal file
45
shaders/framebuffer/resolveframebuffer.frag
Normal file
@@ -0,0 +1,45 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 - 2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "PowerScaling/powerScalingMath.hglsl"
|
||||
|
||||
layout (location = 0) out vec4 finalColor;
|
||||
uniform float blackoutFactor;
|
||||
uniform int nAaSamples;
|
||||
|
||||
uniform sampler2DMS mainColorTexture;
|
||||
|
||||
void main() {
|
||||
vec4 color = vec4(0.0);
|
||||
for (int i = 0; i < nAaSamples; i++) {
|
||||
color += texelFetch(mainColorTexture, ivec2(gl_FragCoord), i);
|
||||
}
|
||||
|
||||
color /= nAaSamples;
|
||||
color.rgb *= blackoutFactor;
|
||||
|
||||
finalColor = vec4(color.rgb, 1.0);
|
||||
}
|
||||
33
shaders/framebuffer/resolveframebuffer.vert
Normal file
33
shaders/framebuffer/resolveframebuffer.vert
Normal file
@@ -0,0 +1,33 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014 - 2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
in vec4 position;
|
||||
out vec2 texCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
texCoord = 0.5 + position.xy / 2.0;
|
||||
}
|
||||
35
shaders/rand.glsl
Normal file
35
shaders/rand.glsl
Normal file
@@ -0,0 +1,35 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2016 *
|
||||
* *
|
||||
* 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 _RAND_GLSL_
|
||||
#define _RAND_GLSL_
|
||||
|
||||
/**
|
||||
* Return a random number between 0 and 1, based on a vec2
|
||||
*/
|
||||
float rand(vec2 co){
|
||||
return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,9 +0,0 @@
|
||||
#include <#{fragmentPath}>
|
||||
|
||||
out vec4 _out_color_;
|
||||
|
||||
void main() {
|
||||
Fragment f = getFragment();
|
||||
_out_color_ = f.color;
|
||||
gl_FragDepth = f.depth;
|
||||
}
|
||||
@@ -60,6 +60,7 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/query/query.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/rendering/abufferrenderer.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/rendering/framebufferrenderer.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/rendering/raycastermanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/rendering/renderable.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/rendering/renderengine.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/rendering/renderengine_lua.inl
|
||||
@@ -129,11 +130,14 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/query/query.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/abufferrenderer.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/framebufferrenderer.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/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/volume.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/screenspacerenderable.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/rendering/volumeraycaster.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/ephemeris.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/scene.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/scenegraph.h
|
||||
|
||||
@@ -39,8 +39,8 @@ namespace properties {
|
||||
[](lua_State* state, bool& success) -> __TYPE__ { \
|
||||
__TYPE__ result; \
|
||||
int number = 1; \
|
||||
for (glm::length_t i = 0; i < __TYPE__::rows; ++i) { \
|
||||
for (glm::length_t j = 0; j < __TYPE__::cols; ++j) { \
|
||||
for (glm::length_t i = 0; i < ghoul::glm_rows<__TYPE__>::value; ++i) { \
|
||||
for (glm::length_t j = 0; j < ghoul::glm_cols<__TYPE__>::value; ++j) { \
|
||||
lua_getfield(state, -1, std::to_string(number).c_str()); \
|
||||
if (lua_isnumber(state, -1) != 1) { \
|
||||
success = false; \
|
||||
@@ -61,8 +61,8 @@ namespace properties {
|
||||
[](lua_State* state, __TYPE__ value) -> bool { \
|
||||
lua_newtable(state); \
|
||||
int number = 1; \
|
||||
for (glm::length_t i = 0; i < __TYPE__::rows; ++i) { \
|
||||
for (glm::length_t j = 0; j < __TYPE__::cols; ++j) { \
|
||||
for (glm::length_t i = 0; i < ghoul::glm_rows<__TYPE__>::value; ++i) { \
|
||||
for (glm::length_t j = 0; j < ghoul::glm_cols<__TYPE__>::value; ++j) { \
|
||||
lua_pushnumber(state, static_cast<lua_Number>(value[i][j])); \
|
||||
lua_setfield(state, -2, std::to_string(number).c_str()); \
|
||||
++number; \
|
||||
@@ -75,13 +75,15 @@ namespace properties {
|
||||
[](std::string value, bool& success) -> __TYPE__ { \
|
||||
__TYPE__ result; \
|
||||
std::vector<std::string> tokens = ghoul::tokenizeString(value, ','); \
|
||||
if (tokens.size() != (__TYPE__::rows * __TYPE__::cols)) { \
|
||||
if (tokens.size() != \
|
||||
(ghoul::glm_rows<__TYPE__>::value * ghoul::glm_cols<__TYPE__>::value)) \
|
||||
{ \
|
||||
success = false; \
|
||||
return result; \
|
||||
} \
|
||||
int number = 0; \
|
||||
for (glm::length_t i = 0; i < __TYPE__::rows; ++i) { \
|
||||
for (glm::length_t j = 0; j < __TYPE__::cols; ++j) { \
|
||||
for (glm::length_t i = 0; i < ghoul::glm_rows<__TYPE__>::value; ++i) { \
|
||||
for (glm::length_t j = 0; j < ghoul::glm_cols<__TYPE__>::value; ++j) { \
|
||||
std::stringstream s(tokens[number]); \
|
||||
__TYPE__::value_type v; \
|
||||
s >> v; \
|
||||
@@ -102,8 +104,8 @@ namespace properties {
|
||||
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
|
||||
[](std::string& outValue, __TYPE__ inValue) -> bool { \
|
||||
outValue = ""; \
|
||||
for (glm::length_t i = 0; i < __TYPE__::rows; ++i) { \
|
||||
for (glm::length_t j = 0; j < __TYPE__::cols; ++j) { \
|
||||
for (glm::length_t i = 0; i < ghoul::glm_rows<__TYPE__>::value; ++i) { \
|
||||
for (glm::length_t j = 0; j < ghoul::glm_cols<__TYPE__>::value; ++j) { \
|
||||
outValue += std::to_string(inValue[i][j]) + ","; \
|
||||
} \
|
||||
outValue.pop_back(); \
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace properties {
|
||||
[](lua_State * state, bool& success) -> __TYPE__ { \
|
||||
__TYPE__ result; \
|
||||
lua_pushnil(state); \
|
||||
for (glm::length_t i = 0; i < __TYPE__::components; ++i) { \
|
||||
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
|
||||
int success = lua_next(state, -2); \
|
||||
if (success != 1) { \
|
||||
success = false; \
|
||||
@@ -61,7 +61,7 @@ namespace properties {
|
||||
[](lua_State * state, __TYPE__ value) -> bool { \
|
||||
lua_newtable(state); \
|
||||
int number = 1; \
|
||||
for (glm::length_t i = 0; i < __TYPE__::components; ++i) { \
|
||||
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
|
||||
lua_pushnumber(state, static_cast<lua_Number>(value[i])); \
|
||||
lua_setfield(state, -2, std::to_string(number).c_str()); \
|
||||
++number; \
|
||||
@@ -77,7 +77,7 @@ namespace properties {
|
||||
success = false; \
|
||||
return result; \
|
||||
} \
|
||||
for (glm::length_t i = 0; i < __TYPE__::components; ++i) { \
|
||||
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) { \
|
||||
std::stringstream s(tokens[i]); \
|
||||
__TYPE__::value_type v; \
|
||||
s >> v; \
|
||||
@@ -95,7 +95,7 @@ namespace properties {
|
||||
#define DEFAULT_TO_STRING_LAMBDA(__TYPE__) \
|
||||
[](std::string& outValue, __TYPE__ inValue) -> bool { \
|
||||
outValue = "{"; \
|
||||
for (glm::length_t i = 0; i < __TYPE__::components; ++i) \
|
||||
for (glm::length_t i = 0; i < ghoul::glm_components<__TYPE__>::value; ++i) \
|
||||
outValue += std::to_string(inValue[i]) + ","; \
|
||||
outValue.pop_back(); \
|
||||
outValue += "}"; \
|
||||
|
||||
@@ -23,31 +23,44 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/rendering/abufferrenderer.h>
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/wrapper/windowwrapper.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "ABufferRenderer";
|
||||
const std::string BoundsFragmentShaderPath = "${SHADERS}/abuffer/boundsabuffer.frag";
|
||||
const std::string RenderFragmentShaderPath = "${SHADERS}/abuffer/renderabuffer.frag";
|
||||
const int MaxRaycasters = 32;
|
||||
const int MaxLayers = 16;
|
||||
const int MaxAverageLayers = 8;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
|
||||
ABufferRenderer::ABufferRenderer()
|
||||
ABufferRenderer::ABufferRenderer()
|
||||
: _camera(nullptr)
|
||||
, _scene(nullptr)
|
||||
, _resolution(glm::ivec2(0))
|
||||
, _dirtyResolution(true)
|
||||
, _dirtyRaycastData(true)
|
||||
, _dirtyRendererData(true)
|
||||
, _dirtyResolveDictionary(true)
|
||||
, _resolveProgram(nullptr) { }
|
||||
|
||||
ABufferRenderer::~ABufferRenderer() {}
|
||||
@@ -85,23 +98,27 @@ void ABufferRenderer::initialize() {
|
||||
glGenBuffers(1, &_fragmentBuffer);
|
||||
glGenTextures(1, &_fragmentTexture);
|
||||
|
||||
if (_dirtyResolution) {
|
||||
updateResolution();
|
||||
}
|
||||
updateRendererData();
|
||||
ghoul::Dictionary dict = createResolveDictionary();
|
||||
|
||||
_resolveProgram = ghoul::opengl::ProgramObject::Build("ABuffer Resolve",
|
||||
"${SHADERS}/abuffer/resolveabuffer.vert",
|
||||
"${SHADERS}/abuffer/resolveabuffer.frag",
|
||||
dict);
|
||||
|
||||
_nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples();
|
||||
if (_nAaSamples > 8) {
|
||||
LERROR("ABuffer does not support more than 8 MSAA samples.");
|
||||
LERROR("ABuffer renderer does not support more than 8 MSAA samples.");
|
||||
_nAaSamples = 8;
|
||||
}
|
||||
|
||||
updateResolution();
|
||||
updateRendererData();
|
||||
updateRaycastData();
|
||||
updateResolveDictionary();
|
||||
|
||||
try {
|
||||
_resolveProgram = ghoul::opengl::ProgramObject::Build("ABuffer Resolve",
|
||||
"${SHADERS}/abuffer/resolveabuffer.vert",
|
||||
"${SHADERS}/abuffer/resolveabuffer.frag",
|
||||
_resolveDictionary);
|
||||
} catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
}
|
||||
|
||||
OsEng.renderEngine().raycasterManager().addListener(*this);
|
||||
}
|
||||
|
||||
void ABufferRenderer::deinitialize() {
|
||||
@@ -115,65 +132,134 @@ void ABufferRenderer::deinitialize() {
|
||||
|
||||
glDeleteBuffers(1, &_vertexPositionBuffer);
|
||||
glDeleteVertexArrays(1, &_screenQuad);
|
||||
|
||||
OsEng.renderEngine().raycasterManager().removeListener(*this);
|
||||
}
|
||||
|
||||
void ABufferRenderer::raycastersChanged(VolumeRaycaster& raycaster, bool attached) {
|
||||
(void) raycaster;
|
||||
(void) attached;
|
||||
_dirtyRaycastData = true;
|
||||
}
|
||||
|
||||
void ABufferRenderer::update() {
|
||||
bool dirtyRendererData = false;
|
||||
bool dirtyResolveDictionary = false;
|
||||
|
||||
// Make sure that the fragment buffer has the correct resoliution
|
||||
// according to the output render buffer size
|
||||
if (_dirtyResolution) {
|
||||
updateResolution();
|
||||
}
|
||||
|
||||
if (dirtyRendererData) {
|
||||
dirtyResolveDictionary = true;
|
||||
|
||||
// Make sure that the renderengine gets the correct render data
|
||||
// to feed into all render programs.
|
||||
// This will trigger a recompilation of all the shader programs
|
||||
// involved in rendering geometries.
|
||||
if (_dirtyRendererData) {
|
||||
updateRendererData();
|
||||
}
|
||||
|
||||
// TODO: Collect volumes from scene graph.
|
||||
// Diff against cache, update cache.
|
||||
// possibly mark resolve dictionary as dirty
|
||||
|
||||
if (dirtyResolveDictionary) {
|
||||
ghoul::Dictionary dict = createResolveDictionary();
|
||||
_resolveProgram->setDictionary(dict);
|
||||
// Make sure that all raycaster data is up to date.
|
||||
if (_dirtyRaycastData) {
|
||||
updateRaycastData();
|
||||
}
|
||||
|
||||
if (_resolveProgram->isDirty()) {
|
||||
_resolveProgram->rebuildFromFile();
|
||||
// Make sure that the resolve dictionary is up to date.
|
||||
// The resolve dictionary contains information for all
|
||||
// ray casters, including shader include paths.
|
||||
|
||||
if (_dirtyResolveDictionary) {
|
||||
updateResolveDictionary();
|
||||
_resolveProgram->setDictionary(_resolveDictionary);
|
||||
}
|
||||
|
||||
// If the resolve dictionary changed (or a file changed on disk)
|
||||
// then rebuild the resolve program.
|
||||
if (_resolveProgram->isDirty()) {
|
||||
try {
|
||||
_resolveProgram->rebuildFromFile();
|
||||
} catch (ghoul::RuntimeError& error) {
|
||||
LERROR(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &program : _boundsPrograms) {
|
||||
if (program.second->isDirty()) {
|
||||
try {
|
||||
program.second->rebuildFromFile();
|
||||
} catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurements) {
|
||||
if (_scene == nullptr) return;
|
||||
if (_camera == nullptr) return;
|
||||
|
||||
|
||||
// Reset
|
||||
clear();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
clear();
|
||||
|
||||
// Step 1: Render geometries to the fragment buffer
|
||||
|
||||
// Bind head-pointer image for read-write
|
||||
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer);
|
||||
// Bind head-pointer image for read-write
|
||||
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer);
|
||||
glBindImageTexture(0, _anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
|
||||
glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI);
|
||||
|
||||
_scene->render({ *_camera, psc(), doPerformanceMeasurements });
|
||||
|
||||
// Step 2: Render volumes to the fragment buffer
|
||||
//TODO: Implement this
|
||||
// Render the scene to the fragment buffer. Collect renderer tasks (active raycasters)
|
||||
RenderData data{ *_camera, psc(), doPerformanceMeasurements };
|
||||
RendererTasks tasks;
|
||||
_scene->render(data, tasks);
|
||||
|
||||
|
||||
// Step 2: Perform raycasting tasks requested by the scene
|
||||
for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) {
|
||||
VolumeRaycaster* raycaster = raycasterTask.raycaster;
|
||||
ghoul::opengl::ProgramObject* program = _boundsPrograms[raycaster].get();
|
||||
if (program) {
|
||||
program->activate();
|
||||
program->setUniform("_exit_", false);
|
||||
raycaster->renderEntryPoints(raycasterTask.renderData, *program);
|
||||
program->setUniform("_exit_", true);
|
||||
raycaster->renderExitPoints(raycasterTask.renderData, *program);
|
||||
program->deactivate();
|
||||
}
|
||||
else {
|
||||
LWARNING("Raycaster is not attached when trying to perform raycaster task");
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: Resolve the buffer
|
||||
_resolveProgram->activate();
|
||||
|
||||
// 3a: Perform the pre-raycast step for all raycaster tasks.
|
||||
for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) {
|
||||
VolumeRaycaster* raycaster = raycasterTask.raycaster;
|
||||
auto raycastData = _raycastData.find(raycaster);
|
||||
if (raycastData != _raycastData.end()) {
|
||||
raycaster->preRaycast(raycastData->second, *_resolveProgram.get());
|
||||
}
|
||||
}
|
||||
|
||||
// 3b: Set "global" uniforms, and start the resolve pass.
|
||||
_resolveProgram->setUniform("blackoutFactor", blackoutFactor);
|
||||
_resolveProgram->setUniform("nAaSamples", _nAaSamples);
|
||||
// todo: pre-ray-cast for each volume
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
// todo: post-ray-cast for each volume
|
||||
|
||||
// 3c: Perform the post-raycast step for all raycaster tasks.
|
||||
for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) {
|
||||
VolumeRaycaster* raycaster = raycasterTask.raycaster;
|
||||
auto raycastData = _raycastData.find(raycaster);
|
||||
if (raycastData != _raycastData.end()) {
|
||||
raycaster->postRaycast(raycastData->second, *_resolveProgram.get());
|
||||
}
|
||||
}
|
||||
|
||||
_resolveProgram->deactivate();
|
||||
}
|
||||
|
||||
@@ -223,7 +309,7 @@ void ABufferRenderer::updateResolution() {
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer);
|
||||
glBufferData(GL_TEXTURE_BUFFER, MaxLayers*totalPixels*sizeof(GLuint) * 4, NULL, GL_DYNAMIC_COPY);
|
||||
glBufferData(GL_TEXTURE_BUFFER, MaxAverageLayers*totalPixels*sizeof(GLuint) * 4, NULL, GL_DYNAMIC_COPY);
|
||||
|
||||
glBindTexture(GL_TEXTURE_BUFFER, _fragmentTexture);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, _fragmentBuffer);
|
||||
@@ -233,27 +319,125 @@ void ABufferRenderer::updateResolution() {
|
||||
|
||||
|
||||
_dirtyResolution = false;
|
||||
|
||||
}
|
||||
|
||||
ghoul::Dictionary ABufferRenderer::createResolveDictionary() {
|
||||
|
||||
|
||||
void ABufferRenderer::updateResolveDictionary() {
|
||||
ghoul::Dictionary dict;
|
||||
|
||||
ghoul::Dictionary raycastersDict;
|
||||
|
||||
for (const auto &raycastPair : _raycastData) {
|
||||
ghoul::Dictionary innerDict;
|
||||
int id = raycastPair.second.id;
|
||||
std::string namespaceName = raycastPair.second.namespaceName;
|
||||
std::string raycastPath = raycastPair.first->getRaycastPath();
|
||||
|
||||
innerDict.setValue("id", id);
|
||||
innerDict.setValue("namespace", namespaceName);
|
||||
innerDict.setValue("bitmask", 1 << id);
|
||||
innerDict.setValue("raycastPath", raycastPath);
|
||||
|
||||
raycastersDict.setValue(std::to_string(id), innerDict);
|
||||
}
|
||||
|
||||
dict.setValue("raycasters", raycastersDict);
|
||||
|
||||
ghoul::Dictionary helperPathsDict;
|
||||
for (int i = 0; i < _helperPaths.size(); i++) {
|
||||
helperPathsDict.setValue(std::to_string(i), _helperPaths[i]);
|
||||
}
|
||||
|
||||
dict.setValue("helperPaths", helperPathsDict);
|
||||
dict.setValue("rendererData", _rendererData);
|
||||
// TODO: Add volume data to dictionary
|
||||
// such as id, bitmask, path to raycaster frag shader, helpers, nVolumes...
|
||||
return dict;
|
||||
dict.setValue("raycastingEnabled", _raycastData.size() > 0);
|
||||
dict.setValue("nRaycasters", static_cast<unsigned long long>(_raycastData.size()));
|
||||
|
||||
_resolveDictionary = dict;
|
||||
_dirtyResolveDictionary = false;
|
||||
}
|
||||
|
||||
void ABufferRenderer::updateRaycastData() {
|
||||
|
||||
_raycastData.clear();
|
||||
_boundsPrograms.clear();
|
||||
_helperPaths.clear();
|
||||
|
||||
const std::vector<VolumeRaycaster*>& raycasters = OsEng.renderEngine().raycasterManager().raycasters();
|
||||
|
||||
std::map<std::string, int> namespaceIndices;
|
||||
int nextId = 0; // raycaster ids are positive integers starting at 0. (for raycasters, fragment type is id+1)
|
||||
int nextNamespaceIndex = 0;
|
||||
|
||||
for (auto &raycaster : raycasters) {
|
||||
if (nextId > MaxRaycasters) {
|
||||
int nIgnored = MaxRaycasters - raycasters.size();
|
||||
LWARNING("ABufferRenderer does not support more than 32 raycasters. Ignoring " << nIgnored << " raycasters");
|
||||
break;
|
||||
}
|
||||
|
||||
RaycastData data;
|
||||
data.id = nextId++;
|
||||
|
||||
std::string helperPath = raycaster->getHelperPath();
|
||||
// Each new helper path generates a new namespace,
|
||||
// to avoid glsl name collisions between raycaster implementaitons.
|
||||
// Assign a new namespace or find an already created index.
|
||||
|
||||
if (helperPath == "") {
|
||||
data.namespaceName = "NAMESPACE_" + std::to_string(nextNamespaceIndex++);
|
||||
} else {
|
||||
auto iter = namespaceIndices.find(helperPath);
|
||||
if (iter == namespaceIndices.end()) {
|
||||
int namespaceIndex = nextNamespaceIndex++;
|
||||
data.namespaceName = std::to_string(namespaceIndex);
|
||||
namespaceIndices[helperPath] = namespaceIndex;
|
||||
_helperPaths.push_back(helperPath);
|
||||
}
|
||||
else {
|
||||
data.namespaceName = "NAMESPACE_" + std::to_string(iter->second);
|
||||
}
|
||||
}
|
||||
|
||||
_raycastData[raycaster] = data;
|
||||
std::string vsPath = raycaster->getBoundsVsPath();
|
||||
std::string fsPath = raycaster->getBoundsFsPath();
|
||||
ghoul::Dictionary dict;
|
||||
|
||||
// set path to the current renderer's main fragment shader
|
||||
dict.setValue("rendererData", _rendererData);
|
||||
// parameterize the main fragment shader program with specific contents.
|
||||
// fsPath should point to a shader file defining a Fragment getFragment() function
|
||||
// instead of a void main() setting glFragColor, glFragDepth, etc.
|
||||
dict.setValue("fragmentPath", fsPath);
|
||||
dict.setValue("fragmentType", data.id + 1);
|
||||
try {
|
||||
_boundsPrograms[raycaster] = ghoul::opengl::ProgramObject::Build("Volume " + std::to_string(data.id) + " bounds", vsPath, BoundsFragmentShaderPath, dict);
|
||||
}
|
||||
catch (ghoul::RuntimeError& error) {
|
||||
LERROR(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
_dirtyRaycastData = false;
|
||||
_dirtyResolveDictionary = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ABufferRenderer::updateRendererData() {
|
||||
ghoul::Dictionary dict;
|
||||
dict.setValue("windowWidth", OsEng.windowWrapper().currentWindowResolution().x);
|
||||
dict.setValue("windowHeight", OsEng.windowWrapper().currentWindowResolution().y);
|
||||
dict.setValue("windowWidth", _resolution.x);
|
||||
dict.setValue("windowHeight", _resolution.y);
|
||||
dict.setValue("fragmentRendererPath", std::string(RenderFragmentShaderPath));
|
||||
dict.setValue("maxLayers", MaxLayers);
|
||||
dict.setValue("fragmentRendererPath", std::string("${SHADERS}/abuffer/renderabuffer.frag"));
|
||||
dict.setValue("maxTotalFragments", MaxLayers * _resolution.x * _resolution.y);
|
||||
|
||||
_rendererData = dict;
|
||||
|
||||
OsEng.renderEngine().setRendererData(dict);
|
||||
_dirtyRendererData = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,74 +30,378 @@
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <vector>
|
||||
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "FramebufferRenderer";
|
||||
const std::string FragmentRendererPath = "${SHADERS}/renderframebuffer.frag";
|
||||
const std::string ExitFragmentShaderPath = "${SHADERS}/framebuffer/exitframebuffer.frag";
|
||||
const std::string RaycastFragmentShaderPath = "${SHADERS}/framebuffer/raycastframebuffer.frag";
|
||||
const std::string RenderFragmentShaderPath = "${SHADERS}/framebuffer/renderframebuffer.frag";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
FramebufferRenderer::FramebufferRenderer()
|
||||
: _camera(nullptr)
|
||||
, _scene(nullptr)
|
||||
, _resolution(glm::vec2(0)) {
|
||||
}
|
||||
|
||||
FramebufferRenderer::FramebufferRenderer()
|
||||
: _camera(nullptr)
|
||||
, _scene(nullptr)
|
||||
, _resolution(glm::vec2(0)) {
|
||||
}
|
||||
FramebufferRenderer::~FramebufferRenderer() {}
|
||||
|
||||
void FramebufferRenderer::initialize() {
|
||||
LINFO("Initializing FramebufferRenderer");
|
||||
|
||||
FramebufferRenderer::~FramebufferRenderer() {
|
||||
|
||||
}
|
||||
const GLfloat size = 1.0f;
|
||||
const GLfloat vertex_data[] = {
|
||||
// x y s t
|
||||
-size, -size, 0.0f, 1.0f,
|
||||
size, size, 0.0f, 1.0f,
|
||||
-size, size, 0.0f, 1.0f,
|
||||
-size, -size, 0.0f, 1.0f,
|
||||
size, -size, 0.0f, 1.0f,
|
||||
size, size, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
glGenVertexArrays(1, &_screenQuad);
|
||||
glBindVertexArray(_screenQuad);
|
||||
|
||||
void FramebufferRenderer::initialize() {
|
||||
LINFO("Initializing FramebufferRenderer");
|
||||
updateRendererData();
|
||||
glGenBuffers(1, &_vertexPositionBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, reinterpret_cast<void*>(0));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
GLint defaultFbo;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo);
|
||||
|
||||
// Main framebuffer
|
||||
glGenTextures(1, &_mainColorTexture);
|
||||
glGenTextures(1, &_mainDepthTexture);
|
||||
glGenFramebuffers(1, &_mainFramebuffer);
|
||||
|
||||
// Exit framebuffer
|
||||
glGenTextures(1, &_exitColorTexture);
|
||||
glGenTextures(1, &_exitDepthTexture);
|
||||
glGenFramebuffers(1, &_exitFramebuffer);
|
||||
|
||||
updateResolution();
|
||||
updateRendererData();
|
||||
updateRaycastData();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture, 0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _exitFramebuffer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _exitColorTexture, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _exitDepthTexture, 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
LERROR("Main framebuffer is not complete");
|
||||
}
|
||||
|
||||
void FramebufferRenderer::deinitialize() {
|
||||
LINFO("Deinitializing FramebufferRenderer");
|
||||
}
|
||||
|
||||
|
||||
void FramebufferRenderer::update() {
|
||||
// no need to update anything.
|
||||
}
|
||||
|
||||
void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurements) {
|
||||
if (_scene == nullptr) return;
|
||||
if (_camera == nullptr) return;
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
_scene->render({ *_camera, psc(), doPerformanceMeasurements });;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
|
||||
|
||||
try {
|
||||
_resolveProgram = ghoul::opengl::ProgramObject::Build("Framebuffer Resolve",
|
||||
"${SHADERS}/framebuffer/resolveframebuffer.vert",
|
||||
"${SHADERS}/framebuffer/resolveframebuffer.frag");
|
||||
} catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
}
|
||||
|
||||
void FramebufferRenderer::setScene(Scene* scene) {
|
||||
_scene = scene;
|
||||
OsEng.renderEngine().raycasterManager().addListener(*this);
|
||||
|
||||
_nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples();
|
||||
if (_nAaSamples > 8) {
|
||||
LERROR("Framebuffer renderer does not support more than 8 MSAA samples.");
|
||||
_nAaSamples = 8;
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferRenderer::deinitialize() {
|
||||
LINFO("Deinitializing FramebufferRenderer");
|
||||
|
||||
glDeleteFramebuffers(1, &_mainFramebuffer);
|
||||
glDeleteFramebuffers(1, &_exitFramebuffer);
|
||||
|
||||
glDeleteTextures(1, &_mainColorTexture);
|
||||
glDeleteTextures(1, &_mainDepthTexture);
|
||||
glDeleteTextures(1, &_exitColorTexture);
|
||||
glDeleteTextures(1, &_exitDepthTexture);
|
||||
|
||||
glDeleteBuffers(1, &_vertexPositionBuffer);
|
||||
glDeleteVertexArrays(1, &_screenQuad);
|
||||
|
||||
OsEng.renderEngine().raycasterManager().removeListener(*this);
|
||||
}
|
||||
|
||||
void FramebufferRenderer::raycastersChanged(VolumeRaycaster& raycaster, bool attached) {
|
||||
(void) raycaster;
|
||||
(void) attached;
|
||||
_dirtyRaycastData = true;
|
||||
}
|
||||
|
||||
void FramebufferRenderer::update() {
|
||||
if (_dirtyResolution) {
|
||||
updateResolution();
|
||||
}
|
||||
|
||||
void FramebufferRenderer::setCamera(Camera* camera) {
|
||||
_camera = camera;
|
||||
if (_dirtyRaycastData) {
|
||||
updateRaycastData();
|
||||
}
|
||||
|
||||
void FramebufferRenderer::setResolution(glm::ivec2 res) {
|
||||
_resolution = res;
|
||||
// If the resolve dictionary changed (or a file changed on disk)
|
||||
// then rebuild the resolve program.
|
||||
if (_resolveProgram->isDirty()) {
|
||||
try {
|
||||
_resolveProgram->rebuildFromFile();
|
||||
} catch (ghoul::RuntimeError& error) {
|
||||
LERROR(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferRenderer::updateRendererData() {
|
||||
for (auto &program : _exitPrograms) {
|
||||
if (program.second->isDirty()) {
|
||||
try {
|
||||
program.second->rebuildFromFile();
|
||||
} catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &program : _raycastPrograms) {
|
||||
if (program.second->isDirty()) {
|
||||
try {
|
||||
program.second->rebuildFromFile();
|
||||
} catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferRenderer::updateResolution() {
|
||||
int nSamples = OsEng.windowWrapper().currentNumberOfAaSamples();
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture);
|
||||
|
||||
glTexImage2DMultisample(
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
nSamples,
|
||||
GL_RGBA,
|
||||
GLsizei(_resolution.x),
|
||||
GLsizei(_resolution.y),
|
||||
true);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture);
|
||||
glTexImage2DMultisample(
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
nSamples,
|
||||
GL_DEPTH_COMPONENT32F,
|
||||
GLsizei(_resolution.x),
|
||||
GLsizei(_resolution.y),
|
||||
true);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _exitColorTexture);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GLsizei(_resolution.x),
|
||||
GLsizei(_resolution.y),
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_BYTE,
|
||||
nullptr);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _exitDepthTexture);
|
||||
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_DEPTH_COMPONENT32F,
|
||||
GLsizei(_resolution.x),
|
||||
GLsizei(_resolution.y),
|
||||
0,
|
||||
GL_DEPTH_COMPONENT,
|
||||
GL_FLOAT,
|
||||
nullptr);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
void FramebufferRenderer::updateRaycastData() {
|
||||
_raycastData.clear();
|
||||
_exitPrograms.clear();
|
||||
_raycastPrograms.clear();
|
||||
|
||||
const std::vector<VolumeRaycaster*>& raycasters = OsEng.renderEngine().raycasterManager().raycasters();
|
||||
int nextId = 0;
|
||||
for (auto &raycaster : raycasters) {
|
||||
RaycastData data;
|
||||
data.id = nextId++;
|
||||
data.namespaceName = "HELPER";
|
||||
|
||||
std::string vsPath = raycaster->getBoundsVsPath();
|
||||
std::string fsPath = raycaster->getBoundsFsPath();
|
||||
|
||||
ghoul::Dictionary dict;
|
||||
dict.setValue("fragmentRendererPath", FragmentRendererPath);
|
||||
dict.setValue("windowWidth", OsEng.windowWrapper().currentWindowResolution().x);
|
||||
dict.setValue("windowHeight", OsEng.windowWrapper().currentWindowResolution().y);
|
||||
dict.setValue("rendererData", _rendererData);
|
||||
dict.setValue("fragmentPath", fsPath);
|
||||
dict.setValue("id", data.id);
|
||||
std::string helperPath = raycaster->getHelperPath();
|
||||
ghoul::Dictionary helpersDict;
|
||||
if (helperPath != "") {
|
||||
helpersDict.setValue("0", helperPath);
|
||||
}
|
||||
dict.setValue("helperPaths", helpersDict);
|
||||
dict.setValue("raycastPath", raycaster->getRaycastPath());
|
||||
|
||||
_raycastData[raycaster] = data;
|
||||
|
||||
OsEng.renderEngine().setRendererData(dict);
|
||||
try {
|
||||
_exitPrograms[raycaster] = ghoul::opengl::ProgramObject::Build("Volume " + std::to_string(data.id) + " exit", vsPath, ExitFragmentShaderPath, dict);
|
||||
}
|
||||
catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
}
|
||||
try {
|
||||
_raycastPrograms[raycaster] = ghoul::opengl::ProgramObject::Build("Volume " + std::to_string(data.id) + " raycast", vsPath, RaycastFragmentShaderPath, dict);
|
||||
} catch (ghoul::RuntimeError e) {
|
||||
LERROR(e.message);
|
||||
}
|
||||
}
|
||||
_dirtyRaycastData = false;
|
||||
}
|
||||
|
||||
void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurements) {
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
if (_scene == nullptr) return;
|
||||
if (_camera == nullptr) return;
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
RenderData data = { *_camera, psc(), doPerformanceMeasurements };
|
||||
RendererTasks tasks;
|
||||
|
||||
// Capture standard fbo
|
||||
GLint defaultFbo;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// bind new fbo A with color and depth buffer.
|
||||
_scene->render(data, tasks);
|
||||
|
||||
for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) {
|
||||
VolumeRaycaster* raycaster = raycasterTask.raycaster;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _exitFramebuffer);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
ghoul::opengl::ProgramObject* exitProgram = _exitPrograms[raycaster].get();
|
||||
if (exitProgram) {
|
||||
exitProgram->activate();
|
||||
raycaster->renderExitPoints(raycasterTask.renderData, *exitProgram);
|
||||
exitProgram->deactivate();
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer);
|
||||
|
||||
ghoul::opengl::ProgramObject* raycastProgram = _raycastPrograms[raycaster].get();
|
||||
if (raycastProgram) {
|
||||
raycastProgram->activate();
|
||||
raycaster->preRaycast(_raycastData[raycaster], *raycastProgram);
|
||||
|
||||
ghoul::opengl::TextureUnit exitColorTextureUnit;
|
||||
exitColorTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D, _exitColorTexture);
|
||||
raycastProgram->setUniform("exitColorTexture", exitColorTextureUnit);
|
||||
|
||||
ghoul::opengl::TextureUnit exitDepthTextureUnit;
|
||||
exitDepthTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D, _exitDepthTexture);
|
||||
raycastProgram->setUniform("exitDepthTexture", exitDepthTextureUnit);
|
||||
|
||||
ghoul::opengl::TextureUnit mainDepthTextureUnit;
|
||||
mainDepthTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture);
|
||||
raycastProgram->setUniform("mainDepthTexture", mainDepthTextureUnit);
|
||||
|
||||
raycastProgram->setUniform("nAaSamples", _nAaSamples);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(false);
|
||||
raycaster->renderEntryPoints(raycasterTask.renderData, *raycastProgram);
|
||||
glDepthMask(true);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
raycaster->postRaycast(_raycastData[raycaster], *raycastProgram);
|
||||
raycastProgram->deactivate();
|
||||
} else {
|
||||
LWARNING("Raycaster is not attached when trying to perform raycaster task");
|
||||
}
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
|
||||
_resolveProgram->activate();
|
||||
|
||||
ghoul::opengl::TextureUnit mainColorTextureUnit;
|
||||
mainColorTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture);
|
||||
|
||||
_resolveProgram->setUniform("mainColorTexture", mainColorTextureUnit);
|
||||
_resolveProgram->setUniform("blackoutFactor", blackoutFactor);
|
||||
_resolveProgram->setUniform("nAaSamples", _nAaSamples);
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
_resolveProgram->deactivate();
|
||||
}
|
||||
|
||||
void FramebufferRenderer::setScene(Scene* scene) {
|
||||
_scene = scene;
|
||||
}
|
||||
|
||||
void FramebufferRenderer::setCamera(Camera* camera) {
|
||||
_camera = camera;
|
||||
}
|
||||
|
||||
void FramebufferRenderer::setResolution(glm::ivec2 res) {
|
||||
_resolution = res;
|
||||
}
|
||||
|
||||
void FramebufferRenderer::updateRendererData() {
|
||||
ghoul::Dictionary dict;
|
||||
dict.setValue("fragmentRendererPath", RenderFragmentShaderPath);
|
||||
dict.setValue("windowWidth", _resolution.x);
|
||||
dict.setValue("windowHeight", _resolution.y);
|
||||
|
||||
_rendererData = dict;
|
||||
|
||||
OsEng.renderEngine().setRendererData(dict);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
83
src/rendering/raycastermanager.cpp
Normal file
83
src/rendering/raycastermanager.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2016 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
#include <openspace/rendering/raycasterlistener.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "RaycasterManager";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
RaycasterManager::RaycasterManager() {}
|
||||
|
||||
RaycasterManager::~RaycasterManager() {}
|
||||
|
||||
void RaycasterManager::attachRaycaster(VolumeRaycaster& raycaster) {
|
||||
if (!isAttached(raycaster)) {
|
||||
_raycasters.push_back(&raycaster);
|
||||
}
|
||||
for (auto &listener : _listeners) {
|
||||
listener->raycastersChanged(raycaster, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool RaycasterManager::isAttached(VolumeRaycaster& raycaster) {
|
||||
auto it = std::find(_raycasters.begin(), _raycasters.end(), &raycaster);
|
||||
return it != _raycasters.end();
|
||||
}
|
||||
|
||||
|
||||
void RaycasterManager::detachRaycaster(VolumeRaycaster& raycaster) {
|
||||
auto it = std::find(_raycasters.begin(), _raycasters.end(), &raycaster);
|
||||
if (it != _raycasters.end()) {
|
||||
_raycasters.erase(it);
|
||||
for (auto &listener : _listeners) {
|
||||
listener->raycastersChanged(raycaster, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RaycasterManager::addListener(RaycasterListener& listener) {
|
||||
auto it = std::find(_listeners.begin(), _listeners.end(), &listener);
|
||||
if (it == _listeners.end()) {
|
||||
_listeners.push_back(&listener);
|
||||
}
|
||||
}
|
||||
|
||||
void RaycasterManager::removeListener(RaycasterListener& listener) {
|
||||
auto it = std::find(_listeners.begin(), _listeners.end(), &listener);
|
||||
if (it != _listeners.end()) {
|
||||
_listeners.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<VolumeRaycaster*>& RaycasterManager::raycasters() {
|
||||
return _raycasters;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -111,15 +111,25 @@ void Renderable::update(const UpdateData&)
|
||||
{
|
||||
}
|
||||
|
||||
void Renderable::render(const RenderData& data, RendererTasks& tasks)
|
||||
{
|
||||
(void) tasks;
|
||||
render(data);
|
||||
}
|
||||
|
||||
void Renderable::render(const RenderData& data)
|
||||
{
|
||||
}
|
||||
|
||||
void Renderable::setPscUniforms(
|
||||
ghoul::opengl::ProgramObject* program,
|
||||
const Camera* camera,
|
||||
ghoul::opengl::ProgramObject& program,
|
||||
const Camera& camera,
|
||||
const PowerScaledCoordinate& position)
|
||||
{
|
||||
program->setUniform("campos", camera->position().vec4());
|
||||
program->setUniform("objpos", position.vec4());
|
||||
program->setUniform("camrot", camera->viewRotationMatrix());
|
||||
program->setUniform("scaling", camera->scaling());
|
||||
program.setUniform("campos", camera.position().vec4());
|
||||
program.setUniform("objpos", position.vec4());
|
||||
program.setUniform("camrot", camera.viewRotationMatrix());
|
||||
program.setUniform("scaling", camera.scaling());
|
||||
}
|
||||
|
||||
bool Renderable::isVisible() const {
|
||||
@@ -166,8 +176,10 @@ bool Renderable::isEnabled() const {
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
std::vector<Volume*> Renderable::volumesToRender(const RenderData& data) const {
|
||||
return std::vector<Volume*>();
|
||||
void Renderable::onEnabledChange(std::function<void(bool)> callback) {
|
||||
_enabled.onChange([=] () {
|
||||
callback(isEnabled());
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <openspace/rendering/renderer.h>
|
||||
#include <openspace/rendering/abufferrenderer.h>
|
||||
#include <openspace/rendering/framebufferrenderer.h>
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
|
||||
#include <modules/base/rendering/screenspaceimage.h>
|
||||
#include <modules/base/rendering/screenspaceframebuffer.h>
|
||||
@@ -57,6 +58,7 @@
|
||||
#include <openspace/engine/wrapper/windowwrapper.h>
|
||||
#include <openspace/rendering/screenspacerenderable.h>
|
||||
|
||||
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/io/texture/texturewriter.h>
|
||||
#ifdef GHOUL_USE_DEVIL
|
||||
@@ -135,6 +137,7 @@ RenderEngine::~RenderEngine() {
|
||||
|
||||
delete _mainCamera;
|
||||
delete _performanceMemory;
|
||||
delete _raycasterManager;
|
||||
|
||||
if (ghoul::SharedMemory::exists(PerformanceMeasurementSharedData))
|
||||
ghoul::SharedMemory::remove(PerformanceMeasurementSharedData);
|
||||
@@ -182,6 +185,8 @@ bool RenderEngine::initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
_raycasterManager = new RaycasterManager();
|
||||
|
||||
LINFO("Seting renderer from string: " << renderingMethod);
|
||||
setRendererFromString(renderingMethod);
|
||||
|
||||
@@ -441,6 +446,10 @@ Scene* RenderEngine::scene() {
|
||||
return _sceneGraph;
|
||||
}
|
||||
|
||||
RaycasterManager& RenderEngine::raycasterManager() {
|
||||
return *_raycasterManager;
|
||||
}
|
||||
|
||||
void RenderEngine::setSceneGraph(Scene* sceneGraph) {
|
||||
_sceneGraph = sceneGraph;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ ScreenSpaceRenderable::ScreenSpaceRenderable()
|
||||
, _alpha("alpha", "Alpha" , 1, 0, 1)
|
||||
, _quad(0)
|
||||
, _vertexPositionBuffer(0)
|
||||
,_rendererPath("${SHADERS}/renderframebuffer.frag")
|
||||
,_rendererPath("${SHADERS}/framebuffer/renderframebuffer.frag")
|
||||
,_vertexPath("${MODULE_BASE}/shaders/screnspace_vs.glsl")
|
||||
,_fragmentPath("${MODULE_BASE}/shaders/screnspace_fs.glsl")
|
||||
,_texture(nullptr)
|
||||
|
||||
@@ -131,19 +131,10 @@ void Scene::evaluate(Camera* camera) {
|
||||
//_root->evaluate(camera);
|
||||
}
|
||||
|
||||
void Scene::render(const RenderData& data) {
|
||||
for (SceneGraphNode* node : _graph.nodes())
|
||||
node->render(data);
|
||||
}
|
||||
|
||||
std::vector<std::pair<Volume*, RenderData>> Scene::volumesToRender(const RenderData& data) const {
|
||||
std::vector<std::pair<Volume*, RenderData>> volumes;
|
||||
|
||||
for (const SceneGraphNode* node : _graph.nodes()) {
|
||||
std::vector<std::pair<Volume*, RenderData>> newVolumes = node->volumesToRender(data);
|
||||
std::copy(newVolumes.begin(), newVolumes.end(), std::back_inserter(volumes));
|
||||
void Scene::render(const RenderData& data, RendererTasks& tasks) {
|
||||
for (SceneGraphNode* node : _graph.nodes()) {
|
||||
node->render(data, tasks);
|
||||
}
|
||||
return volumes;
|
||||
}
|
||||
|
||||
void Scene::scheduleLoadSceneFile(const std::string& sceneDescriptionFilePath) {
|
||||
|
||||
@@ -242,7 +242,7 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) {
|
||||
// child->evaluate(camera, psc());
|
||||
}
|
||||
|
||||
void SceneGraphNode::render(const RenderData& data) {
|
||||
void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) {
|
||||
const psc thisPosition = worldPosition();
|
||||
|
||||
RenderData newData = {data.camera, thisPosition, data.doPerformanceMeasurement};
|
||||
@@ -253,14 +253,14 @@ void SceneGraphNode::render(const RenderData& data) {
|
||||
glFinish();
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
_renderable->render(newData);
|
||||
_renderable->render(newData, tasks);
|
||||
|
||||
glFinish();
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
_performanceRecord.renderTime = (end - start).count();
|
||||
}
|
||||
else
|
||||
_renderable->render(newData);
|
||||
_renderable->render(newData, tasks);
|
||||
}
|
||||
|
||||
// evaluate all the children, tail-recursive function(?)
|
||||
@@ -269,18 +269,6 @@ void SceneGraphNode::render(const RenderData& data) {
|
||||
// child->render(newData);
|
||||
}
|
||||
|
||||
std::vector<std::pair<Volume*, RenderData>> SceneGraphNode::volumesToRender(const RenderData& data) const {
|
||||
const psc thisPosition = worldPosition();
|
||||
RenderData newData = {data.camera, thisPosition, data.doPerformanceMeasurement};
|
||||
std::vector<std::pair<Volume*, RenderData>> toRender;
|
||||
if (_renderableVisible && _renderable->isVisible() && _renderable->isReady() && _renderable->isEnabled()) {
|
||||
std::vector<Volume*> volumes = _renderable->volumesToRender(newData);
|
||||
for (Volume* v : volumes) {
|
||||
toRender.push_back(std::make_pair(v, newData));
|
||||
}
|
||||
}
|
||||
return toRender;
|
||||
}
|
||||
|
||||
// not used anymore @AA
|
||||
//void SceneGraphNode::addNode(SceneGraphNode* child)
|
||||
|
||||
@@ -111,19 +111,19 @@ void BlockPlaneIntersectionGeometry::updateVertices() {
|
||||
std::vector< std::pair<int, float> > angles(nIntersections-1);
|
||||
|
||||
glm::vec3 vector1 = glm::normalize(intersections[1] - intersections[0]);
|
||||
angles[0] = std::pair<int, float>(1, 0.0);
|
||||
angles[0] = std::pair<int, float>(1, 0.0f);
|
||||
|
||||
for (int i = 2; i < nIntersections; i++) {
|
||||
glm::vec3 vectorI = glm::normalize(intersections[i] - intersections[0]);
|
||||
float sinA = glm::dot(glm::cross(vector1, vectorI), _normal);
|
||||
float cosA = glm::dot(vector1, vectorI);
|
||||
angles[i-1] = std::pair<int, float>(i, glm::sign(sinA) * (1.0 - cosA));
|
||||
angles[i - 1] = std::pair<int, float>(i, static_cast<float>(glm::sign(sinA) * (1.0 - cosA)));
|
||||
}
|
||||
|
||||
// Sort the vectors by angle in the plane
|
||||
std::sort(angles.begin(), angles.end(),
|
||||
[](const std::pair<int, float>& a, const std::pair<int, float>& b) -> bool {
|
||||
return a.second > b.second;
|
||||
return a.second < b.second;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -138,6 +138,17 @@ void BlockPlaneIntersectionGeometry::updateVertices() {
|
||||
_vertices.push_back(intersections[j].z);
|
||||
//_vertices.push_back(_w);
|
||||
}
|
||||
|
||||
// First VAO setup
|
||||
glBindVertexArray(_vaoId);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vBufferId);
|
||||
glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(GLfloat), _vertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
bool BlockPlaneIntersectionGeometry::initialize() {
|
||||
@@ -154,23 +165,14 @@ bool BlockPlaneIntersectionGeometry::initialize() {
|
||||
}
|
||||
|
||||
updateVertices();
|
||||
// First VAO setup
|
||||
glBindVertexArray(_vaoId);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vBufferId);
|
||||
glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(GLfloat), _vertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlockPlaneIntersectionGeometry::render() {
|
||||
glBindVertexArray(_vaoId); // select first VAO
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6*6);
|
||||
glBindVertexArray(0);
|
||||
glBindVertexArray(_vaoId);
|
||||
//glDisable(GL_CULL_FACE);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, _vertices.size() / 3);
|
||||
//glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,53 +45,53 @@ BoxGeometry::~BoxGeometry() {
|
||||
|
||||
|
||||
bool BoxGeometry::initialize() {
|
||||
// Initialize and upload to graphics card
|
||||
// Initialize and upload to GPU
|
||||
float x = _size.x * 0.5;
|
||||
float y = _size.y * 0.5;
|
||||
float z = _size.z * 0.5;
|
||||
|
||||
const GLfloat vertices[] = {
|
||||
-x, y, z,
|
||||
x, y, z,
|
||||
-x, y, z,
|
||||
-x, -y, z,
|
||||
x, -y, z,
|
||||
x, y, z,
|
||||
-x, -y, z, // blue corner
|
||||
x, y, z, // white corner
|
||||
-x, y, z, // cyan corner
|
||||
-x, -y, z, // blue corner
|
||||
x, -y, z, // magenta corner
|
||||
x, y, z, // white corner
|
||||
|
||||
-x, -y, -z,
|
||||
x, y, -z,
|
||||
-x, y, -z,
|
||||
-x, -y, -z,
|
||||
x, -y, -z,
|
||||
x, y, -z,
|
||||
-x, -y, -z, // black corner
|
||||
-x, y, -z, // green
|
||||
x, y, -z, // yellow corner
|
||||
-x, -y, -z, // black
|
||||
x, y, -z, // yellow
|
||||
x, -y, -z, // red
|
||||
|
||||
x, -y, -z,
|
||||
x, y, z,
|
||||
x, -y, z,
|
||||
x, -y, -z,
|
||||
x, y, -z,
|
||||
x, y, z,
|
||||
x, -y, -z, // red
|
||||
x, y, z, // yellow
|
||||
x, -y, z, // magenta
|
||||
x, -y, -z, // red
|
||||
x, y, -z, // yellow
|
||||
x, y, z, // white
|
||||
|
||||
-x, -y, -z,
|
||||
-x, y, z,
|
||||
-x, -y, z,
|
||||
-x, -y, -z,
|
||||
-x, y, -z,
|
||||
-x, y, z,
|
||||
|
||||
-x, y, -z,
|
||||
x, y, z,
|
||||
-x, y, z,
|
||||
-x, y, -z,
|
||||
x, y, -z,
|
||||
x, y, z,
|
||||
|
||||
-x, -y, -z,
|
||||
x, -y, z,
|
||||
-x, -y, z,
|
||||
-x, -y, -z,
|
||||
x, -y, -z,
|
||||
x, -y, z
|
||||
-x, -y, -z, // black
|
||||
-x, -y, z, // blue
|
||||
-x, y, z, // cyan
|
||||
-x, -y, -z, // black
|
||||
-x, y, z, // cyan
|
||||
-x, y, -z, // green
|
||||
|
||||
x, y, z, // white
|
||||
-x, y, -z, // green
|
||||
-x, y, z, // cyan
|
||||
-x, y, -z, // green
|
||||
x, y, z, // white
|
||||
x, y, -z, // yellow
|
||||
|
||||
-x, -y, -z, // black
|
||||
x, -y, z, // magenta
|
||||
-x, -y, z, // blue
|
||||
-x, -y, -z, // black
|
||||
x, -y, -z, // red
|
||||
x, -y, z // magenta
|
||||
};
|
||||
|
||||
if (_vaoId == 0)
|
||||
@@ -113,7 +113,7 @@ bool BoxGeometry::initialize() {
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3, 0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);
|
||||
|
||||
glBindVertexArray(0);
|
||||
return true;
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <format.h>
|
||||
#include <cppformat/format.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "SpiceManager";
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#########################################################################################
|
||||
|
||||
include (${OPENSPACE_CMAKE_EXT_DIR}/module_common.cmake)
|
||||
include (${GHOUL_BASE_DIR}/ext/handle_external_library.cmake)
|
||||
include (${GHOUL_BASE_DIR}/support/cmake/handle_external_library.cmake)
|
||||
|
||||
# Creates a new project and a library for the module with name <module_name>. The name of
|
||||
# the library is returned in <output_library_name> for outside configuration
|
||||
|
||||
@@ -126,7 +126,6 @@ function (add_external_dependencies)
|
||||
target_compile_definitions(libOpenSpace PUBLIC ${GHOUL_DEFINITIONS})
|
||||
set_property(TARGET Lua PROPERTY FOLDER "External")
|
||||
set_property(TARGET lz4 PROPERTY FOLDER "External")
|
||||
set_property(TARGET tinyobjloader PROPERTY FOLDER "External")
|
||||
|
||||
# SGCT
|
||||
find_package(SGCT REQUIRED)
|
||||
|
||||
Reference in New Issue
Block a user