More work on refactoring RenderablePlanetProjection and RenderableModelProjection

This commit is contained in:
Alexander Bock
2016-06-04 12:04:19 +02:00
parent 491226ea7a
commit 4dda541d1f
6 changed files with 338 additions and 401 deletions

View File

@@ -24,9 +24,6 @@
#include <modules/newhorizons/rendering/renderablemodelprojection.h>
#include <modules/newhorizons/util/imagesequencer.h>
#include <modules/newhorizons/util/labelparser.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/util/spicemanager.h>
@@ -35,7 +32,6 @@
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/textureunit.h>
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
namespace {
const std::string _loggerCat = "RenderableModelProjection";
@@ -47,21 +43,6 @@ namespace {
const std::string keyTextureColor = "Textures.Color";
const std::string keyTextureProject = "Textures.Project";
const std::string keyTextureDefault = "Textures.Default";
const std::string keySequenceDir = "Projection.Sequence";
const std::string keySequenceType = "Projection.SequenceType";
const std::string keyProjObserver = "Projection.Observer";
const std::string keyProjTarget = "Projection.Target";
const std::string keyProjAberration = "Projection.Aberration";
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 keyTranslation = "DataInputTranslation";
const std::string sequenceTypeImage = "image-sequence";
}
namespace openspace {
@@ -69,17 +50,12 @@ namespace openspace {
RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _colorTexturePath("colorTexture", "Color Texture")
, _rotationX("rotationX", "RotationX", 0, 0, 360)
, _rotationY("rotationY", "RotationY", 0, 0, 360)
, _rotationZ("rotationZ", "RotationZ", 0, 0, 360)
, _rotation("rotation", "Rotation", glm::vec3(0.f), glm::vec3(0.f), glm::vec3(360.f))
, _programObject(nullptr)
, _fboProgramObject(nullptr)
, _baseTexture(nullptr)
, _geometry(nullptr)
, _alpha(1.f)
, _performShading("performShading", "Perform Shading", true)
, _frameCount(0)
, _programIsDirty(false)
{
std::string name;
bool success = dictionary.getValue(SceneGraphNode::KeyName, name);
@@ -88,8 +64,11 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di
ghoul::Dictionary geometryDictionary;
success = dictionary.getValue(keyGeometry, geometryDictionary);
if (success) {
using modelgeometry::ModelGeometry;
geometryDictionary.setValue(SceneGraphNode::KeyName, name);
_geometry = std::unique_ptr<modelgeometry::ModelGeometry>(modelgeometry::ModelGeometry::createFromDictionary(geometryDictionary));
_geometry = std::unique_ptr<ModelGeometry>(
ModelGeometry::createFromDictionary(geometryDictionary)
);
}
std::string texturePath = "";
@@ -115,20 +94,7 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di
setBody(_target);
bool completeSuccess = true;
completeSuccess &= dictionary.getValue(keyInstrument, _instrumentID);
completeSuccess &= dictionary.getValue(keyProjObserver, _projectorID);
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";
bool s = dictionary.getValue(keyProjAberration, a);
_aberration = SpiceManager::AberrationCorrection(a);
completeSuccess &= s;
ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile");
completeSuccess &= initializeProjectionSettings(dictionary);
openspace::SpiceManager::ref().addFrame(_target, _source);
setBoundingSphere(pss(1.f, 9.f));
@@ -136,34 +102,10 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di
addProperty(_performShading);
addProperty(_performProjection);
addProperty(_clearAllProjections);
addProperty(_rotationX);
addProperty(_rotationY);
addProperty(_rotationZ);
SequenceParser* parser;
bool foundSequence = dictionary.getValue(keySequenceDir, _sequenceSource);
if (foundSequence) {
_sequenceSource = absPath(_sequenceSource);
foundSequence = dictionary.getValue(keySequenceType, _sequenceType);
ghoul_assert(foundSequence, "Did not find sequence");
//Important: client must define translation-list in mod file IFF playbook
if (dictionary.hasKey(keyTranslation)) {
ghoul::Dictionary translationDictionary;
//get translation dictionary
dictionary.getValue(keyTranslation, translationDictionary);
if (_sequenceType == sequenceTypeImage) {
parser = new LabelParser(name, _sequenceSource, translationDictionary);
openspace::ImageSequencer::ref().runSequenceParser(parser);
}
}
else {
LWARNING("No translation provided, please make sure all spice calls match playbook!");
}
}
addProperty(_rotation);
success = initializeParser(dictionary);
ghoul_assert(success, "");
}
bool RenderableModelProjection::isReady() const {
@@ -177,67 +119,26 @@ bool RenderableModelProjection::isReady() const {
bool RenderableModelProjection::initialize() {
bool completeSuccess = true;
if (_programObject == nullptr) {
RenderEngine& renderEngine = OsEng.renderEngine();
_programObject = renderEngine.buildRenderProgram("ModelShader",
"${MODULE_NEWHORIZONS}/shaders/modelShader_vs.glsl",
"${MODULE_NEWHORIZONS}/shaders/modelShader_fs.glsl");
RenderEngine& renderEngine = OsEng.renderEngine();
_programObject = renderEngine.buildRenderProgram("ModelShader",
"${MODULE_NEWHORIZONS}/shaders/modelShader_vs.glsl",
"${MODULE_NEWHORIZONS}/shaders/modelShader_fs.glsl");
if (!_programObject)
return false;
}
_programObject->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*) { this->_programIsDirty = true; } );
_fboProgramObject = ghoul::opengl::ProgramObject::Build("ProjectionPass",
"${MODULE_NEWHORIZONS}/shaders/projectionPass_vs.glsl",
"${MODULE_NEWHORIZONS}/shaders/projectionPass_fs.glsl");
_fboProgramObject->setIgnoreUniformLocationError(
ghoul::opengl::ProgramObject::IgnoreError::Yes
);
if (_fboProgramObject == nullptr) {
_fboProgramObject = ghoul::opengl::ProgramObject::Build("ProjectionPass",
"${MODULE_NEWHORIZONS}/shaders/projectionPass_vs.glsl",
"${MODULE_NEWHORIZONS}/shaders/projectionPass_fs.glsl");
_fboProgramObject->setIgnoreUniformLocationError(ghoul::opengl::ProgramObject::IgnoreError::Yes);
if (!_fboProgramObject)
return false;
}
_fboProgramObject->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*) { this->_programIsDirty = true; } );
completeSuccess &= loadTextures();
loadTextures();
completeSuccess &= (_baseTexture != nullptr);
completeSuccess &= (_projectionTexture != nullptr);
completeSuccess &= ProjectionComponent::initialize();
completeSuccess &= _geometry->initialize(this);
completeSuccess &= !_source.empty();
completeSuccess &= !_destination.empty();
bool gotverts = _geometry->getVertices(&_geometryVertecies) && _geometry->getIndices(&_geometryIndeces);
if (!gotverts)
LWARNING("Lack of vertex data from geometry for image projection");
completeSuccess &= auxiliaryRendertarget();
int vertexSize = sizeof(modelgeometry::ModelGeometry::Vertex);
glGenVertexArrays(1, &_vaoID);
glGenBuffers(1, &_vbo);
glGenBuffers(1, &_ibo);
glBindVertexArray(_vaoID);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, _geometryVertecies.size() * vertexSize, &_geometryVertecies[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, vertexSize,
reinterpret_cast<const GLvoid*>(offsetof(modelgeometry::ModelGeometry::Vertex, location)));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, vertexSize,
reinterpret_cast<const GLvoid*>(offsetof(modelgeometry::ModelGeometry::Vertex, tex)));
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, vertexSize,
reinterpret_cast<const GLvoid*>(offsetof(modelgeometry::ModelGeometry::Vertex, normal)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _geometryIndeces.size() * sizeof(int), &_geometryIndeces[0], GL_STATIC_DRAW);
glBindVertexArray(0);
return completeSuccess;
}
@@ -248,28 +149,19 @@ bool RenderableModelProjection::deinitialize() {
_geometry = nullptr;
_baseTexture = nullptr;
_projectionTexture = nullptr;
glDeleteBuffers(1, &_vbo);
ProjectionComponent::deinitialize();
RenderEngine& renderEngine = OsEng.renderEngine();
if (_programObject) {
renderEngine.removeRenderProgram(_programObject);
_programObject = nullptr;
}
OsEng.renderEngine().removeRenderProgram(_programObject);
_programObject = nullptr;
return true;
}
void RenderableModelProjection::render(const RenderData& data) {
if (!_programObject)
return;
if (_clearAllProjections)
clearAllProjections();
_frameCount++;
_camScaling = data.camera.scaling();
_up = data.camera.lookUpVector();
@@ -278,21 +170,9 @@ void RenderableModelProjection::render(const RenderData& data) {
_programObject->activate();
attitudeParameters(_time);
_imageTimes.clear();
double time = openspace::Time::ref().currentTime();
bool targetPositionCoverage = openspace::SpiceManager::ref().hasSpkCoverage(_target, time);
if (!targetPositionCoverage) {
int frame = _frameCount % 180;
float fadingFactor = static_cast<float>(sin((frame * M_PI) / 180));
_alpha = 0.5f + fadingFactor * 0.5f;
}
else
_alpha = 1.0f;
_programObject->setUniform("_performShading", _performShading);
_programObject->setUniform("sun_pos", _sunPosition.vec3());
_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
@@ -313,53 +193,49 @@ void RenderableModelProjection::render(const RenderData& data) {
_geometry->render();
// disable shader
_programObject->deactivate();
}
void RenderableModelProjection::update(const UpdateData& data) {
if (_programIsDirty) {
if (_programObject->isDirty())
_programObject->rebuildFromFile();
if (_fboProgramObject->isDirty())
_fboProgramObject->rebuildFromFile();
_programIsDirty = false;
}
_time = data.time;
if (openspace::ImageSequencer::ref().isReady() && _performProjection) {
openspace::ImageSequencer::ref().updateSequencer(_time);
_capture = openspace::ImageSequencer::ref().getImagePaths(_imageTimes, _projecteeID, _instrumentID);
_capture = openspace::ImageSequencer::ref().getImagePaths(
_imageTimes, _projecteeID, _instrumentID
);
}
// set spice-orientation in accordance to timestamp
if (!_source.empty()) {
_stateMatrix = SpiceManager::ref().positionTransformMatrix(_source, _destination, _time);
_stateMatrix = SpiceManager::ref().positionTransformMatrix(
_source, _destination, _time
);
}
double lt;
double lt;
glm::dvec3 p =
openspace::SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", {}, _time, lt);
openspace::SpiceManager::ref().targetPosition(
"SUN", _target, "GALACTIC", {}, _time, lt
);
_sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z);
}
void RenderableModelProjection::imageProjectGPU(std::unique_ptr<ghoul::opengl::Texture> projectionTexture) {
// keep handle to the current bound FBO
GLint defaultFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
GLint m_viewport[4];
glGetIntegerv(GL_VIEWPORT, m_viewport);
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
glViewport(0, 0, static_cast<GLsizei>(_projectionTexture->width()), static_cast<GLsizei>(_projectionTexture->height()));
ProjectionComponent::imageProjectBegin();
_fboProgramObject->activate();
ghoul::opengl::TextureUnit unitFboProject;
unitFboProject.activate();
ghoul::opengl::TextureUnit unitFbo;
unitFbo.activate();
projectionTexture->bind();
_fboProgramObject->setUniform("projectionTexture", unitFboProject);
_fboProgramObject->setUniform("projectionTexture", unitFbo);
_fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix);
_fboProgramObject->setUniform("ModelTransform", _transform);
@@ -367,17 +243,11 @@ void RenderableModelProjection::imageProjectGPU(std::unique_ptr<ghoul::opengl::T
_fboProgramObject->setUniform("boresight", _boresight);
_geometry->setUniforms(*_fboProgramObject);
_geometry->render();
glBindVertexArray(_vaoID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(_geometryIndeces.size()), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
_fboProgramObject->deactivate();
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glViewport(m_viewport[0], m_viewport[1],
m_viewport[2], m_viewport[3]);
ProjectionComponent::imageProjectEnd();
}
void RenderableModelProjection::attitudeParameters(double time) {
@@ -390,10 +260,21 @@ void RenderableModelProjection::attitudeParameters(double time) {
}
_transform = glm::mat4(1);
glm::mat4 rotPropX = glm::rotate(_transform, glm::radians(static_cast<float>(_rotationX)), glm::vec3(1, 0, 0));
glm::mat4 rotPropY = glm::rotate(_transform, glm::radians(static_cast<float>(_rotationY)), glm::vec3(0, 1, 0));
glm::mat4 rotPropZ = glm::rotate(_transform, glm::radians(static_cast<float>(_rotationZ)), glm::vec3(0, 0, 1));
glm::mat4 rotPropX = glm::rotate(
_transform,
glm::radians(static_cast<float>(_rotation.value().x)),
glm::vec3(1, 0, 0)
);
glm::mat4 rotPropY = glm::rotate(
_transform,
glm::radians(static_cast<float>(_rotation.value().y)),
glm::vec3(0, 1, 0)
);
glm::mat4 rotPropZ = glm::rotate(
_transform,
glm::radians(static_cast<float>(_rotation.value().z)),
glm::vec3(0, 0, 1)
);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
@@ -419,32 +300,32 @@ void RenderableModelProjection::attitudeParameters(double time) {
glm::vec3 cpos = position.vec3();
_projectorMatrix = computeProjectorMatrix(cpos, boresight, _up, _instrumentMatrix,
_fovy, _aspectRatio, _nearPlane, _farPlane, _boresight);
_fovy, _aspectRatio, _nearPlane, _farPlane, _boresight
);
}
void RenderableModelProjection::project() {
for (auto img : _imageTimes) {
//std::thread t1(&RenderableModelProjection::attitudeParameters, this, img.startTime);
//t1.join();
attitudeParameters(img.startTime);
//_projectionTexturePath = img.path;
imageProjectGPU(loadProjectionTexture(img.path)); //fbopass
imageProjectGPU(loadProjectionTexture(img.path));
}
_capture = false;
}
void RenderableModelProjection::loadTextures() {
bool RenderableModelProjection::loadTextures() {
_baseTexture = nullptr;
if (_colorTexturePath.value() != "") {
_baseTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)));
_baseTexture = std::move(
ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath))
);
if (_baseTexture) {
LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'");
_baseTexture->uploadTexture();
_baseTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
}
}
generateProjectionLayerTexture();
return _baseTexture != nullptr;
}
} // namespace openspace

View File

@@ -33,7 +33,7 @@
#include <openspace/properties/numericalproperty.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/util/spicemanager.h>
#include <openspace/properties/vectorproperty.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/opengl/programobject.h>
@@ -57,11 +57,8 @@ public:
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
protected:
void loadTextures();
private:
bool loadTextures();
void attitudeParameters(double time);
void imageProjectGPU(std::unique_ptr<ghoul::opengl::Texture> projectionTexture);
@@ -69,9 +66,7 @@ private:
properties::StringProperty _colorTexturePath;
properties::IntProperty _rotationX;
properties::IntProperty _rotationY;
properties::IntProperty _rotationZ;
properties::Vec3Property _rotation;
std::unique_ptr<ghoul::opengl::ProgramObject> _programObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _fboProgramObject;
@@ -80,7 +75,6 @@ private:
std::unique_ptr<modelgeometry::ModelGeometry> _geometry;
float _alpha;
glm::dmat3 _stateMatrix;
glm::dmat3 _instrumentMatrix;
@@ -89,21 +83,6 @@ private:
std::string _destination;
std::string _target;
// sequence loading
std::string _sequenceSource;
std::string _sequenceType;
// projection mod info
std::string _instrumentID;
std::string _projectorID;
std::string _projecteeID;
SpiceManager::AberrationCorrection _aberration;
std::vector<std::string> _potentialTargets;
float _fovy;
float _aspectRatio;
float _nearPlane;
float _farPlane;
// uniforms
glm::vec2 _camScaling;
glm::vec3 _up;
@@ -111,14 +90,7 @@ private:
glm::mat4 _projectorMatrix;
glm::vec3 _boresight;
GLuint _vbo;
GLuint _ibo;
GLuint _vaoID;
std::vector<modelgeometry::ModelGeometry::Vertex> _geometryVertecies;
std::vector<int> _geometryIndeces;
std::vector<Image> _imageTimes;
int _frameCount;
double _time;
bool _capture;
@@ -126,7 +98,6 @@ private:
psc _sunPosition;
properties::BoolProperty _performShading;
bool _programIsDirty;
};
} // namespace openspace

View File

@@ -25,9 +25,6 @@
#include <modules/newhorizons/rendering/renderableplanetprojection.h>
#include <modules/base/rendering/planetgeometry.h>
#include <modules/newhorizons/util/hongkangparser.h>
#include <modules/newhorizons/util/labelparser.h>
#include <modules/newhorizons/util/sequenceparser.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/scene/scenegraphnode.h>
@@ -41,29 +38,13 @@
namespace {
const std::string _loggerCat = "RenderablePlanetProjection";
const std::string keyProjObserver = "Projection.Observer";
const std::string keyProjTarget = "Projection.Target";
const std::string keyProjAberration = "Projection.Aberration";
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 keySequenceDir = "Projection.Sequence";
const std::string keySequenceType = "Projection.SequenceType";
const std::string keyPotentialTargets = "PotentialTargets";
const std::string keyTranslation = "DataInputTranslation";
const std::string keyFrame = "Frame";
const std::string keyGeometry = "Geometry";
const std::string keyShading = "PerformShading";
const std::string keyBody = "Body";
const std::string _mainFrame = "GALACTIC";
const std::string sequenceTypeImage = "image-sequence";
const std::string sequenceTypePlaybook = "playbook";
const std::string sequenceTypeHybrid = "hybrid";
}
namespace openspace {
@@ -100,16 +81,8 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
if (_target != "")
setBody(_target);
bool b1 = dictionary.getValue(keyInstrument, _instrumentID);
bool b2 = dictionary.getValue(keyProjObserver, _projectorID);
bool b3 = dictionary.getValue(keyProjTarget, _projecteeID);
std::string a = "NONE";
bool b4 = dictionary.getValue(keyProjAberration, a);
_aberration = SpiceManager::AberrationCorrection(a);
bool b5 = dictionary.getValue(keyInstrumentFovy, _fovy);
bool b6 = dictionary.getValue(keyInstrumentAspect, _aspectRatio);
bool b7 = dictionary.getValue(keyInstrumentNear, _nearPlane);
bool b8 = dictionary.getValue(keyInstrumentFar, _farPlane);
success = initializeProjectionSettings(dictionary);
ghoul_assert(success, "");
// @TODO copy-n-paste from renderablefov ---abock
ghoul::Dictionary potentialTargets;
@@ -150,93 +123,32 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
addProperty(_projectionFading);
addProperty(_heightExaggeration);
SequenceParser* parser;
// std::string sequenceSource;
bool _foundSequence = dictionary.getValue(keySequenceDir, _sequenceSource);
if (_foundSequence) {
_sequenceSource = absPath(_sequenceSource);
_foundSequence = dictionary.getValue(keySequenceType, _sequenceType);
//Important: client must define translation-list in mod file IFF playbook
if (dictionary.hasKey(keyTranslation)){
ghoul::Dictionary translationDictionary;
//get translation dictionary
dictionary.getValue(keyTranslation, translationDictionary);
if (_sequenceType == sequenceTypePlaybook) {
parser = new HongKangParser(name,
_sequenceSource,
_projectorID,
translationDictionary,
_potentialTargets);
openspace::ImageSequencer::ref().runSequenceParser(parser);
}
else if (_sequenceType == sequenceTypeImage) {
parser = new LabelParser(name,
_sequenceSource,
translationDictionary);
openspace::ImageSequencer::ref().runSequenceParser(parser);
}
else if (_sequenceType == sequenceTypeHybrid) {
//first read labels
parser = new LabelParser(name,
_sequenceSource,
translationDictionary);
openspace::ImageSequencer::ref().runSequenceParser(parser);
std::string _eventFile;
bool foundEventFile = dictionary.getValue("Projection.EventFile", _eventFile);
if (foundEventFile){
//then read playbook
_eventFile = absPath(_eventFile);
parser = new HongKangParser(name,
_eventFile,
_projectorID,
translationDictionary,
_potentialTargets);
openspace::ImageSequencer::ref().runSequenceParser(parser);
}
else{
LWARNING("No eventfile has been provided, please check modfiles");
}
}
}
else{
LWARNING("No playbook translation provided, please make sure all spice calls match playbook!");
}
}
success = initializeParser(dictionary);
ghoul_assert(success, "");
}
RenderablePlanetProjection::~RenderablePlanetProjection() {}
bool RenderablePlanetProjection::initialize() {
bool completeSuccess = true;
if (_programObject == nullptr) {
// projection program
RenderEngine& renderEngine = OsEng.renderEngine();
_programObject = renderEngine.buildRenderProgram("projectiveProgram",
"${MODULE_NEWHORIZONS}/shaders/projectiveTexture_vs.glsl",
"${MODULE_NEWHORIZONS}/shaders/projectiveTexture_fs.glsl"
);
if (!_programObject)
return false;
}
_programObject = OsEng.renderEngine().buildRenderProgram("projectiveProgram",
"${MODULE_NEWHORIZONS}/shaders/projectiveTexture_vs.glsl",
"${MODULE_NEWHORIZONS}/shaders/projectiveTexture_fs.glsl"
);
_fboProgramObject = ghoul::opengl::ProgramObject::Build("fboPassProgram",
"${MODULE_NEWHORIZONS}/shaders/fboPass_vs.glsl",
"${MODULE_NEWHORIZONS}/shaders/fboPass_fs.glsl"
);
loadTextures();
completeSuccess &= (_baseTexture != nullptr);
completeSuccess &= (_projectionTexture != nullptr);
completeSuccess &= loadTextures();
completeSuccess &= ProjectionComponent::initialize();
completeSuccess &= _geometry->initialize(this);
if (completeSuccess) {
completeSuccess &= auxiliaryRendertarget();
//completeSuccess &= auxiliaryRendertarget();
// SCREEN-QUAD
const GLfloat size = 1.f;
const GLfloat w = 1.f;
@@ -266,14 +178,15 @@ bool RenderablePlanetProjection::initialize() {
}
bool RenderablePlanetProjection::deinitialize() {
ProjectionComponent::deinitialize();
_baseTexture = nullptr;
_geometry = nullptr;
RenderEngine& renderEngine = OsEng.renderEngine();
if (_programObject) {
renderEngine.removeRenderProgram(_programObject);
_programObject = nullptr;
}
glDeleteVertexArrays(1, &_quad);
glDeleteBuffers(1, &_vertexPositionBuffer);
OsEng.renderEngine().removeRenderProgram(_programObject);
_programObject = nullptr;
_fboProgramObject = nullptr;
@@ -283,17 +196,11 @@ bool RenderablePlanetProjection::isReady() const {
return _geometry && _programObject && _baseTexture && _projectionTexture;
}
void RenderablePlanetProjection::imageProjectGPU(std::unique_ptr<ghoul::opengl::Texture> projectionTexture) {
// keep handle to the current bound FBO
GLint defaultFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
void RenderablePlanetProjection::imageProjectGPU(
std::unique_ptr<ghoul::opengl::Texture> projectionTexture)
{
imageProjectBegin();
GLint m_viewport[4];
glGetIntegerv(GL_VIEWPORT, m_viewport);
//counter = 0;
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
glViewport(0, 0, static_cast<GLsizei>(_projectionTexture->width()), static_cast<GLsizei>(_projectionTexture->height()));
_fboProgramObject->activate();
ghoul::opengl::TextureUnit unitFbo;
@@ -327,22 +234,33 @@ void RenderablePlanetProjection::imageProjectGPU(std::unique_ptr<ghoul::opengl::
glDrawArrays(GL_TRIANGLES, 0, 6);
_fboProgramObject->deactivate();
//bind back to default
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glViewport(m_viewport[0], m_viewport[1],
m_viewport[2], m_viewport[3]);
imageProjectEnd();
}
void RenderablePlanetProjection::attitudeParameters(double time) {
// precomputations for shader
_stateMatrix = SpiceManager::ref().positionTransformMatrix(_frame, _mainFrame, time);
_instrumentMatrix = SpiceManager::ref().positionTransformMatrix(_instrumentID, _mainFrame, time);
_instrumentMatrix = SpiceManager::ref().positionTransformMatrix(
_instrumentID, _mainFrame, time
);
_transform = glm::mat4(1);
//90 deg rotation w.r.t spice req.
glm::mat4 rot = glm::rotate(_transform, static_cast<float>(M_PI_2), glm::vec3(1, 0, 0));
glm::mat4 roty = glm::rotate(_transform, static_cast<float>(M_PI_2), glm::vec3(0, -1, 0));
glm::mat4 rotProp = glm::rotate(_transform, static_cast<float>(glm::radians(static_cast<float>(_rotation))), glm::vec3(0, 1, 0));
glm::mat4 rot = glm::rotate(
_transform,
static_cast<float>(M_PI_2),
glm::vec3(1, 0, 0)
);
glm::mat4 roty = glm::rotate(
_transform,
static_cast<float>(M_PI_2),
glm::vec3(0, -1, 0)
);
glm::mat4 rotProp = glm::rotate(
_transform,
static_cast<float>(glm::radians(static_cast<float>(_rotation))),
glm::vec3(0, 1, 0)
);
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
@@ -362,7 +280,9 @@ void RenderablePlanetProjection::attitudeParameters(double time) {
}
double lightTime;
glm::dvec3 p = SpiceManager::ref().targetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, lightTime);
glm::dvec3 p = SpiceManager::ref().targetPosition(
_projectorID, _projecteeID, _mainFrame, _aberration, time, lightTime
);
psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z);
//change to KM and add psc camera scaling.
@@ -371,13 +291,11 @@ void RenderablePlanetProjection::attitudeParameters(double time) {
glm::vec3 cpos = position.vec3();
_projectorMatrix = computeProjectorMatrix(cpos, bs, _up, _instrumentMatrix,
_fovy, _aspectRatio, _nearPlane, _farPlane, _boresight);
_fovy, _aspectRatio, _nearPlane, _farPlane, _boresight
);
}
void RenderablePlanetProjection::render(const RenderData& data) {
if (!_programObject)
return;
if (_clearAllProjections)
clearAllProjections();
@@ -431,23 +349,26 @@ void RenderablePlanetProjection::render(const RenderData& data) {
}
void RenderablePlanetProjection::update(const UpdateData& data) {
_time = Time::ref().currentTime();
_capture = false;
if (openspace::ImageSequencer::ref().isReady() && _performProjection){
openspace::ImageSequencer::ref().updateSequencer(_time);
_capture = openspace::ImageSequencer::ref().getImagePaths(_imageTimes, _projecteeID, _instrumentID);
}
if (_fboProgramObject && _fboProgramObject->isDirty()) {
if (_fboProgramObject->isDirty()) {
_fboProgramObject->rebuildFromFile();
}
if (_programObject->isDirty())
_programObject->rebuildFromFile();
_time = Time::ref().currentTime();
_capture = false;
if (openspace::ImageSequencer::ref().isReady() && _performProjection){
openspace::ImageSequencer::ref().updateSequencer(_time);
_capture = openspace::ImageSequencer::ref().getImagePaths(
_imageTimes, _projecteeID, _instrumentID
);
}
}
void RenderablePlanetProjection::loadTextures() {
bool RenderablePlanetProjection::loadTextures() {
using ghoul::opengl::Texture;
_baseTexture = nullptr;
if (_colorTexturePath.value() != "") {
@@ -459,8 +380,6 @@ void RenderablePlanetProjection::loadTextures() {
}
}
generateProjectionLayerTexture();
_heightMapTexture = nullptr;
if (_heightMapTexturePath.value() != "") {
_heightMapTexture = ghoul::io::TextureReader::ref().loadTexture(_heightMapTexturePath);
@@ -470,6 +389,9 @@ void RenderablePlanetProjection::loadTextures() {
_heightMapTexture->setFilter(Texture::FilterMode::Linear);
}
}
return _baseTexture != nullptr;
}
} // namespace openspace

View File

@@ -32,7 +32,6 @@
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/triggerproperty.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/opengl/programobject.h>
@@ -53,13 +52,12 @@ public:
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
ghoul::opengl::Texture* baseTexture() { return _projectionTexture.get(); };
protected:
void loadTextures();
bool loadTextures();
void attitudeParameters(double time);
@@ -81,41 +79,21 @@ private:
std::unique_ptr<planetgeometry::PlanetGeometry> _geometry;
glm::vec2 _camScaling;
glm::vec3 _up;
glm::mat4 _transform;
glm::mat4 _projectorMatrix;
//sequenceloading
std::string _sequenceSource;
std::string _sequenceType;
bool _foundSequence;
// spice
std::string _instrumentID;
std::string _projectorID;
std::string _projecteeID;
SpiceManager::AberrationCorrection _aberration;
std::vector<std::string> _potentialTargets; // @TODO copy-n-paste from renderablefov
float _fovy;
float _aspectRatio;
float _nearPlane;
float _farPlane;
glm::vec2 _camScaling;
glm::vec3 _up;
glm::mat4 _transform;
glm::mat4 _projectorMatrix;
glm::dmat3 _stateMatrix;
glm::dmat3 _instrumentMatrix;
glm::vec3 _boresight;
glm::vec3 _boresight;
double _time;
std::vector<Image> _imageTimes;
int _sequenceID;
std::string _target;
std::string _frame;
std::string _next;
bool _capture;

View File

@@ -24,20 +24,168 @@
#include <modules/newhorizons/util/projectioncomponent.h>
#include <modules/newhorizons/util/hongkangparser.h>
#include <modules/newhorizons/util/imagesequencer.h>
#include <modules/newhorizons/util/labelparser.h>
#include <openspace/scene/scenegraphnode.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/textureconversion.h>
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
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";
const std::string keyProjAberration = "Projection.Aberration";
const std::string keySequenceDir = "Projection.Sequence";
const std::string keySequenceType = "Projection.SequenceType";
const std::string keyTranslation = "DataInputTranslation";
const std::string sequenceTypeImage = "image-sequence";
const std::string sequenceTypePlaybook = "playbook";
const std::string sequenceTypeHybrid = "hybrid";
const std::string _loggerCat = "ProjectionComponent";
}
namespace openspace {
using ghoul::Dictionary;
ProjectionComponent::ProjectionComponent()
: _performProjection("performProjection", "Perform Projections", true)
, _clearAllProjections("clearAllProjections", "Clear Projections", false)
, _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f)
, _projectionTexture(nullptr)
{
{}
bool ProjectionComponent::initialize() {
bool a = generateProjectionLayerTexture();
bool b = auxiliaryRendertarget();
return a && b;
}
bool ProjectionComponent::deinitialize() {
_projectionTexture = nullptr;
glDeleteFramebuffers(1, &_fboID);
return true;
}
bool ProjectionComponent::initializeProjectionSettings(const Dictionary& dictionary) {
bool completeSuccess = true;
completeSuccess &= dictionary.getValue(keyInstrument, _instrumentID);
completeSuccess &= dictionary.getValue(keyProjObserver, _projectorID);
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";
bool s = dictionary.getValue(keyProjAberration, a);
_aberration = SpiceManager::AberrationCorrection(a);
completeSuccess &= s;
ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile");
return completeSuccess;
}
bool ProjectionComponent::initializeParser(const ghoul::Dictionary& dictionary) {
bool completeSuccess = true;
std::string name;
dictionary.getValue(SceneGraphNode::KeyName, name);
SequenceParser* parser;
std::string sequenceSource;
std::string sequenceType;
bool foundSequence = dictionary.getValue(keySequenceDir, sequenceSource);
if (foundSequence) {
sequenceSource = absPath(sequenceSource);
foundSequence = dictionary.getValue(keySequenceType, sequenceType);
//Important: client must define translation-list in mod file IFF playbook
if (dictionary.hasKey(keyTranslation)) {
ghoul::Dictionary translationDictionary;
//get translation dictionary
dictionary.getValue(keyTranslation, translationDictionary);
if (sequenceType == sequenceTypePlaybook) {
parser = new HongKangParser(name,
sequenceSource,
_projectorID,
translationDictionary,
_potentialTargets);
openspace::ImageSequencer::ref().runSequenceParser(parser);
}
else if (sequenceType == sequenceTypeImage) {
parser = new LabelParser(name,
sequenceSource,
translationDictionary);
openspace::ImageSequencer::ref().runSequenceParser(parser);
}
else if (sequenceType == sequenceTypeHybrid) {
//first read labels
parser = new LabelParser(name,
sequenceSource,
translationDictionary);
openspace::ImageSequencer::ref().runSequenceParser(parser);
std::string _eventFile;
bool foundEventFile = dictionary.getValue("Projection.EventFile", _eventFile);
if (foundEventFile) {
//then read playbook
_eventFile = absPath(_eventFile);
parser = new HongKangParser(name,
_eventFile,
_projectorID,
translationDictionary,
_potentialTargets);
openspace::ImageSequencer::ref().runSequenceParser(parser);
}
else {
LWARNING("No eventfile has been provided, please check modfiles");
}
}
}
else {
LWARNING("No playbook translation provided, please make sure all spice calls match playbook!");
}
}
return completeSuccess;
}
void ProjectionComponent::imageProjectBegin() {
// keep handle to the current bound FBO
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO);
glGetIntegerv(GL_VIEWPORT, _viewport);
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
glViewport(
0, 0,
static_cast<GLsizei>(_projectionTexture->width()),
static_cast<GLsizei>(_projectionTexture->height())
);
}
void ProjectionComponent::imageProjectEnd() {
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO);
glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]);
}
bool ProjectionComponent::auxiliaryRendertarget() {
@@ -49,7 +197,13 @@ bool ProjectionComponent::auxiliaryRendertarget() {
// setup FBO
glGenFramebuffers(1, &_fboID);
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_projectionTexture, 0);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
*_projectionTexture,
0
);
// check FBO status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
@@ -60,12 +214,12 @@ bool ProjectionComponent::auxiliaryRendertarget() {
return completeSuccess;
}
glm::mat4 ProjectionComponent::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up,
glm::mat4 ProjectionComponent::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim,
const glm::vec3 up,
const glm::dmat3& instrumentMatrix,
float fieldOfViewY,
float aspectRatio,
float nearPlane,
float farPlane,
float nearPlane, float farPlane,
glm::vec3& boreSight)
{
//rotate boresight into correct alignment
@@ -113,31 +267,39 @@ void ProjectionComponent::clearAllProjections() {
_clearAllProjections = false;
}
std::unique_ptr<ghoul::opengl::Texture> ProjectionComponent::loadProjectionTexture(const std::string& texturePath) {
std::unique_ptr<ghoul::opengl::Texture> texture = ghoul::io::TextureReader::ref().loadTexture(absPath(texturePath));
std::unique_ptr<ghoul::opengl::Texture> ProjectionComponent::loadProjectionTexture(
const std::string& texturePath)
{
using std::unique_ptr;
using ghoul::opengl::Texture;
using ghoul::io::TextureReader;
unique_ptr<Texture> texture = TextureReader::ref().loadTexture(absPath(texturePath));
if (texture) {
ghoul::opengl::convertTextureFormat(ghoul::opengl::Texture::Format::RGB, *texture);
texture->uploadTexture();
// TODO: AnisotropicMipMap crashes on ATI cards ---abock
//_textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder);
texture->setFilter(Texture::FilterMode::Linear);
texture->setWrapping(Texture::WrappingMode::ClampToBorder);
}
return texture;
}
void ProjectionComponent::generateProjectionLayerTexture() {
bool ProjectionComponent::generateProjectionLayerTexture() {
int maxSize = OpenGLCap.max2DTextureSize() / 2;
LINFOC(
"ProjectionComponent",
LINFO(
"Creating projection texture of size '" << maxSize << ", " << maxSize / 2 << "'"
);
_projectionTexture = std::make_unique<ghoul::opengl::Texture> (
glm::uvec3(maxSize, maxSize / 2, 1),
ghoul::opengl::Texture::Format::RGBA
);
_projectionTexture->uploadTexture();
if (_projectionTexture)
_projectionTexture->uploadTexture();
return _projectionTexture != nullptr;
}
} // namespace openspace

View File

@@ -26,7 +26,9 @@
#define __PROJECTIONCOMPONENT_H__
#include <openspace/properties/scalarproperty.h>
#include <openspace/util/spicemanager.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/opengl/texture.h>
namespace openspace {
@@ -36,7 +38,16 @@ public:
ProjectionComponent();
protected:
void generateProjectionLayerTexture();
bool initialize();
bool deinitialize();
bool initializeProjectionSettings(const ghoul::Dictionary& dictionary);
bool initializeParser(const ghoul::Dictionary& dictionary);
void imageProjectBegin();
void imageProjectEnd();
bool generateProjectionLayerTexture();
bool auxiliaryRendertarget();
std::unique_ptr<ghoul::opengl::Texture> loadProjectionTexture(const std::string& texturePath);
@@ -55,13 +66,25 @@ protected:
properties::BoolProperty _performProjection;
properties::BoolProperty _clearAllProjections;
properties::FloatProperty _projectionFading;
std::unique_ptr<ghoul::opengl::Texture> _projectionTexture;
std::string _instrumentID;
std::string _projectorID;
std::string _projecteeID;
SpiceManager::AberrationCorrection _aberration;
std::vector<std::string> _potentialTargets;
float _fovy;
float _aspectRatio;
float _nearPlane;
float _farPlane;
GLuint _fboID;
GLint _defaultFBO;
GLint _viewport[4];
};
} // namespace openspace