Merge branch 'develop' into feature/globebrowsing

Conflicts:
	modules/base/scale/staticscale.cpp
	modules/base/scale/staticscale.h
	modules/globebrowsing/meshes/trianglesoup.h
	modules/globebrowsing/tile/tiledataset.cpp
	modules/newhorizons/shaders/renderableModelProjection_fs.glsl
	src/interaction/interactionhandler.cpp
	src/rendering/renderengine.cpp
	src/scene/scenegraphnode.cpp
This commit is contained in:
Alexander Bock
2016-09-20 15:52:01 +02:00
142 changed files with 8052 additions and 1702 deletions
+26 -5
View File
@@ -65,12 +65,27 @@ BaseModule::BaseModule()
{}
void BaseModule::internalInitialize() {
FactoryManager::ref().addFactory(std::make_unique<ghoul::TemplateFactory<planetgeometry::PlanetGeometry>>());
FactoryManager::ref().addFactory(std::make_unique<ghoul::TemplateFactory<modelgeometry::ModelGeometry>>());
FactoryManager::ref().addFactory(std::make_unique<ghoul::TemplateFactory<ScreenSpaceRenderable>>());
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<planetgeometry::PlanetGeometry>>(),
"PlanetGeometry"
);
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<modelgeometry::ModelGeometry>>(),
"ModelGeometry"
);
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<ScreenSpaceRenderable>>(),
"ScreenSpaceRenderable"
);
FactoryManager::ref().addFactory(std::make_unique<ghoul::TemplateFactory<Rotation>>());
FactoryManager::ref().addFactory(std::make_unique<ghoul::TemplateFactory<Scale>>());
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<Rotation>>(),
"Rotation"
);
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<Scale>>(),
"Scale"
);
auto fScreenSpaceRenderable = FactoryManager::ref().factory<ScreenSpaceRenderable>();
ghoul_assert(fScreenSpaceRenderable, "ScreenSpaceRenderable factory was not created");
@@ -119,4 +134,10 @@ void BaseModule::internalInitialize() {
fModelGeometry->registerClass<modelgeometry::MultiModelGeometry>("MultiModelGeometry");
}
std::vector<Documentation> BaseModule::documentations() const {
return {
StaticScale::Documentation()
};
}
} // namespace openspace
+2
View File
@@ -33,6 +33,8 @@ class BaseModule : public OpenSpaceModule {
public:
BaseModule();
std::vector<Documentation> documentations() const override;
protected:
void internalInitialize() override;
};
+10 -1
View File
@@ -27,6 +27,8 @@
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
#include <ghoul/filesystem/filesystem.h>
namespace {
const std::string _loggerCat = "SpiceEphemeris";
//const std::string keyGhosting = "EphmerisGhosting";
@@ -59,8 +61,15 @@ SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary)
for (size_t i = 1; i <= kernels.size(); ++i) {
std::string kernel;
bool success = kernels.getValue(std::to_string(i), kernel);
if (!success)
if (!success) {
LERROR("'" << KeyKernels << "' has to be an array-style table");
break;
}
if (!FileSys.fileExists(kernel)) {
LERROR("Kernel '" << kernel << "' does not exist");
continue;
}
try {
SpiceManager::ref().loadKernel(kernel);
+3 -3
View File
@@ -125,9 +125,9 @@ bool ModelGeometry::initialize(Renderable* parent) {
for (auto v: _vertices)
{
maximumDistanceSquared = glm::max(
glm::pow(v.location[0], 2) +
glm::pow(v.location[1], 2) +
glm::pow(v.location[2], 2), maximumDistanceSquared);
glm::pow(v.location[0], 2.f) +
glm::pow(v.location[1], 2.f) +
glm::pow(v.location[2], 2.f), maximumDistanceSquared);
}
_parent->setBoundingSphere(PowerScaledScalar(glm::sqrt(maximumDistanceSquared), 0.0));
+1 -1
View File
@@ -211,7 +211,7 @@ void RenderableModel::render(const RenderData& data) {
glm::dmat4 modelTransform =
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation
glm::dmat4(data.modelTransform.rotation) * // Spice rotation
glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)));
glm::dmat4(glm::scale(glm::dmat4(_modelTransform), glm::dvec3(data.modelTransform.scale)));
debugModelRotation; // debug model rotation controlled from GUI
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
+30 -1
View File
@@ -60,6 +60,7 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary)
, _shader(nullptr)
, _textureIsDirty(false)
, _texture(nullptr)
, _blendMode(BlendMode::Normal)
, _quad(0)
, _vertexPositionBuffer(0)
{
@@ -67,7 +68,7 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary)
dictionary.getValue("Size", size);
_size = size;
if (dictionary.hasKey("Name")){
if (dictionary.hasKey("Name")) {
dictionary.getValue("Name", _nodeName);
}
@@ -102,6 +103,13 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary)
}
}
std::string blendMode;
if (dictionary.getValue("BlendMode", blendMode)) {
if (blendMode == "Additive") {
_blendMode = BlendMode::Additive;
setRenderBin(Renderable::RenderBin::Transparent);
}
}
std::string texturePath = "";
bool success = dictionary.getValue("Texture", texturePath);
@@ -228,9 +236,30 @@ void RenderablePlane::render(const RenderData& data) {
_texture->bind();
_shader->setUniform("texture1", unit);
bool usingFramebufferRenderer =
OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::Framebuffer;
bool usingABufferRenderer =
OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::ABuffer;
if (usingABufferRenderer) {
_shader->setUniform("additiveBlending", _blendMode == BlendMode::Additive);
}
bool additiveBlending = _blendMode == BlendMode::Additive && usingFramebufferRenderer;
if (additiveBlending) {
glDepthMask(false);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
}
glBindVertexArray(_quad);
glDrawArrays(GL_TRIANGLES, 0, 6);
if (additiveBlending) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(true);
}
_shader->deactivate();
}
+6
View File
@@ -51,6 +51,11 @@ class RenderablePlane : public Renderable {
};
public:
enum class BlendMode : int {
Normal = 0,
Additive
};
RenderablePlane(const ghoul::Dictionary& dictionary);
~RenderablePlane();
@@ -79,6 +84,7 @@ private:
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
bool _textureIsDirty;
std::unique_ptr<ghoul::opengl::Texture> _texture;
BlendMode _blendMode;
ghoul::filesystem::File* _textureFile;
GLuint _quad;
GLuint _vertexPositionBuffer;
@@ -124,6 +124,7 @@ bool RenderableTrail::initialize() {
"${MODULE_BASE}/shaders/ephemeris_vs.glsl",
"${MODULE_BASE}/shaders/ephemeris_fs.glsl");
setRenderBin(Renderable::RenderBin::Overlay);
if (!_programObject)
return false;
@@ -192,6 +193,14 @@ void RenderableTrail::render(const RenderData& data) {
// _programObject->setUniform("forceFade", _distanceFade);
//}
bool usingFramebufferRenderer =
OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::Framebuffer;
if (usingFramebufferRenderer) {
glDepthMask(false);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
}
glLineWidth(_lineWidth);
glBindVertexArray(_vaoID);
@@ -207,6 +216,12 @@ void RenderableTrail::render(const RenderData& data) {
glBindVertexArray(0);
}
if (usingFramebufferRenderer) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(true);
}
_programObject->deactivate();
}
+26 -13
View File
@@ -24,6 +24,8 @@
#include <modules/base/scale/staticscale.h>
#include <openspace/documentation/verifier.h>
namespace {
const std::string _loggerCat = "StaticScale";
const std::string KeyValue = "Scale";
@@ -31,24 +33,35 @@ namespace {
namespace openspace {
StaticScale::StaticScale(const ghoul::Dictionary& dictionary)
Documentation StaticScale::Documentation() {
using namespace openspace::documentation;
return {
"Static Scaling",
{{
KeyValue,
new DoubleVerifier,
"The scaling factor by which the scenegraph node is scaled."
}}
};
}
StaticScale::StaticScale()
: _scaleValue("scale", "Scale", 1.0, 1.0, 1000.0)
{
const bool hasValue = dictionary.hasKeyAndValue<glm::vec3>(KeyValue);
if (hasValue) {
float value;
dictionary.getValue(KeyValue, value);
_scaleValue.setValue(value);
}
Scale::addProperty(_scaleValue);
addProperty(_scaleValue);
}
StaticScale::~StaticScale() {}
StaticScale::StaticScale(const ghoul::Dictionary& dictionary)
: StaticScale()
{
documentation::testSpecificationAndThrow(Documentation(), dictionary, "StaticScale");
_scaleValue = dictionary.value<double>(KeyValue);
}
double StaticScale::scaleValue() const {
return _scaleValue.value();
return _scaleValue;
}
void StaticScale::update(const UpdateData&) {}
} // namespace openspace
} // namespace openspace
+9 -6
View File
@@ -27,17 +27,20 @@
#include <openspace/scene/scale.h>
#include <openspace/documentation/documentation.h>
namespace openspace {
class StaticScale: public Scale {
class StaticScale : public Scale {
public:
StaticScale(const ghoul::Dictionary& dictionary = ghoul::Dictionary());
virtual ~StaticScale();
virtual double scaleValue() const;
virtual void update(const UpdateData& data) override;
StaticScale();
StaticScale(const ghoul::Dictionary& dictionary);
double scaleValue() const;
static openspace::Documentation Documentation();
private:
properties::FloatProperty _scaleValue;
//double _scaleValue;
};
} // namespace openspace
+4 -3
View File
@@ -32,10 +32,11 @@ in float fade;
#include "fragment.glsl"
Fragment getFragment() {
vec4 c = vec4(color, fade*forceFade);
vec4 c = vec4(color * fade * forceFade, 1.0);
Fragment frag;
frag.color = c;
frag.depth = vs_positionScreenSpace.w;
frag.blend = BLEND_MODE_ADDITIVE;
return frag;
}
}
+5
View File
@@ -24,6 +24,7 @@
uniform float time;
uniform sampler2D texture1;
uniform bool additiveBlending;
in vec2 vs_st;
in vec4 vs_positionScreenSpace;
@@ -50,6 +51,10 @@ Fragment getFragment() {
Fragment frag;
frag.color = diffuse;
frag.depth = vs_positionScreenSpace.w;
if (additiveBlending) {
frag.blend = BLEND_MODE_ADDITIVE;
}
return frag;
}
@@ -26,8 +26,6 @@
#include <modules/debugging/rendering/renderabledebugplane.h>
#include <openspace/engine/configurationmanager.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/util/powerscaledcoordinate.h>
@@ -214,7 +214,7 @@ namespace openspace {
const vec4& clippingSpaceCorner = mvp * modelSpaceCorners[i];
clippingSpaceCorners[i] = clippingSpaceCorner;
vec3 screenSpaceCorner = (1.0f / clippingSpaceCorner.w) * clippingSpaceCorner.xyz();
vec3 screenSpaceCorner = (1.0f / clippingSpaceCorner.w) * clippingSpaceCorner;
screenSpaceBounds.expand(screenSpaceCorner);
}
@@ -372,7 +372,7 @@ namespace openspace {
glm::vec3 directionToSunWorldSpace =
glm::normalize(-data.modelTransform.translation);
glm::vec3 directionToSunCameraSpace =
(viewTransform * glm::dvec4(directionToSunWorldSpace, 0)).xyz();
(viewTransform * glm::dvec4(directionToSunWorldSpace, 0));
data.modelTransform.translation;
programObject->setUniform("modelViewTransform", modelViewTransform);
programObject->setUniform("lightDirectionCameraSpace", -directionToSunCameraSpace);
@@ -451,7 +451,7 @@ namespace openspace {
glm::vec3 directionToSunWorldSpace =
glm::normalize(-data.modelTransform.translation);
glm::vec3 directionToSunCameraSpace =
(viewTransform * glm::dvec4(directionToSunWorldSpace, 0)).xyz();
(viewTransform * glm::dvec4(directionToSunWorldSpace, 0));
data.modelTransform.translation;
programObject->setUniform("lightDirectionCameraSpace", -directionToSunCameraSpace);
}
+1 -1
View File
@@ -72,7 +72,7 @@ namespace openspace {
dvec4 cornerClippingSpace = modelViewProjectionTransform * corners[i];
clippingSpaceCorners[i] = cornerClippingSpace;
dvec3 cornerScreenSpace = (1.0f / glm::abs(cornerClippingSpace.w)) * cornerClippingSpace.xyz();
dvec3 cornerScreenSpace = (1.0f / glm::abs(cornerClippingSpace.w)) * cornerClippingSpace;
bounds.expand(cornerScreenSpace);
}
+1 -1
View File
@@ -145,7 +145,7 @@ namespace openspace {
}
Scalar Ellipsoid::longitudalDistance(Scalar lat, Scalar lon1, Scalar lon2) const {
Vec2 ellipseRadii = glm::cos(lat) * _radii.xy();
Vec2 ellipseRadii = glm::cos(lat) * Vec2(_radii);
// Approximating with the ellipse mean radius
Scalar meanRadius = 0.5 * (ellipseRadii.x + ellipseRadii.y);
return meanRadius * std::abs(lon2 - lon1);
@@ -239,14 +239,14 @@ namespace openspace {
// Sample and do linear interpolation (could possibly be moved as a function in ghoul texture)
glm::uvec3 dimensions = tile.texture->dimensions();
glm::vec2 samplePos = transformedUv * glm::vec2(dimensions.xy());
glm::vec2 samplePos = transformedUv * glm::vec2(dimensions);
glm::uvec2 samplePos00 = samplePos;
samplePos00 = glm::clamp(samplePos00, glm::uvec2(0, 0), dimensions.xy() - glm::uvec2(1));
samplePos00 = glm::clamp(samplePos00, glm::uvec2(0, 0), glm::uvec2(dimensions) - glm::uvec2(1));
glm::vec2 samplePosFract = samplePos - glm::vec2(samplePos00);
glm::uvec2 samplePos10 = glm::min(samplePos00 + glm::uvec2(1, 0), dimensions.xy() - glm::uvec2(1));
glm::uvec2 samplePos01 = glm::min(samplePos00 + glm::uvec2(0, 1), dimensions.xy() - glm::uvec2(1));
glm::uvec2 samplePos11 = glm::min(samplePos00 + glm::uvec2(1, 1), dimensions.xy() - glm::uvec2(1));
glm::uvec2 samplePos10 = glm::min(samplePos00 + glm::uvec2(1, 0), glm::uvec2(dimensions) - glm::uvec2(1));
glm::uvec2 samplePos01 = glm::min(samplePos00 + glm::uvec2(0, 1), glm::uvec2(dimensions) - glm::uvec2(1));
glm::uvec2 samplePos11 = glm::min(samplePos00 + glm::uvec2(1, 1), glm::uvec2(dimensions) - glm::uvec2(1));
float sample00 = tile.texture->texelAsFloat(samplePos00).x;
float sample10 = tile.texture->texelAsFloat(samplePos10).x;
@@ -36,9 +36,9 @@ TriangleSoup::TriangleSoup(std::vector<unsigned int> elements,
: _vaoID(0)
,_vertexBufferID(0)
,_elementBufferID(0)
,_useVertexPositions(usePositions == Positions::Yes)
,_useTextureCoordinates(useTextures == TextureCoordinates::Yes)
,_useVertexNormals(useNormals == Normals::Yes)
,_useVertexPositions(usePositions)
,_useTextureCoordinates(useTextures)
,_useVertexNormals(useNormals)
{
setElements(elements);
}
+4 -3
View File
@@ -25,6 +25,7 @@
#ifndef __TRIANGLESOUP_H__
#define __TRIANGLESOUP_H__
#include <ghoul/misc/boolean.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/logging/logmanager.h>
@@ -46,9 +47,9 @@ namespace openspace {
class TriangleSoup
{
public:
enum class Positions { Yes, No };
enum class TextureCoordinates { Yes, No };
enum class Normals { Yes, No };
using Positions = ghoul::Boolean;
using TextureCoordinates = ghoul::Boolean;
using Normals = ghoul::Boolean;
TriangleSoup(
std::vector<unsigned int> elements, // At least elements are required
+3 -2
View File
@@ -24,6 +24,7 @@
#ifndef __STATS_TRACKER_H__
#define __STATS_TRACKER_H__
#include <ghoul/misc/boolean.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem>
@@ -143,13 +144,13 @@ namespace openspace {
StatsCollector() = delete;
enum class Enabled { Yes, No };
using Enabled = ghoul::Boolean;
StatsCollector(const std::string& filename, int dumpEveryXRecord, Enabled enabled = Enabled::Yes, const std::string& delimiter = ",")
: _filename(filename)
, _dumpEveryXRecord(dumpEveryXRecord)
, _recordsSinceLastDump(0)
, _enabled(enabled == Enabled::Yes)
, _enabled(enabled)
, _delimiter(delimiter)
, _hasWrittenHeader(false)
, i(TemplatedStatsCollector<long long>(_enabled, delimiter))
+3 -3
View File
@@ -473,7 +473,7 @@ namespace openspace {
io.write.region.roundDownToQuadratic();
io.write.region.roundUpNumPixelToNearestMultipleOf(2);
if (preRound != io.write.region.numPixels) {
//LDEBUG(chunkIndex << " | " << preRound.x << ", " << preRound.y << " --> " << io.write.region.numPixels.x << ", " << io.write.region.numPixels.y);
LDEBUG(chunkIndex << " | " << preRound.x << ", " << preRound.y << " --> " << io.write.region.numPixels.x << ", " << io.write.region.numPixels.y);
}
@@ -611,10 +611,10 @@ namespace openspace {
}
}
if (depth == 0) {
//if (depth == 0) {
//LDEBUG(indentation << "main rasterIO read: " << io.read.region);
//LDEBUG(indentation << "main rasterIO write: " << io.write.region);
}
//}
else if (worstError > CPLErr::CE_None) {
LDEBUG(indentation << "Error reading padding: " << worstError);
+4 -1
View File
@@ -51,7 +51,10 @@ NewHorizonsModule::NewHorizonsModule()
void NewHorizonsModule::internalInitialize() {
ImageSequencer::initialize();
FactoryManager::ref().addFactory(std::make_unique<ghoul::TemplateFactory<Decoder>>());
FactoryManager::ref().addFactory(
std::make_unique<ghoul::TemplateFactory<Decoder>>(),
"Decoder"
);
auto fRenderable = FactoryManager::ref().factory<Renderable>();
ghoul_assert(fRenderable, "No renderable factory existed");
@@ -24,12 +24,10 @@
#include <modules/newhorizons/rendering/renderablecrawlingline.h>
#include <openspace/engine/configurationmanager.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/spicemanager.h>
#include <modules/newhorizons/util/imagesequencer.h>
//#include <imgui.h>
namespace {
const std::string _loggerCat = "RenderableCrawlingLine";
@@ -528,7 +528,7 @@ void RenderableFov::computeIntercepts(const RenderData& data) {
_interceptTag[_bounds.size()] = _interceptTag[0];
fovSurfaceIntercept(_interceptTag, _bounds);
glm::vec3 aim = (_spacecraftRotation * glm::vec4(_boresight, 1)).xyz();
glm::vec3 aim = (_spacecraftRotation * glm::vec4(_boresight, 1));
double lt;
glm::dvec3 position =
SpiceManager::ref().targetPosition(
@@ -40,6 +40,7 @@ namespace {
const std::string keyDestination = "Rotation.Destination";
const std::string keyBody = "Body";
const std::string keyGeometry = "Geometry";
const std::string keyBoundingSphereRadius = "BoundingSphereRadius";
const std::string keyTextureColor = "Textures.Color";
const std::string keyTextureProject = "Textures.Project";
@@ -96,10 +97,10 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di
completeSuccess &= _projectionComponent.initializeProjectionSettings(dictionary);
openspace::SpiceManager::ref().addFrame(_target, _source);
double boundingRadius = _geometry->boundingRadius();
setBoundingSphere(PowerScaledScalar::CreatePSS(boundingRadius));
float boundingSphereRadius = 1.0e9;
dictionary.getValue(keyBoundingSphereRadius, boundingSphereRadius);
setBoundingSphere(PowerScaledScalar::CreatePSS(boundingSphereRadius));
Renderable::addProperty(_performShading);
Renderable::addProperty(_rotation);
@@ -132,9 +133,18 @@ bool RenderableModelProjection::initialize() {
ghoul::opengl::ProgramObject::IgnoreError::Yes
);
_depthFboProgramObject = ghoul::opengl::ProgramObject::Build("DepthPass",
"${MODULE_NEWHORIZONS}/shaders/renderableModelDepth_vs.glsl",
"${MODULE_NEWHORIZONS}/shaders/renderableModelDepth_fs.glsl");
completeSuccess &= loadTextures();
completeSuccess &= _projectionComponent.initialize();
auto bs = getBoundingSphere();
completeSuccess &= _geometry->initialize(this);
setBoundingSphere(bs); // ignore bounding sphere set by geometry.
completeSuccess &= !_source.empty();
completeSuccess &= !_destination.empty();
@@ -164,7 +174,6 @@ void RenderableModelProjection::render(const RenderData& data) {
if (_projectionComponent.needsClearProjection())
_projectionComponent.clearAllProjections();
_camScaling = data.camera.scaling();
_up = data.camera.lookUpVectorCameraSpace();
if (_capture && _projectionComponent.doesPerformProjection())
@@ -221,6 +230,9 @@ void RenderableModelProjection::update(const UpdateData& data) {
_projectionComponent.update();
if (_depthFboProgramObject->isDirty())
_depthFboProgramObject->rebuildFromFile();
_time = data.time;
if (openspace::ImageSequencer::ref().isReady()) {
@@ -252,8 +264,20 @@ void RenderableModelProjection::update(const UpdateData& data) {
void RenderableModelProjection::imageProjectGPU(
std::shared_ptr<ghoul::opengl::Texture> projectionTexture)
{
_projectionComponent.imageProjectBegin();
if (_projectionComponent.needsShadowMap()) {
_projectionComponent.depthMapRenderBegin();
_depthFboProgramObject->activate();
_depthFboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix);
_depthFboProgramObject->setUniform("ModelTransform", _transform);
_geometry->setUniforms(*_fboProgramObject);
_geometry->render();
_depthFboProgramObject->deactivate();
_projectionComponent.depthMapRenderEnd();
}
_projectionComponent.imageProjectBegin();
_fboProgramObject->activate();
ghoul::opengl::TextureUnit unitFbo;
@@ -261,9 +285,17 @@ void RenderableModelProjection::imageProjectGPU(
projectionTexture->bind();
_fboProgramObject->setUniform("projectionTexture", unitFbo);
_fboProgramObject->setUniform("needShadowMap", _projectionComponent.needsShadowMap());
ghoul::opengl::TextureUnit unitDepthFbo;
if (_projectionComponent.needsShadowMap()) {
unitDepthFbo.activate();
_projectionComponent.depthTexture().bind();
_fboProgramObject->setUniform("depthTexture", unitDepthFbo);
}
_fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix);
_fboProgramObject->setUniform("ModelTransform", _transform);
_fboProgramObject->setUniform("_scaling", _camScaling);
_fboProgramObject->setUniform("boresight", _boresight);
_geometry->setUniforms(*_fboProgramObject);
@@ -325,19 +357,24 @@ void RenderableModelProjection::attitudeParameters(double time) {
time, lightTime);
psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z);
position[3] += (3 + _camScaling[1]) + 1;
position[3] += 4;
glm::vec3 cpos = position.vec3();
float distance = glm::length(cpos);
float radius = getBoundingSphere().lengthf();
_projectorMatrix = _projectionComponent.computeProjectorMatrix(
cpos, boresight, _up, _instrumentMatrix,
_projectionComponent.fieldOfViewY(),
_projectionComponent.aspectRatio(),
_projectionComponent.nearPlane(),
_projectionComponent.farPlane(),
distance - radius,
distance + radius,
_boresight
);
}
void RenderableModelProjection::project() {
for (auto img : _imageTimes) {
attitudeParameters(img.timeRange.start);
@@ -74,6 +74,7 @@ private:
std::unique_ptr<ghoul::opengl::ProgramObject> _programObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _fboProgramObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _depthFboProgramObject;
std::unique_ptr<ghoul::opengl::Texture> _baseTexture;
@@ -100,7 +101,6 @@ private:
bool _capture;
psc _sunPosition;
properties::BoolProperty _performShading;
};
@@ -47,6 +47,7 @@ namespace {
const std::string keyFrame = "Frame";
const std::string keyGeometry = "Geometry";
const std::string keyRadius = "Geometry.Radius";
const std::string keyShading = "PerformShading";
const std::string keyBody = "Body";
const std::string _mainFrame = "GALACTIC";
@@ -101,6 +102,10 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
if (success)
_heightMapTexturePath = absPath(heightMapPath);
glm::vec2 radius = glm::vec2(1.0, 9.0);
dictionary.getValue(keyRadius, radius);
setBoundingSphere(pss(radius));
addPropertySubOwner(_geometry.get());
addPropertySubOwner(_projectionComponent);
@@ -134,7 +139,6 @@ bool RenderablePlanetProjection::initialize() {
completeSuccess &= loadTextures();
completeSuccess &= _projectionComponent.initialize();
completeSuccess &= _geometry->initialize(this);
if (completeSuccess) {
@@ -285,6 +289,9 @@ void RenderablePlanetProjection::attitudeParameters(double time) {
//position[3] += 3;
glm::vec3 cpos = position.vec3();
float distance = glm::length(cpos);
float radius = getBoundingSphere().lengthf();
_projectorMatrix = _projectionComponent.computeProjectorMatrix(
cpos,
bs,
@@ -292,8 +299,8 @@ void RenderablePlanetProjection::attitudeParameters(double time) {
_instrumentMatrix,
_projectionComponent.fieldOfViewY(),
_projectionComponent.aspectRatio(),
_projectionComponent.nearPlane(),
_projectionComponent.farPlane(),
distance - radius,
distance + radius,
_boresight
);
}
@@ -0,0 +1,30 @@
/*****************************************************************************************
* *
* 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__
void main() {
gl_FragColor = vec4(1.0);
//gl_FragDepth = gl_FragCoord.z;
}
@@ -0,0 +1,36 @@
/*****************************************************************************************
* *
* 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/powerScaling_vs.hglsl"
layout(location = 0) in vec4 in_position;
uniform mat4 ProjectorMatrix;
uniform mat4 ModelTransform;
void main() {
gl_Position = ProjectorMatrix * ModelTransform * psc_to_meter(in_position, vec2(1.0, 0.0));
}
@@ -25,9 +25,8 @@
#version __CONTEXT__
in vec4 vs_position;
in vec4 vs_ndc;
in vec4 vs_normal;
in vec2 vs_uv;
in vec4 ProjTexCoord;
layout (location = 0) out vec4 color;
// Even though the stencel texture is only a single channel, we still need to
@@ -35,34 +34,53 @@ layout (location = 0) out vec4 color;
layout (location = 1) out vec4 stencil;
uniform sampler2D projectionTexture;
uniform sampler2D depthTexture;
uniform bool needShadowMap;
uniform mat4 ModelTransform;
uniform vec2 _scaling;
uniform vec3 boresight;
uniform vec4 debugColor;
bool inRange(float x, float a, float b) {
return (x >= a && x <= b);
}
void main() {
vec2 uv = vec2(0.5,0.5)*vs_uv+vec2(0.5,0.5);
vec3 n = normalize(vs_normal.xyz);
vec4 projected = ProjTexCoord;
vec4 projected = vs_ndc;
vec2 uv = vec2(0.5) * projected.xy + vec2(0.5);
// normalize
projected.x /= projected.w;
projected.y /= projected.w;
// invert gl coordinates
projected.x = 1 - projected.x;
if (needShadowMap) {
float thisDepth = projected.z * 0.5 + 0.5;
float closestDepth = texture(depthTexture, uv).r;
float epsilon = 0.001;
if ((inRange(projected.x, 0, 1) && inRange(projected.y, 0, 1)) && (dot(n, boresight) < 0)) {
color = texture(projectionTexture, projected.xy);
//color.a = 1.0;
stencil = vec4(1.0);
if (inRange(uv.x, 0.0, 1.0) && inRange(uv.y, 0.0, 1.0) &&
dot(n, boresight) < 0 && thisDepth <= closestDepth + epsilon)
{
// color = texture(projectionTexture, projected.xy);
color = texture(projectionTexture, vec2(1.0) - uv);
color.a = 1.0;
stencil = vec4(1.0);
}
else {
color = vec4(vec3(0.0), 0.0);
stencil = vec4(0.0);
}
}
else {
color = vec4(0.0);//vec4(vec3(0.0), 1.0);
stencil = vec4(0.0);
if (inRange(uv.x, 0.0, 1.0) && inRange(uv.y, 0.0, 1.0) &&
dot(n, boresight) < 0)
{
// color = texture(projectionTexture, projected.xy);
color = texture(projectionTexture, vec2(1.0) - uv);
color.a = 1.0;
stencil = vec4(1.0);
}
else {
color = vec4(vec3(0.0), 0.0);
stencil = vec4(0.0);
}
}
}
@@ -33,26 +33,20 @@ layout(location = 2) in vec3 in_normal;
out vec4 vs_position;
out vec4 vs_normal;
out vec2 vs_uv;
out vec4 ProjTexCoord;
out vec4 vs_ndc;
uniform mat4 ProjectorMatrix;
uniform mat4 ModelTransform;
uniform vec2 _scaling;
uniform vec3 boresight;
void main() {
vs_position = in_position;
vec4 tmp = in_position;
vec4 position = pscTransform(tmp, ModelTransform);
vs_position = position;
vec4 raw_pos = psc_to_meter(in_position, _scaling);
ProjTexCoord = ProjectorMatrix * ModelTransform * raw_pos;
vec4 raw_pos = psc_to_meter(in_position, vec2(1.0, 0.0));
vs_position = ProjectorMatrix * ModelTransform * raw_pos;
vs_normal = normalize(ModelTransform * vec4(in_normal,0));
vs_ndc = vs_position / vs_position.w;
//match clipping plane
vec2 texco = (in_st * 2) - 1;
vs_uv = texco;
@@ -84,12 +84,12 @@ Fragment getFragment() {
color = diffuseAlbedo;
}
float transparency = 1.0;
float alpha = _projectionFading * transparency;
// float transparency = 1.0;
// float alpha = _projectionFading * transparency;
Fragment frag;
frag.color = vec4(color, alpha);
frag.color = vec4(color, 1.0);
frag.depth = vs_positionScreenSpace.w;
return frag;
}
@@ -73,6 +73,8 @@ void main() {
projected.x /= projected.w;
projected.y /= projected.w;
projected = projected * 0.5 + vec4(0.5);
vec3 normal = normalize((ModelTransform*vec4(vertex.xyz,0)).xyz);
vec3 v_b = normalize(boresight);
@@ -83,7 +85,7 @@ void main() {
{
// The 1-x is in this texture call because of flipped textures
// to be fixed soon ---abock
color = texture(projectionTexture, vec2(projected.x, 1-projected.y));
color = texture(projectionTexture, vec2(projected.x, projected.y));
stencil = vec4(1.0);
}
else {
+11 -15
View File
@@ -23,8 +23,11 @@
****************************************************************************************/
#include <modules/newhorizons/util/decoder.h>
#include <openspace/util/factorymanager.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/exception.h>
namespace {
const std::string _loggerCat = "Decoder";
@@ -32,29 +35,22 @@ const std::string _loggerCat = "Decoder";
namespace openspace {
Decoder* Decoder::createFromDictionary(const ghoul::Dictionary& dictionary, const std::string& type)
std::unique_ptr<Decoder> Decoder::createFromDictionary(
const ghoul::Dictionary& dictionary, const std::string& type)
{
ghoul::TemplateFactory<Decoder>* factory
= FactoryManager::ref().factory<Decoder>();
Decoder* result = factory->create(type, dictionary);
if (result == nullptr) {
LERROR("Failed creating Payload object of type '" << type << "'");
return nullptr;
throw ghoul::RuntimeError(
"Failed creating payload object of type '" + type + '"',
"Decoder"
);
}
return result;
return std::unique_ptr<Decoder>(result);
}
Decoder::Decoder()
{
}
Decoder::Decoder(const ghoul::Dictionary& dictionary)
{
}
Decoder::~Decoder()
{
}
Decoder::~Decoder() {}
} // namespace openspace
+7 -4
View File
@@ -26,20 +26,23 @@
#define __DECODER_H__
#include <ghoul/misc/dictionary.h>
#include <openspace/util/updatestructures.h>
#include <memory>
namespace openspace {
class Decoder {
public:
static Decoder* createFromDictionary(const ghoul::Dictionary& dictionary, const std::string& type);
static std::unique_ptr<Decoder> createFromDictionary(
const ghoul::Dictionary& dictionary, const std::string& type);
Decoder(const ghoul::Dictionary& dictionary);
virtual ~Decoder();
virtual std::string getDecoderType() = 0;
virtual std::vector<std::string> getTranslation() = 0;
protected:
Decoder();
Decoder() = default;
};
} // namespace openspace
+3 -3
View File
@@ -75,10 +75,10 @@ HongKangParser::HongKangParser(std::string name, std::string fileName,
ghoul::Dictionary decoderDictionary;
translationDictionary.getValue(currentKey, decoderDictionary);
Decoder* decoder = Decoder::createFromDictionary(decoderDictionary, decoders[i]);
auto decoder = Decoder::createFromDictionary(decoderDictionary, decoders[i]);
//insert decoder to map - this will be used in the parser to determine
//behavioral characteristics of each instrument
_fileTranslation[keys[j]] = decoder;
_fileTranslation[keys[j]] = std::move(decoder);
}
}
//Hong's playbook needs _only_ instrument translation though.
@@ -201,7 +201,7 @@ bool HongKangParser::create() {
if (it->second->getDecoderType() == "SCANNER"){ // SCANNER START
scan_start = time;
InstrumentDecoder* scanner = static_cast<InstrumentDecoder*>(it->second);
InstrumentDecoder* scanner = static_cast<InstrumentDecoder*>(it->second.get());
std::string endNominal = scanner->getStopCommand();
// store current position in file
+1 -2
View File
@@ -46,7 +46,6 @@ public:
bool create() override;
void findPlaybookSpecifiedTarget(std::string line, std::string& target);
virtual std::map<std::string, Decoder*> getTranslation(){ return _fileTranslation; };
private:
double getMetFromET(double et);
@@ -70,7 +69,7 @@ private:
std::string _name;
std::string _fileName;
std::string _spacecraft;
std::map<std::string, Decoder*> _fileTranslation;
std::map<std::string, std::unique_ptr<Decoder>> _fileTranslation;
std::vector<std::string> _potentialTargets;
};
+9 -6
View File
@@ -338,9 +338,9 @@ void ImageSequencer::runSequenceParser(SequenceParser* parser){
bool parserComplete = parser->create();
if (parserComplete){
// get new data
std::map<std::string, Decoder*> translations = parser->getTranslation(); // in1
std::map<std::string, std::unique_ptr<Decoder>>& translations = parser->getTranslation(); // in1
std::map<std::string, ImageSubset> imageData = parser->getSubsetMap(); // in2
std::vector<std::pair<std::string, TimeRange>> instrumentTimes = parser->getIstrumentTimes(); //in3
std::vector<std::pair<std::string, TimeRange>> instrumentTimes = parser->getInstrumentTimes(); //in3
std::vector<std::pair<double, std::string>> targetTimes = parser->getTargetTimes(); //in4
std::vector<double> captureProgression = parser->getCaptureProgression(); //in5
@@ -349,11 +349,14 @@ void ImageSequencer::runSequenceParser(SequenceParser* parser){
LERROR("Missing sequence data");
return;
}
// append data
_fileTranslation.insert(translations.begin(), translations.end());
for (auto it : imageData){
for (auto& it : translations) {
_fileTranslation[it.first] = std::move(it.second);
}
for (auto& it : imageData){
if (_subsetMap.find(it.first) == _subsetMap.end()) {
// if key not exist yet - add sequence data for key (target)
_subsetMap.insert(it);
@@ -404,7 +407,7 @@ void ImageSequencer::runSequenceParser(SequenceParser* parser){
sortData();
// extract payload from _fileTranslation
for (auto t : _fileTranslation){
for (auto& t : _fileTranslation){
if (t.second->getDecoderType() == "CAMERA" ||
t.second->getDecoderType() == "SCANNER"){
std::vector<std::string> spiceIDs = t.second->getTranslation();
+1 -1
View File
@@ -152,7 +152,7 @@ private:
* \see Decoder
* \see (projection mod files)
*/
std::map<std::string, Decoder*> _fileTranslation;
std::map<std::string, std::unique_ptr<Decoder>> _fileTranslation;
/*
* This is the main container of image data. The key is the target name,
@@ -65,7 +65,7 @@ InstrumentTimesParser::InstrumentTimesParser(
for (const auto& instrumentKey : instruments.keys()) {
ghoul::Dictionary instrument = instruments.value<ghoul::Dictionary>(instrumentKey);
ghoul::Dictionary files = instrument.value<ghoul::Dictionary>(KeyInstrumentFiles);
_fileTranslation[instrumentKey] = Decoder::createFromDictionary(instrument, KeyInstrument);
_fileTranslation[instrumentKey] = std::move(Decoder::createFromDictionary(instrument, KeyInstrument));
for (int i = 0; i < files.size(); i++) {
std::string filename = files.value<std::string>(std::to_string(i + 1));
_instrumentFiles[instrumentKey].push_back(filename);
@@ -45,13 +45,7 @@ public:
bool create() override;
//virtual std::map<std::string, Decoder*> getTranslation() override;
// temporary need to figure this out
std::map<std::string, Decoder*> getTranslation(){ return _fileTranslation; };
private:
std::regex _pattern;
std::map<std::string, std::vector<std::string>> _instrumentFiles;
@@ -59,7 +53,7 @@ private:
std::string _name;
std::string _fileName;
std::string _spacecraft;
std::map<std::string, Decoder*> _fileTranslation;
std::map<std::string, std::unique_ptr<Decoder>> _fileTranslation;
std::vector<std::string> _specsOfInterest;
std::string _target;
+46 -39
View File
@@ -22,18 +22,23 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/directory.h>
#include <openspace/util/time.h>
#include <openspace/util/spicemanager.h>
#include <modules/newhorizons/util/labelparser.h>
#include <modules/newhorizons/util/decoder.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/time.h>
#include <ghoul/filesystem/directory.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <fstream>
#include <iterator>
#include <iomanip>
#include <limits>
#include <modules/newhorizons/util/labelparser.h>
namespace {
const std::string _loggerCat = "LabelParser";
@@ -54,24 +59,24 @@ LabelParser::LabelParser(std::string name, std::string fileName,
//get the different instrument types
const std::vector<std::string>& decoders = translationDictionary.keys();
//for each decoder (assuming might have more if hong makes changes)
for (int i = 0; i < decoders.size(); i++){
for (int i = 0; i < decoders.size(); ++i) {
ghoul::Dictionary typeDictionary;
translationDictionary.getValue(decoders[i], typeDictionary);
//create dictionary containing all {playbookKeys , spice IDs}
if (decoders[i] == "Instrument"){
if (decoders[i] == "Instrument") {
//for each playbook call -> create a Decoder object
const std::vector<std::string>& keys = typeDictionary.keys();
for (int j = 0; j < keys.size(); j++){
std::vector<std::string> keys = typeDictionary.keys();
for (int j = 0; j < keys.size(); ++j){
std::string currentKey = decoders[i] + "." + keys[j];
ghoul::Dictionary decoderDictionary;
translationDictionary.getValue(currentKey, decoderDictionary);
ghoul::Dictionary decoderDictionary =
translationDictionary.value<ghoul::Dictionary>(currentKey);
Decoder *decoder = Decoder::createFromDictionary(decoderDictionary, decoders[i]);
auto decoder = Decoder::createFromDictionary(decoderDictionary, decoders[i]);
//insert decoder to map - this will be used in the parser to determine
//behavioral characteristics of each instrument
_fileTranslation[keys[j]] = decoder;
_fileTranslation[keys[j]] = std::move(decoder);
}
}
if (decoders[i] == "Target"){
@@ -91,17 +96,17 @@ LabelParser::LabelParser(std::string name, std::string fileName,
for (int j = 0; j < keys.size(); j++){
ghoul::Dictionary itemDictionary;
convertDictionary.getValue(keys[j], itemDictionary);
Decoder *decoder = Decoder::createFromDictionary(itemDictionary, decoders[i]);
auto decoder = Decoder::createFromDictionary(itemDictionary, decoders[i]);
//insert decoder to map - this will be used in the parser to determine
//behavioral characteristics of each instrument
_fileTranslation[keys[j]] = decoder;
_fileTranslation[keys[j]] = std::move(decoder);
};
}
}
}
std::string LabelParser::decode(std::string line){
for (auto key : _fileTranslation){
for (auto& key : _fileTranslation){
std::size_t value = line.find(key.first);
if (value != std::string::npos){
std::string toTranslate = line.substr(value);
@@ -121,7 +126,7 @@ std::string LabelParser::decode(std::string line){
}
std::string LabelParser::encode(std::string line) {
for (auto key : _fileTranslation) {
for (auto& key : _fileTranslation) {
std::size_t value = line.find(key.first);
if (value != std::string::npos) {
return line.substr(value);
@@ -232,29 +237,31 @@ bool LabelParser::create() {
LINFO("Please make sure input data adheres to format https://pds.jpl.nasa.gov/documents/qs/labels.html");
}
}
if (count == _specsOfInterest.size()){
count = 0;
std::string ext = "jpg";
path.replace(path.begin() + position, path.end(), ext);
bool fileExists = FileSys.fileExists(path);
if (!fileExists) {
ext = "JPG";
path.replace(path.begin() + position, path.end(), ext);
fileExists = FileSys.fileExists(path);
}
if (fileExists) {
Image image;
std::vector<std::string> spiceInstrument;
spiceInstrument.push_back(_instrumentID);
createImage(image, startTime, stopTime, spiceInstrument, _target, path);
_subsetMap[image.target]._subset.push_back(image);
_subsetMap[image.target]._range.include(startTime);
if (count == _specsOfInterest.size()) {
using ghoul::io::TextureReader;
auto extensions = TextureReader::ref().supportedExtensions();
_captureProgression.push_back(startTime);
std::stable_sort(_captureProgression.begin(), _captureProgression.end());
count = 0;
using namespace std::literals;
std::string p = path.substr(0, path.size() - ("lbl"s).size());
for (const std::string& ext : extensions) {
path = p + ext;
if (FileSys.fileExists(path)) {
Image image;
std::vector<std::string> spiceInstrument;
spiceInstrument.push_back(_instrumentID);
createImage(image, startTime, stopTime, spiceInstrument, _target, path);
_subsetMap[image.target]._subset.push_back(image);
_subsetMap[image.target]._range.include(startTime);
_captureProgression.push_back(startTime);
std::stable_sort(_captureProgression.begin(), _captureProgression.end());
break;
}
}
}
} while (!file.eof());
}
+1 -2
View File
@@ -43,7 +43,7 @@ public:
bool create() override;
// temporary need to figure this out
std::map<std::string, Decoder*> getTranslation(){ return _fileTranslation; };
//std::map<std::string, Decoder*> getTranslation() { return _fileTranslation; };
private:
void createImage(Image& image,
@@ -64,7 +64,6 @@ private:
std::string _name;
std::string _fileName;
std::string _spacecraft;
std::map<std::string, Decoder*> _fileTranslation;
std::vector<std::string> _specsOfInterest;
std::string _target;
+332 -55
View File
@@ -33,6 +33,7 @@
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/framebufferobject.h>
#include <ghoul/opengl/textureconversion.h>
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
@@ -42,8 +43,6 @@ namespace {
const std::string keyInstrument = "Instrument.Name";
const std::string keyInstrumentFovy = "Instrument.Fovy";
const std::string keyInstrumentAspect = "Instrument.Aspect";
const std::string keyInstrumentNear = "Instrument.Near";
const std::string keyInstrumentFar = "Instrument.Far";
const std::string keyProjObserver = "Projection.Observer";
const std::string keyProjTarget = "Projection.Target";
@@ -54,6 +53,8 @@ namespace {
const std::string keyTranslation = "DataInputTranslation";
const std::string keyNeedsTextureMapDilation = "Projection.TextureMap";
const std::string keyNeedsShadowing = "Projection.ShadowMap";
const std::string keyTextureMapAspectRatio = "Projection.AspectRatio";
const std::string sequenceTypeImage = "image-sequence";
const std::string sequenceTypePlaybook = "playbook";
@@ -69,25 +70,55 @@ namespace {
namespace openspace {
using ghoul::Dictionary;
using glm::ivec2;
ProjectionComponent::ProjectionComponent()
: properties::PropertyOwner()
, _performProjection("performProjection", "Perform Projections", true)
, _clearAllProjections("clearAllProjections", "Clear Projections", false)
, _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f)
, _textureSize("textureSize", "Texture Size", ivec2(16), ivec2(16), ivec2(32768))
, _applyTextureSize("applyTextureSize", "Apply Texture Size")
, _textureSizeDirty(false)
, _projectionTexture(nullptr)
, _needsTextureMapDilation(false)
{
setName("ProjectionComponent");
_shadowing.isEnabled = false;
_dilation.isEnabled = false;
addProperty(_performProjection);
addProperty(_clearAllProjections);
addProperty(_projectionFading);
addProperty(_textureSize);
addProperty(_applyTextureSize);
_applyTextureSize.onChange([this]() { _textureSizeDirty = true; });
}
bool ProjectionComponent::initialize() {
bool a = generateProjectionLayerTexture();
bool b = auxiliaryRendertarget();
int maxSize = OpenGLCap.max2DTextureSize();
glm::ivec2 size;
if (_projectionTextureAspectRatio > 1.f) {
size.x = maxSize;
size.y = static_cast<int>(maxSize / _projectionTextureAspectRatio);
}
else {
size.x = static_cast<int>(maxSize * _projectionTextureAspectRatio);
size.y = maxSize;
}
_textureSize.setMaxValue(size);
_textureSize = size / 2;
// We only want to use half the resolution per default:
size /= 2;
bool success = generateProjectionLayerTexture(size);
success &= generateDepthTexture(size);
success &= auxiliaryRendertarget();
success &= depthRendertarget();
using std::unique_ptr;
using ghoul::opengl::Texture;
@@ -103,8 +134,7 @@ bool ProjectionComponent::initialize() {
}
_placeholderTexture = std::move(texture);
if (_needsTextureMapDilation) {
if (_dilation.isEnabled) {
_dilation.program = ghoul::opengl::ProgramObject::Build(
"Dilation",
"${MODULE_NEWHORIZONS}/shaders/dilation_vs.glsl",
@@ -139,7 +169,7 @@ bool ProjectionComponent::initialize() {
glBindVertexArray(0);
}
return a && b;
return success;
}
bool ProjectionComponent::deinitialize() {
@@ -147,7 +177,7 @@ bool ProjectionComponent::deinitialize() {
glDeleteFramebuffers(1, &_fboID);
if (_needsTextureMapDilation) {
if (_dilation.isEnabled) {
glDeleteFramebuffers(1, &_dilation.fbo);
glDeleteVertexArrays(1, &_dilation.vao);
glDeleteBuffers(1, &_dilation.vbo);
@@ -170,8 +200,7 @@ bool ProjectionComponent::initializeProjectionSettings(const Dictionary& diction
completeSuccess &= dictionary.getValue(keyProjTarget, _projecteeID);
completeSuccess &= dictionary.getValue(keyInstrumentFovy, _fovy);
completeSuccess &= dictionary.getValue(keyInstrumentAspect, _aspectRatio);
completeSuccess &= dictionary.getValue(keyInstrumentNear, _nearPlane);
completeSuccess &= dictionary.getValue(keyInstrumentFar, _farPlane);
ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile");
std::string a = "NONE";
@@ -195,7 +224,17 @@ bool ProjectionComponent::initializeProjectionSettings(const Dictionary& diction
}
if (dictionary.hasKeyAndValue<bool>(keyNeedsTextureMapDilation)) {
_needsTextureMapDilation = dictionary.value<bool>(keyNeedsTextureMapDilation);
_dilation.isEnabled = dictionary.value<bool>(keyNeedsTextureMapDilation);
}
if (dictionary.hasKeyAndValue<bool>(keyNeedsShadowing)) {
_shadowing.isEnabled = dictionary.value<bool>(keyNeedsShadowing);
}
_projectionTextureAspectRatio = 1.f;
if (dictionary.hasKeyAndValue<double>(keyTextureMapAspectRatio)) {
_projectionTextureAspectRatio =
static_cast<float>(dictionary.value<double>(keyTextureMapAspectRatio));
}
return completeSuccess;
@@ -283,6 +322,190 @@ void ProjectionComponent::imageProjectBegin() {
// keep handle to the current bound FBO
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO);
if (_textureSizeDirty) {
LDEBUG("Changing texture size to " << std::to_string(_textureSize));
// If the texture size has changed, we have to allocate new memory and copy
// the image texture to the new target
using ghoul::opengl::Texture;
using ghoul::opengl::FramebufferObject;
// Make a copy of the old textures
std::unique_ptr<Texture> oldProjectionTexture = std::move(_projectionTexture);
std::unique_ptr<Texture> oldDilationStencil = std::move(_dilation.stencilTexture);
std::unique_ptr<Texture> oldDilationTexture = std::move(_dilation.texture);
std::unique_ptr<Texture> oldDepthTexture = std::move(_shadowing.texture);
// Generate the new textures
generateProjectionLayerTexture(_textureSize);
if (_shadowing.isEnabled) {
generateDepthTexture(_textureSize);
}
auto copyFramebuffers = [](Texture* src, Texture* dst, const std::string& msg) {
glFramebufferTexture(
GL_READ_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
*src,
0
);
GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
if (!FramebufferObject::errorChecking(status).empty()) {
LERROR(
"Read Buffer (" << msg << "): " <<
FramebufferObject::errorChecking(status)
);
}
glFramebufferTexture(
GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
*dst,
0
);
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
if (!FramebufferObject::errorChecking(status).empty()) {
LERROR(
"Draw Buffer (" << msg << "): " <<
FramebufferObject::errorChecking(status)
);
}
glBlitFramebuffer(
0, 0,
src->dimensions().x, src->dimensions().y,
0, 0,
dst->dimensions().x, dst->dimensions().y,
GL_COLOR_BUFFER_BIT,
GL_LINEAR
);
};
auto copyDepthBuffer = [](Texture* src, Texture* dst, const std::string& msg) {
glFramebufferTexture(
GL_READ_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
*src,
0
);
GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
if (!FramebufferObject::errorChecking(status).empty()) {
LERROR(
"Read Buffer (" << msg << "): " <<
FramebufferObject::errorChecking(status)
);
}
glFramebufferTexture(
GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
*dst,
0
);
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
if (!FramebufferObject::errorChecking(status).empty()) {
LERROR(
"Draw Buffer (" << msg << "): " <<
FramebufferObject::errorChecking(status)
);
}
glBlitFramebuffer(
0, 0,
src->dimensions().x, src->dimensions().y,
0, 0,
dst->dimensions().x, dst->dimensions().y,
GL_DEPTH_BUFFER_BIT,
GL_NEAREST
);
};
GLuint fbos[2];
glGenFramebuffers(2, fbos);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);
copyFramebuffers(
oldProjectionTexture.get(),
_projectionTexture.get(),
"Projection"
);
if (_dilation.isEnabled) {
copyFramebuffers(
oldDilationStencil.get(),
_dilation.stencilTexture.get(),
"Dilation Stencil"
);
copyFramebuffers(
oldDilationTexture.get(),
_dilation.texture.get(),
"Dilation Texture"
);
}
if (_shadowing.isEnabled) {
copyDepthBuffer(
oldDepthTexture.get(),
_shadowing.texture.get(),
"Shadowing"
);
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDeleteFramebuffers(2, fbos);
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
*_projectionTexture,
0
);
if (_dilation.isEnabled) {
// We only need the stencil texture if we need to dilate
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT1,
GL_TEXTURE_2D,
*_dilation.stencilTexture,
0
);
glBindFramebuffer(GL_FRAMEBUFFER, _dilation.fbo);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
*_dilation.texture,
0
);
}
if (_shadowing.isEnabled) {
glBindFramebuffer(GL_FRAMEBUFFER, _depthFboID);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D,
*_shadowing.texture,
0
);
}
_textureSizeDirty = false;
}
glGetIntegerv(GL_VIEWPORT, _viewport);
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
@@ -292,14 +515,46 @@ void ProjectionComponent::imageProjectBegin() {
static_cast<GLsizei>(_projectionTexture->height())
);
if (_needsTextureMapDilation) {
if (_dilation.isEnabled) {
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, buffers);
}
}
bool ProjectionComponent::needsShadowMap() const {
return _shadowing.isEnabled;
}
ghoul::opengl::Texture& ProjectionComponent::depthTexture() {
return *_shadowing.texture;
}
void ProjectionComponent::depthMapRenderBegin() {
ghoul_assert(_shadowing.isEnabled, "Shadowing is not enabled");
// keep handle to the current bound FBO
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO);
glGetIntegerv(GL_VIEWPORT, _viewport);
glBindFramebuffer(GL_FRAMEBUFFER, _depthFboID);
glEnable(GL_DEPTH_TEST);
glViewport(
0, 0,
static_cast<GLsizei>(_shadowing.texture->width()),
static_cast<GLsizei>(_shadowing.texture->height())
);
glClear(GL_DEPTH_BUFFER_BIT);
}
void ProjectionComponent::depthMapRenderEnd() {
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO);
glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]);
}
void ProjectionComponent::imageProjectEnd() {
if (_needsTextureMapDilation) {
if (_dilation.isEnabled) {
glBindFramebuffer(GL_FRAMEBUFFER, _dilation.fbo);
glDisable(GL_BLEND);
@@ -328,13 +583,34 @@ void ProjectionComponent::imageProjectEnd() {
}
void ProjectionComponent::update() {
if (_needsTextureMapDilation) {
if (_dilation.program->isDirty()) {
_dilation.program->rebuildFromFile();
}
if (_dilation.isEnabled && _dilation.program->isDirty()) {
_dilation.program->rebuildFromFile();
}
}
bool ProjectionComponent::depthRendertarget() {
GLint defaultFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
// setup FBO
glGenFramebuffers(1, &_depthFboID);
glBindFramebuffer(GL_FRAMEBUFFER, _depthFboID);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D,
*_shadowing.texture,
0);
glDrawBuffer(GL_NONE);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
return false;
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
return true;
}
bool ProjectionComponent::auxiliaryRendertarget() {
bool completeSuccess = true;
@@ -359,7 +635,7 @@ bool ProjectionComponent::auxiliaryRendertarget() {
}
if (_needsTextureMapDilation) {
if (_dilation.isEnabled) {
// We only need the stencil texture if we need to dilate
glFramebufferTexture2D(
GL_FRAMEBUFFER,
@@ -408,32 +684,24 @@ glm::mat4 ProjectionComponent::computeProjectorMatrix(const glm::vec3 loc, glm::
float nearPlane, float farPlane,
glm::vec3& boreSight)
{
//rotate boresight into correct alignment
boreSight = instrumentMatrix*aim;
glm::vec3 uptmp(instrumentMatrix*glm::dvec3(up));
// create view matrix
glm::vec3 e3 = glm::normalize(boreSight);
glm::vec3 e3 = glm::normalize(-boreSight);
glm::vec3 e1 = glm::normalize(glm::cross(uptmp, e3));
glm::vec3 e2 = glm::normalize(glm::cross(e3, e1));
glm::mat4 projViewMatrix = glm::mat4(
e1.x, e2.x, e3.x, 0.f,
e1.y, e2.y, e3.y, 0.f,
e1.z, e2.z, e3.z, 0.f,
-glm::dot(e1, loc), -glm::dot(e2, loc), -glm::dot(e3, loc), 1.f
);
glm::mat4 projViewMatrix = glm::mat4(e1.x, e2.x, e3.x, 0.f,
e1.y, e2.y, e3.y, 0.f,
e1.z, e2.z, e3.z, 0.f,
glm::dot(e1, -loc), glm::dot(e2, -loc), glm::dot(e3, -loc), 1.f);
// create perspective projection matrix
glm::mat4 projProjectionMatrix = glm::perspective(
glm::radians(fieldOfViewY), aspectRatio, nearPlane, farPlane
);
// bias matrix
glm::mat4 projNormalizationMatrix = glm::mat4(
0.5f, 0.f, 0.f, 0.f,
0.f, 0.5f, 0.f, 0.f,
0.f, 0.f, 0.5f, 0.f,
0.5f, 0.5f, 0.5f, 1.f
);
return projNormalizationMatrix * projProjectionMatrix * projViewMatrix;
glm::mat4 projProjectionMatrix = glm::perspective(glm::radians(fieldOfViewY), aspectRatio, nearPlane, farPlane);
return projProjectionMatrix*projViewMatrix;
}
bool ProjectionComponent::doesPerformProjection() const {
@@ -449,7 +717,7 @@ float ProjectionComponent::projectionFading() const {
}
ghoul::opengl::Texture& ProjectionComponent::projectionTexture() const {
if (_needsTextureMapDilation) {
if (_dilation.isEnabled) {
return *_dilation.texture;
}
else {
@@ -481,14 +749,6 @@ float ProjectionComponent::aspectRatio() const {
return _aspectRatio;
}
float ProjectionComponent::nearPlane() const {
return _nearPlane;
}
float ProjectionComponent::farPlane() const {
return _farPlane;
}
void ProjectionComponent::clearAllProjections() {
// keep handle to the current bound FBO
GLint defaultFBO;
@@ -504,7 +764,7 @@ void ProjectionComponent::clearAllProjections() {
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
if (_needsTextureMapDilation) {
if (_dilation.isEnabled) {
glBindFramebuffer(GL_FRAMEBUFFER, _dilation.fbo);
glClear(GL_COLOR_BUFFER_BIT);
}
@@ -543,14 +803,12 @@ std::shared_ptr<ghoul::opengl::Texture> ProjectionComponent::loadProjectionTextu
return std::move(texture);
}
bool ProjectionComponent::generateProjectionLayerTexture() {
int maxSize = OpenGLCap.max2DTextureSize() / 2;
bool ProjectionComponent::generateProjectionLayerTexture(const ivec2& size) {
LINFO(
"Creating projection texture of size '" << maxSize << ", " << maxSize / 2 << "'"
"Creating projection texture of size '" << size.x << ", " << size.y << "'"
);
_projectionTexture = std::make_unique<ghoul::opengl::Texture> (
glm::uvec3(maxSize, maxSize / 2, 1),
glm::uvec3(size, 1),
ghoul::opengl::Texture::Format::RGBA
);
if (_projectionTexture) {
@@ -558,9 +816,9 @@ bool ProjectionComponent::generateProjectionLayerTexture() {
//_projectionTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
}
if (_needsTextureMapDilation) {
if (_dilation.isEnabled) {
_dilation.texture = std::make_unique<ghoul::opengl::Texture>(
glm::uvec3(maxSize, maxSize / 2, 1),
glm::uvec3(size, 1),
ghoul::opengl::Texture::Format::RGBA
);
@@ -570,7 +828,7 @@ bool ProjectionComponent::generateProjectionLayerTexture() {
}
_dilation.stencilTexture = std::make_unique<ghoul::opengl::Texture>(
glm::uvec3(maxSize, maxSize / 2, 1),
glm::uvec3(size, 1),
ghoul::opengl::Texture::Format::Red,
ghoul::opengl::Texture::Format::Red
);
@@ -586,4 +844,23 @@ bool ProjectionComponent::generateProjectionLayerTexture() {
}
bool ProjectionComponent::generateDepthTexture(const ivec2& size) {
LINFO(
"Creating depth texture of size '" << size.x << ", " << size.y << "'"
);
_shadowing.texture = std::make_unique<ghoul::opengl::Texture>(
glm::uvec3(size, 1),
ghoul::opengl::Texture::Format::DepthComponent,
GL_DEPTH_COMPONENT32F
);
if (_shadowing.texture) {
_shadowing.texture->uploadTexture();
}
return _shadowing.texture != nullptr;
}
} // namespace openspace
+26 -7
View File
@@ -27,6 +27,8 @@
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/scalarproperty.h>
#include <openspace/properties/triggerproperty.h>
#include <openspace/properties/vectorproperty.h>
#include <openspace/util/spicemanager.h>
#include <ghoul/misc/dictionary.h>
@@ -54,13 +56,17 @@ public:
bool initializeProjectionSettings(const ghoul::Dictionary& dictionary);
bool initializeParser(const ghoul::Dictionary& dictionary);
ghoul::opengl::Texture& depthTexture();
void imageProjectBegin();
void imageProjectEnd();
void depthMapRenderBegin();
void depthMapRenderEnd();
void update();
bool generateProjectionLayerTexture();
bool auxiliaryRendertarget();
bool depthRendertarget();
std::shared_ptr<ghoul::opengl::Texture> loadProjectionTexture(
const std::string& texturePath,
@@ -81,6 +87,8 @@ public:
bool needsClearProjection() const;
float projectionFading() const;
bool needsShadowMap() const;
void clearAllProjections();
ghoul::opengl::Texture& projectionTexture() const;
@@ -92,18 +100,25 @@ public:
float fieldOfViewY() const;
float aspectRatio() const;
float nearPlane() const;
float farPlane() const;
private:
bool generateProjectionLayerTexture(const glm::ivec2& size);
bool generateDepthTexture(const glm::ivec2& size);
protected:
properties::BoolProperty _performProjection;
properties::BoolProperty _clearAllProjections;
properties::FloatProperty _projectionFading;
std::unique_ptr<ghoul::opengl::Texture> _projectionTexture;
properties::IVec2Property _textureSize;
properties::TriggerProperty _applyTextureSize;
bool _textureSizeDirty;
std::unique_ptr<ghoul::opengl::Texture> _projectionTexture;
std::shared_ptr<ghoul::opengl::Texture> _placeholderTexture;
float _projectionTextureAspectRatio;
std::string _instrumentID;
std::string _projectorID;
std::string _projecteeID;
@@ -111,16 +126,20 @@ protected:
std::vector<std::string> _potentialTargets;
float _fovy;
float _aspectRatio;
float _nearPlane;
float _farPlane;
GLuint _fboID;
GLuint _depthFboID;
GLint _defaultFBO;
GLint _viewport[4];
bool _needsTextureMapDilation;
struct {
bool isEnabled;
std::unique_ptr<ghoul::opengl::Texture> texture;
} _shadowing;
struct {
bool isEnabled;
GLuint fbo;
GLuint vao;
GLuint vbo;
+4 -1
View File
@@ -42,7 +42,7 @@ namespace openspace {
std::map<std::string, ImageSubset> SequenceParser::getSubsetMap(){
return _subsetMap;
}
std::vector<std::pair<std::string, TimeRange>> SequenceParser::getIstrumentTimes(){
std::vector<std::pair<std::string, TimeRange>> SequenceParser::getInstrumentTimes(){
return _instrumentTimes;
}
std::vector<std::pair<double, std::string>> SequenceParser::getTargetTimes(){
@@ -52,6 +52,9 @@ std::vector<double> SequenceParser::getCaptureProgression(){
return _captureProgression;
};
std::map<std::string, std::unique_ptr<Decoder>>& SequenceParser::getTranslation() {
return _fileTranslation;
}
template <typename T>
void writeToBuffer(std::vector<char>& buffer, size_t& currentWriteLocation, T value) {
+7 -4
View File
@@ -28,14 +28,15 @@
#include <openspace/network/networkengine.h>
#include <openspace/util/timerange.h>
#include <modules/newhorizons/util/decoder.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
namespace openspace {
class Decoder;
struct Image {
TimeRange timeRange;
std::string path;
@@ -54,9 +55,9 @@ class SequenceParser {
public:
virtual bool create() = 0;
virtual std::map<std::string, ImageSubset> getSubsetMap() final;
virtual std::vector<std::pair<std::string, TimeRange>> getIstrumentTimes() final;
virtual std::vector<std::pair<std::string, TimeRange>> getInstrumentTimes() final;
virtual std::vector<std::pair<double, std::string>> getTargetTimes() final;
virtual std::map<std::string, Decoder*> getTranslation() = 0;
std::map<std::string, std::unique_ptr<Decoder>>& getTranslation();
virtual std::vector<double> getCaptureProgression() final;
protected:
@@ -67,6 +68,8 @@ protected:
std::vector<std::pair<double, std::string>> _targetTimes;
std::vector<double> _captureProgression;
std::map<std::string, std::unique_ptr<Decoder>> _fileTranslation;
NetworkEngine::MessageIdentifier _messageIdentifier;
};
-1
View File
@@ -24,7 +24,6 @@
#include <modules/toyvolume/toyvolumemodule.h>
#include <openspace/rendering/renderable.h>
#include <openspace/util/factorymanager.h>
#include <ghoul/misc/assert.h>