diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 851dcf84ca..927c434977 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -146,11 +146,12 @@ public: } _onScreenInformation; std::shared_ptr ssr; + void renderInformation(); //MOVE BACK TO PRIVATE + private: void setRenderer(std::unique_ptr renderer); RendererImplementation rendererFromString(const std::string& method); void storePerformanceMeasurements(); - void renderInformation(); void renderScreenLog(); Camera* _mainCamera; diff --git a/include/openspace/rendering/screenspacerenderable.h b/include/openspace/rendering/screenspacerenderable.h index 86b6b44128..2bc0c3f3a5 100644 --- a/include/openspace/rendering/screenspacerenderable.h +++ b/include/openspace/rendering/screenspacerenderable.h @@ -30,6 +30,12 @@ #include #include #include +#include +#include +#include +#include +#include + #include #ifdef WIN32 #define _USE_MATH_DEFINES @@ -63,8 +69,15 @@ public: protected: void createPlane(); + void useEuclideanCoordinates(bool b); glm::vec2 toEuclidean(glm::vec2 polar, float radius); glm::vec2 toSpherical(glm::vec2 euclidean); + void registerProperties(); + void createShaders(); + glm::mat4 scaleMatrix(); + glm::mat4 rotationMatrix(); + glm::mat4 translationMatrix(); + void draw(glm::mat4 modelTransform); properties::BoolProperty _enabled; properties::BoolProperty _useFlatScreen; @@ -73,17 +86,21 @@ protected: properties::FloatProperty _depth; properties::FloatProperty _scale; + GLuint _quad; GLuint _vertexPositionBuffer; const std::string _rendererPath; ghoul::Dictionary _rendererData; + const std::string _vertexPath; + const std::string _fragmentPath; + std::unique_ptr _texture; std::unique_ptr _shader; - float _radius; bool _useEuclideanCoordinates; const float _planeDepth = -2.0; glm::vec2 _originalViewportSize; - + + float _radius; }; } // namespace openspace #endif // __SCREENSPACERENDERABLE_H__ \ No newline at end of file diff --git a/modules/base/rendering/screenspaceframebuffer.cpp b/modules/base/rendering/screenspaceframebuffer.cpp index cc842e7f8f..c327e1f352 100644 --- a/modules/base/rendering/screenspaceframebuffer.cpp +++ b/modules/base/rendering/screenspaceframebuffer.cpp @@ -38,54 +38,107 @@ ScreenSpaceFramebuffer::ScreenSpaceFramebuffer() { _id = id(); setName("ScreenSpaceFramebuffer" + std::to_string(_id)); - OsEng.gui()._property.registerProperty(&_enabled); - OsEng.gui()._property.registerProperty(&_useFlatScreen); - 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())); - }); - } + registerProperties(); } 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; + _originalViewportSize = OsEng.windowWrapper().currentWindowResolution(); + + createPlane(); + createShaders(); + + createFragmentbuffer(); + + // Setting spherical/euclidean onchange handler + _useFlatScreen.onChange([this](){ + useEuclideanCoordinates(_useFlatScreen.value()); + }); + + //for testing + _ssi = std::make_shared("${OPENSPACE_DATA}/test3.jpg"); + OsEng.renderEngine().registerScreenSpaceRenderable(_ssi); + return isReady(); } bool ScreenSpaceFramebuffer::deinitialize(){ + glDeleteVertexArrays(1, &_quad); + _quad = 0; + + glDeleteBuffers(1, &_vertexPositionBuffer); + _vertexPositionBuffer = 0; + + _texture = nullptr; + + RenderEngine& renderEngine = OsEng.renderEngine(); + if (_shader) { + renderEngine.removeRenderProgram(_shader); + _shader = nullptr; + } + + _framebuffer->detachAll(); + return true; } void ScreenSpaceFramebuffer::render(){ + glViewport (0, 0, _originalViewportSize.x, _originalViewportSize.y); GLint defaultFBO = _framebuffer->getActiveObject(); _framebuffer->activate(); - // _shader->activate(); - - - // _shader->deactivate(); + glClearColor (0.0f, 0.0f, 0.0f, 0.0f); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // test functions ------------------------------- + _ssi->render(); + // OsEng.renderEngine().renderer()->render(1,false); + OsEng.renderEngine().renderInformation(); + //----------------------------------------------- _framebuffer->deactivate(); + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + glm::vec2 resolution = OsEng.windowWrapper().currentWindowResolution(); + glViewport (0, 0, resolution.x, resolution.y); + + glm::mat4 rotation = rotationMatrix(); + glm::mat4 translation = translationMatrix(); + glm::mat4 scale = scaleMatrix(); + scale = glm::scale(scale, glm::vec3(1.0f, -1.0f, 1.0f)); + glm::mat4 modelTransform = rotation*translation*scale; + draw(modelTransform); } void ScreenSpaceFramebuffer::update(){} -bool ScreenSpaceFramebuffer::isReady() const {} + +bool ScreenSpaceFramebuffer::isReady() const{ + bool ready = true; + if (!_shader) + ready &= false; + if(!_texture) + ready &= false; + return ready; +} int ScreenSpaceFramebuffer::id(){ static int id = 0; return id++; } + +void ScreenSpaceFramebuffer::createFragmentbuffer(){ + _framebuffer = std::make_unique(); + _framebuffer->activate(); + _texture = std::make_unique(glm::uvec3(_originalViewportSize.x, _originalViewportSize.y, 1)); + _texture->uploadTexture(); + _texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + _framebuffer->attachTexture(_texture.get(), GL_COLOR_ATTACHMENT0); + _framebuffer->deactivate(); + + // GLuint depthrenderbuffer; + // glGenRenderbuffers(1, &depthrenderbuffer); + // glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer); + // glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, _originalViewportSize.x, _originalViewportSize.y); + // glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer); + + // GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; + // glDrawBuffers(1, DrawBuffers); +} } //namespace openspace \ No newline at end of file diff --git a/modules/base/rendering/screenspaceframebuffer.h b/modules/base/rendering/screenspaceframebuffer.h index 74f8e59e21..e2e9474a19 100644 --- a/modules/base/rendering/screenspaceframebuffer.h +++ b/modules/base/rendering/screenspaceframebuffer.h @@ -26,6 +26,9 @@ #include #include +#include + +#include namespace openspace { class ScreenSpaceFramebuffer : public ScreenSpaceRenderable { @@ -40,10 +43,13 @@ public: bool isReady() const override; private: + void createFragmentbuffer(); static int id(); std::unique_ptr _framebuffer; int _id; + + std::shared_ptr _ssi; //for testing }; } //namespace openspace diff --git a/modules/base/rendering/screenspaceimage.cpp b/modules/base/rendering/screenspaceimage.cpp index 4a47531ed9..800fcc24fb 100644 --- a/modules/base/rendering/screenspaceimage.cpp +++ b/modules/base/rendering/screenspaceimage.cpp @@ -24,115 +24,31 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include namespace openspace { ScreenSpaceImage::ScreenSpaceImage(std::string texturePath) :ScreenSpaceRenderable() ,_texturePath("texturePath", "Texture path", texturePath) - , _vertexPath("${MODULE_BASE}/shaders/screnspace_vs.glsl") - , _fragmentPath("${MODULE_BASE}/shaders/screnspace_fs.glsl") -{ - addProperty(_texturePath); +{ _id = id(); setName("ScreenSpaceImage" + std::to_string(_id)); - OsEng.gui()._property.registerProperty(&_enabled); - OsEng.gui()._property.registerProperty(&_useFlatScreen); - OsEng.gui()._property.registerProperty(&_euclideanPosition); - OsEng.gui()._property.registerProperty(&_sphericalPosition); - OsEng.gui()._property.registerProperty(&_depth); - OsEng.gui()._property.registerProperty(&_scale); + + addProperty(_texturePath); + registerProperties(); OsEng.gui()._property.registerProperty(&_texturePath); - + _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(){ - glm::vec2 resolution = OsEng.windowWrapper().currentWindowResolution(); - //to scale the plane - float textureRatio = (float(_texture->height())/float(_texture->width())); - - //to keep the texture ratio after viewport is distorted. - float scalingRatioX = resolution[0] / _originalViewportSize[0]; - float scalingRatioY = resolution[1] / _originalViewportSize[1]; - - 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(); - modelTransform = glm::translate(glm::mat4(1.f), glm::vec3(position, _planeDepth)); - } - - 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(); - _shader->setUniform("OcclusionDepth", occlusionDepth); - _shader->setUniform("ModelTransform",modelTransform); - _shader->setUniform("ViewProjectionMatrix", OsEng.renderEngine().camera()->viewProjectionMatrix()); - ghoul::opengl::TextureUnit unit; - unit.activate(); - _texture->bind(); - _shader->setUniform("texture1", unit); - - glBindVertexArray(_quad); - glDrawArrays(GL_TRIANGLES, 0, 6); - - _shader->deactivate(); -} - bool ScreenSpaceImage::initialize(){ - glGenVertexArrays(1, &_quad); // generate array - glGenBuffers(1, &_vertexPositionBuffer); // generate buffer - createPlane(); - - if(_shader == nullptr) { - - ghoul::Dictionary dict = ghoul::Dictionary(); - - dict.setValue("rendererData", _rendererData); - dict.setValue("fragmentPath", _fragmentPath); - _shader = ghoul::opengl::ProgramObject::Build("ScreenSpaceProgram", - _vertexPath, - "${SHADERS}/render.frag", - dict - ); - - if (!_shader) - return false; - } - _originalViewportSize = OsEng.windowWrapper().currentWindowResolution(); + createPlane(); + createShaders(); + loadTexture(); // Setting spherical/euclidean onchange handler @@ -162,28 +78,43 @@ bool ScreenSpaceImage::deinitialize(){ return true; } +void ScreenSpaceImage::render(){ + glm::vec2 resolution = OsEng.windowWrapper().currentWindowResolution(); + //to scale the plane + float textureRatio = (float(_texture->height())/float(_texture->width())); -void ScreenSpaceImage::update(){ - -} + //to keep the texture ratio after viewport is distorted. + float scalingRatioX = resolution[0] / _originalViewportSize[0]; + float scalingRatioY = resolution[1] / _originalViewportSize[1]; -void ScreenSpaceImage::useEuclideanCoordinates(bool b){ - _useEuclideanCoordinates = b; - if(_useEuclideanCoordinates){ - _euclideanPosition.set(toEuclidean(_sphericalPosition.value(), _radius)); - _euclideanPosition.onChange([this](){ - _sphericalPosition.set(toSpherical(_euclideanPosition.value())); - }); - _sphericalPosition.onChange([this](){}); + glm::mat4 modelTransform = glm::mat4(1.0); + 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 { - _sphericalPosition.set(toSpherical(_euclideanPosition.value())); - _sphericalPosition.onChange([this](){ - _euclideanPosition.set(toEuclidean(_sphericalPosition.value(), _radius)); - }); - _euclideanPosition.onChange([this](){}); + glm::vec2 position = _euclideanPosition.value(); + modelTransform = glm::translate(glm::mat4(1.f), glm::vec3(position, _planeDepth)); } + + + // modelTransform = glm::scale(modelTransform, glm::vec3(_scale.value()*scalingRatioY, _scale.value()*textureRatio*scalingRatioX, 1)); + glm::mat4 rotation = rotationMatrix(); + glm::mat4 translation = translationMatrix(); + glm::mat4 scale = scaleMatrix(); + // scale = glm::scale(scale, glm::vec3(1.0f, -1.0f, 1.0f)); + modelTransform = rotation*translation*scale; + + draw(modelTransform); } +void ScreenSpaceImage::update(){} + + bool ScreenSpaceImage::isReady() const{ bool ready = true; if (!_shader) diff --git a/modules/base/rendering/screenspaceimage.h b/modules/base/rendering/screenspaceimage.h index c2d29a0eae..2de74ba413 100644 --- a/modules/base/rendering/screenspaceimage.h +++ b/modules/base/rendering/screenspaceimage.h @@ -40,16 +40,13 @@ public: bool deinitialize() override; void update() override; bool isReady() const override; - void useEuclideanCoordinates(bool b); + private: void loadTexture(); static int id(); properties::StringProperty _texturePath; - std::unique_ptr _texture; // The image to render int _id; - const std::string _vertexPath; - const std::string _fragmentPath; }; } //namespace openspace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 31c424b847..54668b0375 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -206,10 +206,11 @@ bool RenderEngine::initialize() { #endif // GHOUL_USE_SOIL ghoul::io::TextureReader::ref().addReader(std::make_shared()); - ssr = std::make_shared("${OPENSPACE_DATA}/test2.jpg"); + ssr = 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()); + // registerScreenSpaceRenderable(std::make_shared()); return true; } diff --git a/src/rendering/screenspacerenderable.cpp b/src/rendering/screenspacerenderable.cpp index 96b0e180e3..346154b109 100644 --- a/src/rendering/screenspacerenderable.cpp +++ b/src/rendering/screenspacerenderable.cpp @@ -27,16 +27,18 @@ namespace openspace { ScreenSpaceRenderable::ScreenSpaceRenderable() : _enabled("enabled", "Is Enabled", true) - , _useFlatScreen("flatScreen", "Flat Screen", true) + , _useFlatScreen("flatScreen", "Flat Screen", false) , _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) , _quad(0) , _vertexPositionBuffer(0) + ,_rendererPath("${SHADERS}/renderframebuffer.frag") + ,_vertexPath("${MODULE_BASE}/shaders/screnspace_vs.glsl") + ,_fragmentPath("${MODULE_BASE}/shaders/screnspace_fs.glsl") + ,_texture(nullptr) ,_shader(nullptr) - ,_radius(-.2f) - , _rendererPath("${SHADERS}/renderframebuffer.frag") { addProperty(_enabled); addProperty(_useFlatScreen); @@ -44,7 +46,6 @@ ScreenSpaceRenderable::ScreenSpaceRenderable() addProperty(_sphericalPosition); addProperty(_depth); addProperty(_scale); - // addProperty(_texturePath); _rendererData = ghoul::Dictionary(); _rendererData.setValue("fragmentRendererPath", _rendererPath); @@ -52,6 +53,9 @@ ScreenSpaceRenderable::ScreenSpaceRenderable() _rendererData.setValue("windowHeight", OsEng.windowWrapper().currentWindowResolution().y); _useEuclideanCoordinates = _useFlatScreen.value(); + _radius = _planeDepth; + + _sphericalPosition.set(toSpherical(_euclideanPosition.value())); } ScreenSpaceRenderable::~ScreenSpaceRenderable(){} @@ -62,6 +66,8 @@ bool ScreenSpaceRenderable::isEnabled() const { } void ScreenSpaceRenderable::createPlane() { + glGenVertexArrays(1, &_quad); // generate array + glGenBuffers(1, &_vertexPositionBuffer); // generate buffer // ============================ // GEOMETRY (quad) // ============================ @@ -84,6 +90,23 @@ void ScreenSpaceRenderable::createPlane() { glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(sizeof(GLfloat) * 4)); } +void ScreenSpaceRenderable::useEuclideanCoordinates(bool b){ + _useEuclideanCoordinates = b; + if(_useEuclideanCoordinates){ + _euclideanPosition.set(toEuclidean(_sphericalPosition.value(), _radius)); + _euclideanPosition.onChange([this](){ + _sphericalPosition.set(toSpherical(_euclideanPosition.value())); + }); + _sphericalPosition.onChange([this](){}); + } else { + _sphericalPosition.set(toSpherical(_euclideanPosition.value())); + _sphericalPosition.onChange([this](){ + _euclideanPosition.set(toEuclidean(_sphericalPosition.value(), _radius)); + }); + _euclideanPosition.onChange([this](){}); + } +} + glm::vec2 ScreenSpaceRenderable::toEuclidean(glm::vec2 polar, float r){ float x = r*sin(polar[0])*sin(polar[1]); float y = r*cos(polar[1]); @@ -99,4 +122,103 @@ glm::vec2 ScreenSpaceRenderable::toSpherical(glm::vec2 euclidean){ return glm::vec2(theta, phi); } +void ScreenSpaceRenderable::registerProperties(){ + OsEng.gui()._property.registerProperty(&_enabled); + OsEng.gui()._property.registerProperty(&_useFlatScreen); + 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())); + }); + } +} + +void ScreenSpaceRenderable::createShaders(){ + if(_shader == nullptr) { + + ghoul::Dictionary dict = ghoul::Dictionary(); + + dict.setValue("rendererData", _rendererData); + dict.setValue("fragmentPath", _fragmentPath); + _shader = ghoul::opengl::ProgramObject::Build("ScreenSpaceProgram", + _vertexPath, + "${SHADERS}/render.frag", + dict + ); + } +} + +glm::mat4 ScreenSpaceRenderable::scaleMatrix(){ + glm::mat4 scale(1.0); + + glm::vec2 resolution = OsEng.windowWrapper().currentWindowResolution(); + + //to scale the plane + float textureRatio = (float(_texture->height())/float(_texture->width())); + float scalingRatioX = resolution[0] / _originalViewportSize[0]; + float scalingRatioY = resolution[1] / _originalViewportSize[1]; + scale = glm::scale(scale, glm::vec3(_scale.value() * scalingRatioY, + _scale.value() * scalingRatioX * textureRatio, + 1)); + return scale; +} + +glm::mat4 ScreenSpaceRenderable::rotationMatrix(){ + glm::mat4 rotation(1.0); + if(!_useEuclideanCoordinates){ + glm::vec2 position = _sphericalPosition.value(); + + float theta = position.x; + float phi = position.y - M_PI/2.0; + + rotation = glm::rotate(rotation, position.x, glm::vec3(0.0f, 1.0f, 0.0f)); + rotation = glm::rotate(rotation, (float) (position.y - M_PI/2.0) , glm::vec3(1.0f, 0.0f, 0.0f)); + } + + return rotation; +} + + +glm::mat4 ScreenSpaceRenderable::translationMatrix(){ + glm::mat4 translation(1.0); + if(!_useEuclideanCoordinates){ + translation = glm::translate(translation, glm::vec3(0.0f, 0.0f, _planeDepth)); + }else{ + + translation = glm::translate(glm::mat4(1.f), glm::vec3(_euclideanPosition.value(), _planeDepth)); + } + + return translation; +} + + +void ScreenSpaceRenderable::draw(glm::mat4 modelTransform){ + float occlusionDepth = 1-_depth.value(); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + _shader->activate(); + _shader->setUniform("OcclusionDepth", occlusionDepth); + _shader->setUniform("ModelTransform",modelTransform); + _shader->setUniform("ViewProjectionMatrix", OsEng.renderEngine().camera()->viewProjectionMatrix()); + ghoul::opengl::TextureUnit unit; + unit.activate(); + _texture->bind(); + _shader->setUniform("texture1", unit); + + glBindVertexArray(_quad); + glDrawArrays(GL_TRIANGLES, 0, 6); + glEnable(GL_CULL_FACE); + + _shader->deactivate(); +} }// namespace openspace \ No newline at end of file