From 0f963ee3b8d69b57c3df47db05234a12e2aec432 Mon Sep 17 00:00:00 2001 From: Sebastian Piwell Date: Wed, 16 Mar 2016 17:27:10 -0400 Subject: [PATCH] Created screenspaceframebuffer --- .../rendering/screenspacerenderable.h | 14 +-- modules/base/CMakeLists.txt | 2 + .../base/rendering/screenspaceframebuffer.cpp | 91 ++++++++++++++ .../base/rendering/screenspaceframebuffer.h | 50 ++++++++ modules/base/rendering/screenspaceimage.cpp | 110 +++++++---------- modules/base/rendering/screenspaceimage.h | 9 +- src/rendering/renderengine.cpp | 11 +- src/rendering/screenspacerenderable.cpp | 112 ++++++++++-------- 8 files changed, 269 insertions(+), 130 deletions(-) create mode 100644 modules/base/rendering/screenspaceframebuffer.cpp create mode 100644 modules/base/rendering/screenspaceframebuffer.h diff --git a/include/openspace/rendering/screenspacerenderable.h b/include/openspace/rendering/screenspacerenderable.h index 4f25fafbe3..7e08404fcd 100644 --- a/include/openspace/rendering/screenspacerenderable.h +++ b/include/openspace/rendering/screenspacerenderable.h @@ -34,7 +34,7 @@ namespace openspace { class ScreenSpaceRenderable : public properties::PropertyOwner { public: - ScreenSpaceRenderable(std::string texturePath); + ScreenSpaceRenderable(); ~ScreenSpaceRenderable(); virtual void render() = 0; @@ -53,16 +53,12 @@ public: pos += v; _sphericalPosition.set(pos); } - // glm::vec3 pos = _position.value(); - // pos += v; - // _position.set(pos); - }; - void toggleFlatScreen(){ - _flatScreen.set(!_flatScreen.value()); }; protected: void createPlane(); + glm::vec2 toEuclidean(glm::vec2 polar, float radius); + glm::vec2 toSpherical(glm::vec2 euclidean); properties::BoolProperty _enabled; properties::BoolProperty _flatScreen; @@ -70,13 +66,15 @@ protected: properties::Vec2Property _sphericalPosition; properties::FloatProperty _depth; properties::FloatProperty _scale; - properties::StringProperty _texturePath; GLuint _quad; GLuint _vertexPositionBuffer; std::unique_ptr _shader; float _radius; bool _useEuclideanCoordinates; + const float _planeDepth = -2.0; + glm::vec2 _originalViewportSize; + }; } // namespace openspace #endif // __SCREENSPACERENDERABLE_H__ \ No newline at end of file diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt index 7c7210e225..4287156849 100644 --- a/modules/base/CMakeLists.txt +++ b/modules/base/CMakeLists.txt @@ -38,6 +38,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrail.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/simplespheregeometry.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/wavefrontgeometry.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimage.h ${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/dynamicephemeris.h ${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/spiceephemeris.h @@ -59,6 +60,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrail.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/simplespheregeometry.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/wavefrontgeometry.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimage.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/dynamicephemeris.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ephemeris/spiceephemeris.cpp diff --git a/modules/base/rendering/screenspaceframebuffer.cpp b/modules/base/rendering/screenspaceframebuffer.cpp new file mode 100644 index 0000000000..76a39b4dcb --- /dev/null +++ b/modules/base/rendering/screenspaceframebuffer.cpp @@ -0,0 +1,91 @@ +/***************************************************************************************** +* * +* 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 +#include +#include +#include +#include + +#include +#include +#include + +namespace openspace { +ScreenSpaceFramebuffer::ScreenSpaceFramebuffer() + :ScreenSpaceRenderable() + ,_framebuffer(nullptr) +{ + _id = id(); + setName("ScreenSpaceFramebuffer" + std::to_string(_id)); + OsEng.gui()._property.registerProperty(&_enabled); + OsEng.gui()._property.registerProperty(&_flatScreen); + OsEng.gui()._property.registerProperty(&_euclideanPosition); + OsEng.gui()._property.registerProperty(&_sphericalPosition); + OsEng.gui()._property.registerProperty(&_depth); + OsEng.gui()._property.registerProperty(&_scale); + + if(_useEuclideanCoordinates){ + _euclideanPosition.onChange([this](){ + _sphericalPosition.set(toSpherical(_euclideanPosition.value())); + }); + _sphericalPosition.onChange([this](){}); + }else{ + _euclideanPosition.onChange([this](){ + _sphericalPosition.set(toSpherical(_euclideanPosition.value())); + }); + } +} + +ScreenSpaceFramebuffer::~ScreenSpaceFramebuffer(){} + +bool ScreenSpaceFramebuffer::initialize(){ + _framebuffer = std::make_unique(); + ghoul::opengl::Texture texture = ghoul::opengl::Texture(glm::uvec3(512, 512, 10)); + _framebuffer->attachTexture(&texture, GL_COLOR_ATTACHMENT0); + return true; +} + +bool ScreenSpaceFramebuffer::deinitialize(){ + return true; +} + +void ScreenSpaceFramebuffer::render(){ + GLint defaultFBO = _framebuffer->getActiveObject(); + _framebuffer->activate(); + // _shader->activate(); + + + // _shader->deactivate(); + _framebuffer->deactivate(); + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); +} + +void ScreenSpaceFramebuffer::update(){} +bool ScreenSpaceFramebuffer::isReady() const {} + +int ScreenSpaceFramebuffer::id(){ + static int id = 0; + return id++; +} +} //namespace openspace \ No newline at end of file diff --git a/modules/base/rendering/screenspaceframebuffer.h b/modules/base/rendering/screenspaceframebuffer.h new file mode 100644 index 0000000000..74f8e59e21 --- /dev/null +++ b/modules/base/rendering/screenspaceframebuffer.h @@ -0,0 +1,50 @@ +/***************************************************************************************** +* * +* 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 __SCREENSPACEFRAMEBUFFER_H__ +#define __SCREENSPACEFRAMEBUFFER_H__ + +#include +#include + +namespace openspace { +class ScreenSpaceFramebuffer : public ScreenSpaceRenderable { +public: + ScreenSpaceFramebuffer(); + ~ScreenSpaceFramebuffer(); + + bool initialize() override; + bool deinitialize() override; + void render() override; + void update() override; + bool isReady() const override; + +private: + static int id(); + + std::unique_ptr _framebuffer; + int _id; +}; + +} //namespace openspace +#endif //__SCREENSPACEFRAMEBUFFER_H__ \ No newline at end of file diff --git a/modules/base/rendering/screenspaceimage.cpp b/modules/base/rendering/screenspaceimage.cpp index ab3050c230..c67b8953d5 100644 --- a/modules/base/rendering/screenspaceimage.cpp +++ b/modules/base/rendering/screenspaceimage.cpp @@ -30,41 +30,43 @@ #include #include #include +#include namespace openspace { ScreenSpaceImage::ScreenSpaceImage(std::string texturePath) - :ScreenSpaceRenderable(texturePath) - { - _id = id(); - setName("ScreenSpaceImage" + std::to_string(_id)); - OsEng.gui()._property.registerProperty(&_enabled); - OsEng.gui()._property.registerProperty(&_flatScreen); - OsEng.gui()._property.registerProperty(&_euclideanPosition); - OsEng.gui()._property.registerProperty(&_sphericalPosition); - OsEng.gui()._property.registerProperty(&_depth); - OsEng.gui()._property.registerProperty(&_scale); - OsEng.gui()._property.registerProperty(&_texturePath); + :ScreenSpaceRenderable() + ,_texturePath("texturePath", "Texture path", texturePath) +{ + addProperty(_texturePath); - _texturePath.onChange([this](){ loadTexture(); }); + _id = id(); + setName("ScreenSpaceImage" + std::to_string(_id)); + OsEng.gui()._property.registerProperty(&_enabled); + OsEng.gui()._property.registerProperty(&_flatScreen); + OsEng.gui()._property.registerProperty(&_euclideanPosition); + OsEng.gui()._property.registerProperty(&_sphericalPosition); + OsEng.gui()._property.registerProperty(&_depth); + OsEng.gui()._property.registerProperty(&_scale); + OsEng.gui()._property.registerProperty(&_texturePath); - if(_useEuclideanCoordinates){ - _euclideanPosition.onChange([this](){ - _sphericalPosition.set(toSpherical(_euclideanPosition.value())); - }); - _sphericalPosition.onChange([this](){}); - }else{ - _euclideanPosition.onChange([this](){ - _sphericalPosition.set(toSpherical(_euclideanPosition.value())); - }); - } - // _flatScreen.onChange([this](){ _useEuclideanCoordinates = _flatScreen.value(); }); + _texturePath.onChange([this](){ loadTexture(); }); + + if(_useEuclideanCoordinates){ + _euclideanPosition.onChange([this](){ + _sphericalPosition.set(toSpherical(_euclideanPosition.value())); + }); + _sphericalPosition.onChange([this](){}); + }else{ + _euclideanPosition.onChange([this](){ + _sphericalPosition.set(toSpherical(_euclideanPosition.value())); + }); } +} ScreenSpaceImage::~ScreenSpaceImage(){} void ScreenSpaceImage::render(){ - GLfloat m_viewport[4]; glGetFloatv(GL_VIEWPORT, m_viewport); @@ -75,16 +77,14 @@ void ScreenSpaceImage::render(){ float scalingRatioX = m_viewport[2] / _originalViewportSize[0]; float scalingRatioY = m_viewport[3] / _originalViewportSize[1]; - float occlusionDepth = 1-_depth.value(); - glm::mat4 modelTransform; if(!_useEuclideanCoordinates){ glm::vec2 position = _sphericalPosition.value(); float phi = position.y - M_PI/2.0; + glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), position.x, glm::vec3(0.0f, 1.0f, 0.0f)); rotation = glm::rotate(rotation, phi , glm::vec3(1.0f, 0.0f, 0.0f)); glm::mat4 translate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, _planeDepth)); - modelTransform = rotation * translate; } else { glm::vec2 position = _euclideanPosition.value(); @@ -92,6 +92,7 @@ void ScreenSpaceImage::render(){ } modelTransform = glm::scale(modelTransform, glm::vec3(_scale.value()*scalingRatioY, _scale.value()*textureRatio*scalingRatioX, 1)); + float occlusionDepth = 1-_depth.value(); glEnable(GL_DEPTH_TEST); _shader->activate(); @@ -130,9 +131,27 @@ bool ScreenSpaceImage::initialize(){ return isReady(); } + bool ScreenSpaceImage::deinitialize(){ + glDeleteVertexArrays(1, &_quad); + _quad = 0; + + glDeleteBuffers(1, &_vertexPositionBuffer); + _vertexPositionBuffer = 0; + + + _texturePath = ""; + _texture = nullptr; + + RenderEngine& renderEngine = OsEng.renderEngine(); + if (_shader) { + renderEngine.removeRenderProgram(_shader); + _shader = nullptr; + } + return true; } + void ScreenSpaceImage::update(){ if(_flatScreen.value() != _useEuclideanCoordinates){ _useEuclideanCoordinates = _flatScreen.value(); @@ -154,39 +173,6 @@ void ScreenSpaceImage::update(){ } } -glm::vec2 ScreenSpaceImage::toEuclidean(glm::vec2 polar, float r){ - float x = r*sin(polar[0])*sin(polar[1]); - float y = r*cos(polar[1]); - float z = _planeDepth; - return glm::vec2(x, y); -} - -glm::vec2 ScreenSpaceImage::toSpherical(glm::vec2 euclidean){ - _radius = -sqrt(pow(euclidean[0],2)+pow(euclidean[1],2)+pow(_planeDepth,2)); - float theta = atan2(-_planeDepth,euclidean[0])-M_PI/2.0; - float phi = acos(euclidean[1]/_radius); - - while(phi>=M_PI){ - phi -= M_PI; - } - - if(!_radius){ - phi = 0; - } - - while(theta <= -M_PI){ - theta += 2.0*M_PI; - } - - while(theta >= M_PI) { - theta -= 2.0*M_PI; - } - - // std::cout << euclidean[2] << " " << r - return glm::vec2(theta, phi); -} - - bool ScreenSpaceImage::isReady() const{ bool ready = true; if (!_shader) @@ -207,10 +193,6 @@ void ScreenSpaceImage::loadTexture() { texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); _texture = std::move(texture); - - // delete _textureFile; - // _textureFile = new ghoul::filesystem::File(_texturePath); - // _textureFile->setCallback([&](const ghoul::filesystem::File&) { _textureIsDirty = true; }); } } } diff --git a/modules/base/rendering/screenspaceimage.h b/modules/base/rendering/screenspaceimage.h index c65042684b..7ccea78e5b 100644 --- a/modules/base/rendering/screenspaceimage.h +++ b/modules/base/rendering/screenspaceimage.h @@ -26,6 +26,7 @@ #include #include + namespace openspace { class ScreenSpaceImage : public ScreenSpaceRenderable { @@ -41,16 +42,12 @@ public: bool isReady() const override; private: void loadTexture(); - glm::vec2 toEuclidean(glm::vec2 polar, float radius); - glm::vec2 toSpherical(glm::vec2 euclidean); static int id(); + properties::StringProperty _texturePath; std::unique_ptr _texture; // The image to render - glm::vec2 _originalViewportSize; - const float _planeDepth = -2.0; - bool _isFlatScreen = true; int _id; }; -// int ScreenSpaceImage::id = 0; + } //namespace openspace #endif //__SCREENSPACEIMAGE_H__ \ No newline at end of file diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index c4731af940..31c424b847 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -207,7 +208,9 @@ bool RenderEngine::initialize() { ghoul::io::TextureReader::ref().addReader(std::make_shared()); ssr = std::make_shared("${OPENSPACE_DATA}/test2.jpg"); registerScreenSpaceRenderable(ssr); - registerScreenSpaceRenderable(std::make_shared("${OPENSPACE_DATA}/test3.jpg")); + // registerScreenSpaceRenderable(std::make_shared("${OPENSPACE_DATA}/test3.jpg")); + registerScreenSpaceRenderable(std::make_shared()); + return true; } @@ -397,9 +400,9 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi } } - for (auto s : _screenSpaceRenderables) { - if(s->isEnabled()) - s->render(); + for (auto screenSpaceRenderable : _screenSpaceRenderables) { + if(screenSpaceRenderable->isEnabled()) + screenSpaceRenderable->render(); } } diff --git a/src/rendering/screenspacerenderable.cpp b/src/rendering/screenspacerenderable.cpp index 883a76702d..d617f3d60d 100644 --- a/src/rendering/screenspacerenderable.cpp +++ b/src/rendering/screenspacerenderable.cpp @@ -25,57 +25,73 @@ #include namespace openspace { - ScreenSpaceRenderable::ScreenSpaceRenderable(std::string texturePath) - : _enabled("enabled", "Is Enabled", true) - , _flatScreen("flatScreen", "Flat Screen", true) - , _euclideanPosition("euclideanPosition", "Euclidean coordinates", glm::vec2(0),glm::vec2(-4),glm::vec2(4)) - , _sphericalPosition("sphericalPosition", "Spherical coordinates", glm::vec2(0),glm::vec2(-M_PI),glm::vec2(M_PI)) - , _depth("depth", "Depth", 0, 0, 1) - , _scale("scale", "Scale" , 0.5, 0, 1) - , _texturePath("texturePath", "Texture path", texturePath) - , _quad(0) - , _vertexPositionBuffer(0) - ,_shader(nullptr) - ,_radius(-.2f) +ScreenSpaceRenderable::ScreenSpaceRenderable() + : _enabled("enabled", "Is Enabled", true) + , _flatScreen("flatScreen", "Flat Screen", true) + , _euclideanPosition("euclideanPosition", "Euclidean coordinates", glm::vec2(0),glm::vec2(-4),glm::vec2(4)) + , _sphericalPosition("sphericalPosition", "Spherical coordinates", glm::vec2(0),glm::vec2(-M_PI),glm::vec2(M_PI)) + , _depth("depth", "Depth", 0, 0, 1) + , _scale("scale", "Scale" , 0.5, 0, 1) + // , _texturePath("texturePath", "Texture path", texturePath) + , _quad(0) + , _vertexPositionBuffer(0) + ,_shader(nullptr) + ,_radius(-.2f) - { - addProperty(_enabled); - addProperty(_flatScreen); - addProperty(_euclideanPosition); - addProperty(_sphericalPosition); - addProperty(_depth); - addProperty(_scale); - addProperty(_texturePath); +{ + addProperty(_enabled); + addProperty(_flatScreen); + addProperty(_euclideanPosition); + addProperty(_sphericalPosition); + addProperty(_depth); + addProperty(_scale); + // addProperty(_texturePath); - _useEuclideanCoordinates = _flatScreen.value(); - } + _useEuclideanCoordinates = _flatScreen.value(); +} - ScreenSpaceRenderable::~ScreenSpaceRenderable(){} +ScreenSpaceRenderable::~ScreenSpaceRenderable(){} - bool ScreenSpaceRenderable::isEnabled() const { - return _enabled; - } +bool ScreenSpaceRenderable::isEnabled() const { + return _enabled; +} - void ScreenSpaceRenderable::createPlane() { - // ============================ - // GEOMETRY (quad) - // ============================ - const GLfloat vertex_data[] = { // square of two triangles (sigh) - // x y z w s t - -1, -1, 0.0f, 1, 0, 1, - 1, 1, 0.0f, 1, 1, 0, - -1, 1, 0.0f, 1, 0, 0, - -1, -1, 0.0f, 1, 0, 1, - 1, -1, 0.0f, 1, 1, 1, - 1, 1, 0.0f, 1, 1, 0, - }; +void ScreenSpaceRenderable::createPlane() { + // ============================ + // GEOMETRY (quad) + // ============================ + const GLfloat vertex_data[] = { // square of two triangles (sigh) + // x y z w s t + -1, -1, 0.0f, 1, 0, 1, + 1, 1, 0.0f, 1, 1, 0, + -1, 1, 0.0f, 1, 0, 0, + -1, -1, 0.0f, 1, 0, 1, + 1, -1, 0.0f, 1, 1, 1, + 1, 1, 0.0f, 1, 1, 0, + }; - glBindVertexArray(_quad); // bind array - glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); // bind buffer - 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(0)); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(sizeof(GLfloat) * 4)); - } -} \ No newline at end of file + glBindVertexArray(_quad); // bind array + glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); // bind buffer + 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(0)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(sizeof(GLfloat) * 4)); +} + +glm::vec2 ScreenSpaceRenderable::toEuclidean(glm::vec2 polar, float r){ + float x = r*sin(polar[0])*sin(polar[1]); + float y = r*cos(polar[1]); + + return glm::vec2(x, y); +} + +glm::vec2 ScreenSpaceRenderable::toSpherical(glm::vec2 euclidean){ + _radius = -sqrt(pow(euclidean[0],2)+pow(euclidean[1],2)+pow(_planeDepth,2)); + float theta = atan2(-_planeDepth,euclidean[0])-M_PI/2.0; + float phi = acos(euclidean[1]/_radius); + + return glm::vec2(theta, phi); +} + +}// namespace openspace \ No newline at end of file