Started refactoring RenderableModelProjection and RenderablePlanetProjection to place common code into ProjectionComponent

This commit is contained in:
Alexander Bock
2016-06-03 18:30:16 +02:00
parent 4ef03bb02b
commit 491226ea7a
7 changed files with 255 additions and 247 deletions
+2
View File
@@ -37,6 +37,7 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/util/imagesequencer.h
${CMAKE_CURRENT_SOURCE_DIR}/util/instrumentdecoder.h
${CMAKE_CURRENT_SOURCE_DIR}/util/labelparser.h
${CMAKE_CURRENT_SOURCE_DIR}/util/projectioncomponent.h
${CMAKE_CURRENT_SOURCE_DIR}/util/scannerdecoder.h
${CMAKE_CURRENT_SOURCE_DIR}/util/sequenceparser.h
${CMAKE_CURRENT_SOURCE_DIR}/util/targetdecoder.h
@@ -55,6 +56,7 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/util/imagesequencer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/instrumentdecoder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/labelparser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/projectioncomponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/scannerdecoder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/sequenceparser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/targetdecoder.cpp
@@ -75,13 +75,9 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di
, _programObject(nullptr)
, _fboProgramObject(nullptr)
, _baseTexture(nullptr)
, _projectionTexture(nullptr)
, _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f)
, _geometry(nullptr)
, _alpha(1.f)
, _performShading("performShading", "Perform Shading", true)
, _performProjection("performProjection", "Perform Projections", true)
, _clearAllProjections("clearAllProjections", "Clear Projections", false)
, _frameCount(0)
, _programIsDirty(false)
{
@@ -218,27 +214,6 @@ bool RenderableModelProjection::initialize() {
LWARNING("Lack of vertex data from geometry for image projection");
completeSuccess &= auxiliaryRendertarget();
return completeSuccess;
}
bool RenderableModelProjection::auxiliaryRendertarget() {
bool completeSuccess = true;
// set FBO to texture to project to
GLint defaultFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
glGenFramebuffers(1, &_fboID);
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_projectionTexture, 0);
// check FBO status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
completeSuccess &= false;
// switch back to window-system-provided framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
int vertexSize = sizeof(modelgeometry::ModelGeometry::Vertex);
glGenVertexArrays(1, &_vaoID);
@@ -253,12 +228,12 @@ bool RenderableModelProjection::auxiliaryRendertarget() {
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, vertexSize,
reinterpret_cast<const GLvoid*>(offsetof(modelgeometry::ModelGeometry::Vertex, location)));
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)));
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)));
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);
@@ -286,28 +261,6 @@ bool RenderableModelProjection::deinitialize() {
return true;
}
void RenderableModelProjection::clearAllProjections() {
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()));
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glViewport(m_viewport[0], m_viewport[1],
m_viewport[2], m_viewport[3]);
_clearAllProjections = false;
}
void RenderableModelProjection::render(const RenderData& data) {
if (!_programObject)
return;
@@ -465,34 +418,11 @@ void RenderableModelProjection::attitudeParameters(double time) {
position[3] += (3 + _camScaling[1]);
glm::vec3 cpos = position.vec3();
_projectorMatrix = computeProjectorMatrix(cpos, boresight, _up);
_projectorMatrix = computeProjectorMatrix(cpos, boresight, _up, _instrumentMatrix,
_fovy, _aspectRatio, _nearPlane, _farPlane, _boresight);
}
glm::mat4 RenderableModelProjection::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up) {
//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 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);
// create perspective projection matrix
glm::mat4 projProjectionMatrix = glm::perspective(glm::radians(_fovy), _aspectRatio, _nearPlane, _farPlane);
// bias matrix
glm::mat4 projNormalizationMatrix = glm::mat4(0.5f, 0, 0, 0,
0, 0.5f, 0, 0,
0, 0, 0.5f, 0,
0.5f, 0.5f, 0.5f, 1);
return projNormalizationMatrix*projProjectionMatrix*projViewMatrix;
}
void RenderableModelProjection::project() {
for (auto img : _imageTimes) {
//std::thread t1(&RenderableModelProjection::attitudeParameters, this, img.startTime);
@@ -514,28 +444,7 @@ void RenderableModelProjection::loadTextures() {
_baseTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
}
}
int maxSize = OpenGLCap.max2DTextureSize() / 2;
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();
}
std::unique_ptr<ghoul::opengl::Texture> RenderableModelProjection::loadProjectionTexture(const std::string& texturePath) {
std::unique_ptr<ghoul::opengl::Texture> texture = ghoul::io::TextureReader::ref().loadTexture(absPath(texturePath));
if (texture) {
texture->uploadTexture();
// TODO: AnisotropicMipMap crashes on ATI cards ---abock
//texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder);
}
return texture;
generateProjectionLayerTexture();
}
} // namespace openspace
@@ -26,6 +26,7 @@
#define __RENDERABLEMODELPROJECTION_H__
#include <openspace/rendering/renderable.h>
#include <modules/newhorizons/util/projectioncomponent.h>
#include <modules/base/rendering/modelgeometry.h>
#include <modules/newhorizons/util/imagesequencer.h>
@@ -44,7 +45,7 @@ namespace modelgeometry {
class ModelGeometry;
}
class RenderableModelProjection : public Renderable {
class RenderableModelProjection : public Renderable, private ProjectionComponent {
public:
RenderableModelProjection(const ghoul::Dictionary& dictionary);
@@ -59,20 +60,14 @@ public:
protected:
void loadTextures();
std::unique_ptr<ghoul::opengl::Texture> loadProjectionTexture(const std::string& texturePath);
private:
bool auxiliaryRendertarget();
glm::mat4 computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up);
void attitudeParameters(double time);
void imageProjectGPU(std::unique_ptr<ghoul::opengl::Texture> projectionTexture);
void project();
void clearAllProjections();
properties::StringProperty _colorTexturePath;
properties::BoolProperty _performProjection;
properties::BoolProperty _clearAllProjections;
properties::IntProperty _rotationX;
properties::IntProperty _rotationY;
@@ -82,9 +77,6 @@ private:
std::unique_ptr<ghoul::opengl::ProgramObject> _fboProgramObject;
std::unique_ptr<ghoul::opengl::Texture> _baseTexture;
std::unique_ptr<ghoul::opengl::Texture> _projectionTexture;
properties::FloatProperty _projectionFading;
std::unique_ptr<modelgeometry::ModelGeometry> _geometry;
@@ -119,11 +111,6 @@ private:
glm::mat4 _projectorMatrix;
glm::vec3 _boresight;
// FBO stuff
GLuint _fboID;
GLuint _quad;
GLuint _vertexPositionBuffer;
GLuint _vbo;
GLuint _ibo;
GLuint _vaoID;
@@ -38,7 +38,6 @@
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/textureconversion.h>
#include <ghoul/opengl/textureunit.h>
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
namespace {
const std::string _loggerCat = "RenderablePlanetProjection";
@@ -74,14 +73,10 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
, _colorTexturePath("planetTexture", "RGB Texture")
, _heightMapTexturePath("heightMap", "Heightmap Texture")
, _rotation("rotation", "Rotation", 0, 0, 360)
, _performProjection("performProjection", "Perform Projections", true)
, _clearAllProjections("clearAllProjections", "Clear Projections", false)
, _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f)
, _heightExaggeration("heightExaggeration", "Height Exaggeration", 1.f, 0.f, 100.f)
, _programObject(nullptr)
, _fboProgramObject(nullptr)
, _baseTexture(nullptr)
, _projectionTexture(nullptr)
, _heightMapTexture(nullptr)
, _capture(false)
{
@@ -213,9 +208,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
}
}
RenderablePlanetProjection::~RenderablePlanetProjection() {
deinitialize();
}
RenderablePlanetProjection::~RenderablePlanetProjection() {}
bool RenderablePlanetProjection::initialize() {
bool completeSuccess = true;
@@ -242,52 +235,32 @@ bool RenderablePlanetProjection::initialize() {
completeSuccess &= (_projectionTexture != nullptr);
completeSuccess &= _geometry->initialize(this);
if (completeSuccess)
if (completeSuccess) {
completeSuccess &= auxiliaryRendertarget();
// SCREEN-QUAD
const GLfloat size = 1.f;
const GLfloat w = 1.f;
const GLfloat vertex_data[] = {
-size, -size, 0.f, w, 0.f, 0.f,
size, size, 0.f, w, 1.f, 1.f,
-size, size, 0.f, w, 0.f, 1.f,
-size, -size, 0.f, w, 0.f, 0.f,
size, -size, 0.f, w, 1.f, 0.f,
size, size, 0.f, w, 1.f, 1.f,
};
return completeSuccess;
}
glGenVertexArrays(1, &_quad);
glBindVertexArray(_quad);
glGenBuffers(1, &_vertexPositionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(sizeof(GLfloat) * 4));
bool RenderablePlanetProjection::auxiliaryRendertarget() {
bool completeSuccess = true;
GLint defaultFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
// setup FBO
glGenFramebuffers(1, &_fboID);
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_projectionTexture, 0);
// check FBO status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
completeSuccess &= false;
// switch back to window-system-provided framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
// SCREEN-QUAD
const GLfloat size = 1.f;
const GLfloat w = 1.f;
const GLfloat vertex_data[] = {
-size, -size, 0.f, w, 0.f, 0.f,
size, size, 0.f, w, 1.f, 1.f,
-size, size, 0.f, w, 0.f, 1.f,
-size, -size, 0.f, w, 0.f, 0.f,
size, -size, 0.f, w, 1.f, 0.f,
size, size, 0.f, w, 1.f, 1.f,
};
glGenVertexArrays(1, &_quad);
glBindVertexArray(_quad);
glGenBuffers(1, &_vertexPositionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(sizeof(GLfloat) * 4));
glBindVertexArray(0);
glBindVertexArray(0);
}
return completeSuccess;
}
@@ -360,29 +333,6 @@ void RenderablePlanetProjection::imageProjectGPU(std::unique_ptr<ghoul::opengl::
m_viewport[2], m_viewport[3]);
}
glm::mat4 RenderablePlanetProjection::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up) {
//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 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);
// create perspective projection matrix
glm::mat4 projProjectionMatrix = glm::perspective(glm::radians(_fovy), _aspectRatio, _nearPlane, _farPlane);
// bias matrix
glm::mat4 projNormalizationMatrix = glm::mat4(0.5f, 0, 0, 0,
0, 0.5f, 0, 0,
0, 0, 0.5f, 0,
0.5f, 0.5f, 0.5f, 1);
return projNormalizationMatrix*projProjectionMatrix*projViewMatrix;
}
void RenderablePlanetProjection::attitudeParameters(double time) {
// precomputations for shader
_stateMatrix = SpiceManager::ref().positionTransformMatrix(_frame, _mainFrame, time);
@@ -420,31 +370,8 @@ void RenderablePlanetProjection::attitudeParameters(double time) {
//position[3] += 3;
glm::vec3 cpos = position.vec3();
_projectorMatrix = computeProjectorMatrix(cpos, bs, _up);
}
void RenderablePlanetProjection::clearAllProjections() {
// keep handle to the current bound FBO
GLint defaultFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
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();
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
//bind back to default
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glViewport(m_viewport[0], m_viewport[1],
m_viewport[2], m_viewport[3]);
_clearAllProjections = false;
_projectorMatrix = computeProjectorMatrix(cpos, bs, _up, _instrumentMatrix,
_fovy, _aspectRatio, _nearPlane, _farPlane, _boresight);
}
void RenderablePlanetProjection::render(const RenderData& data) {
@@ -520,19 +447,6 @@ void RenderablePlanetProjection::update(const UpdateData& data) {
_programObject->rebuildFromFile();
}
std::unique_ptr<ghoul::opengl::Texture> RenderablePlanetProjection::loadProjectionTexture(const std::string& texturePath) {
std::unique_ptr<ghoul::opengl::Texture> texture = ghoul::io::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);
}
return texture;
}
void RenderablePlanetProjection::loadTextures() {
using ghoul::opengl::Texture;
_baseTexture = nullptr;
@@ -545,14 +459,7 @@ void RenderablePlanetProjection::loadTextures() {
}
}
int maxSize = OpenGLCap.max2DTextureSize() / 2;
LINFO("Creating projection texture of size '" << maxSize << ", " << maxSize/2 << "'");
_projectionTexture = std::make_unique<Texture>(
glm::uvec3(maxSize, maxSize / 2, 1),
Texture::Format::RGBA
);
_projectionTexture->uploadTexture();
generateProjectionLayerTexture();
_heightMapTexture = nullptr;
if (_heightMapTexturePath.value() != "") {
@@ -26,6 +26,7 @@
#define __RENDERABLEPLANETPROJECTION_H__
#include <openspace/rendering/renderable.h>
#include <modules/newhorizons/util/projectioncomponent.h>
#include <modules/newhorizons/util/imagesequencer.h>
@@ -43,7 +44,7 @@ namespace planetgeometry {
class PlanetGeometry;
}
class RenderablePlanetProjection : public Renderable {
class RenderablePlanetProjection : public Renderable, private ProjectionComponent {
public:
RenderablePlanetProjection(const ghoul::Dictionary& dictionary);
~RenderablePlanetProjection();
@@ -59,12 +60,8 @@ public:
protected:
void loadTextures();
std::unique_ptr<ghoul::opengl::Texture> loadProjectionTexture(const std::string& texturePath);
bool auxiliaryRendertarget();
glm::mat4 computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up);
void attitudeParameters(double time);
void clearAllProjections();
private:
void imageProjectGPU(std::unique_ptr<ghoul::opengl::Texture> projectionTexture);
@@ -73,18 +70,13 @@ private:
properties::StringProperty _heightMapTexturePath;
properties::IntProperty _rotation;
properties::BoolProperty _performProjection;
properties::BoolProperty _clearAllProjections;
std::unique_ptr<ghoul::opengl::ProgramObject> _programObject;
std::unique_ptr<ghoul::opengl::ProgramObject> _fboProgramObject;
std::unique_ptr<ghoul::opengl::Texture> _baseTexture;
std::unique_ptr<ghoul::opengl::Texture> _projectionTexture;
std::unique_ptr<ghoul::opengl::Texture> _heightMapTexture;
properties::FloatProperty _projectionFading;
properties::FloatProperty _heightExaggeration;
std::unique_ptr<planetgeometry::PlanetGeometry> _geometry;
@@ -127,11 +119,10 @@ private:
bool _capture;
// FBO stuff
GLuint _fboID;
GLuint _quad;
GLuint _vertexPositionBuffer;
};
} // namespace openspace
#endif // __RENDERABLEPLANETPROJECTION_H__
#endif // __RENDERABLEPLANETPROJECTION_H__
@@ -0,0 +1,143 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <modules/newhorizons/util/projectioncomponent.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/textureconversion.h>
#include <ghoul/systemcapabilities/openglcapabilitiescomponent.h>
namespace openspace {
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::auxiliaryRendertarget() {
bool completeSuccess = true;
GLint defaultFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
// setup FBO
glGenFramebuffers(1, &_fboID);
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_projectionTexture, 0);
// check FBO status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
completeSuccess &= false;
// switch back to window-system-provided framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
return completeSuccess;
}
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,
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 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);
// 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, 0, 0,
0, 0.5f, 0, 0,
0, 0, 0.5f, 0,
0.5f, 0.5f, 0.5f, 1);
return projNormalizationMatrix*projProjectionMatrix*projViewMatrix;
}
void ProjectionComponent::clearAllProjections() {
// keep handle to the current bound FBO
GLint defaultFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
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()));
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
//bind back to default
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
glViewport(m_viewport[0], m_viewport[1],
m_viewport[2], m_viewport[3]);
_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));
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);
}
return texture;
}
void ProjectionComponent::generateProjectionLayerTexture() {
int maxSize = OpenGLCap.max2DTextureSize() / 2;
LINFOC(
"ProjectionComponent",
"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();
}
} // namespace openspace
@@ -0,0 +1,69 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __PROJECTIONCOMPONENT_H__
#define __PROJECTIONCOMPONENT_H__
#include <openspace/properties/scalarproperty.h>
#include <ghoul/opengl/texture.h>
namespace openspace {
class ProjectionComponent {
public:
ProjectionComponent();
protected:
void generateProjectionLayerTexture();
bool auxiliaryRendertarget();
std::unique_ptr<ghoul::opengl::Texture> loadProjectionTexture(const std::string& texturePath);
glm::mat4 computeProjectorMatrix(
const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up,
const glm::dmat3& instrumentMatrix,
float fieldOfViewY,
float aspectRatio,
float nearPlane,
float farPlane,
glm::vec3& boreSight
);
void clearAllProjections();
properties::BoolProperty _performProjection;
properties::BoolProperty _clearAllProjections;
properties::FloatProperty _projectionFading;
std::unique_ptr<ghoul::opengl::Texture> _projectionTexture;
GLuint _fboID;
};
} // namespace openspace
#endif // __PROJECTIONCOMPONENT_H__