From aa969795cc1cd457dd3d3f4316c9b6bffa735954 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 10 Oct 2017 14:16:55 -0400 Subject: [PATCH] Factor ScreenSpaceImage into separate classes for local loading and online download (closes #296) --- .../rendering/screenspacerenderable.h | 11 +- modules/base/CMakeLists.txt | 6 +- modules/base/basemodule.cpp | 9 +- .../base/rendering/screenspaceframebuffer.cpp | 19 +- .../base/rendering/screenspaceframebuffer.h | 2 - .../base/rendering/screenspaceimagelocal.cpp | 123 +++++++++++ .../base/rendering/screenspaceimagelocal.h | 53 +++++ ...ceimage.cpp => screenspaceimageonline.cpp} | 156 ++++---------- ...nspaceimage.h => screenspaceimageonline.h} | 29 +-- modules/base/shaders/screenspace_vs.glsl | 4 +- modules/imgui/src/gui.cpp | 35 +++- modules/iswa/rendering/screenspacecygnet.cpp | 11 +- modules/iswa/rendering/screenspacecygnet.h | 4 +- src/rendering/screenspacerenderable.cpp | 193 +++++++++++++----- 14 files changed, 425 insertions(+), 230 deletions(-) create mode 100644 modules/base/rendering/screenspaceimagelocal.cpp create mode 100644 modules/base/rendering/screenspaceimagelocal.h rename modules/base/rendering/{screenspaceimage.cpp => screenspaceimageonline.cpp} (54%) rename modules/base/rendering/{screenspaceimage.h => screenspaceimageonline.h} (79%) diff --git a/include/openspace/rendering/screenspacerenderable.h b/include/openspace/rendering/screenspacerenderable.h index bd9b4ebafc..16fba100bb 100644 --- a/include/openspace/rendering/screenspacerenderable.h +++ b/include/openspace/rendering/screenspacerenderable.h @@ -55,13 +55,14 @@ public: const ghoul::Dictionary& dictionary); ScreenSpaceRenderable(const ghoul::Dictionary& dictionary); - virtual ~ScreenSpaceRenderable(); + virtual ~ScreenSpaceRenderable() = default; - virtual void render() = 0; - virtual bool initialize() = 0; - virtual bool deinitialize() = 0; + virtual void render(); + + virtual bool initialize(); + virtual bool deinitialize(); virtual void update() = 0; - virtual bool isReady() const = 0; + virtual bool isReady() const; bool isEnabled() const; glm::vec3 euclideanPosition() const; diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt index 682686b701..6f85ec7df9 100644 --- a/modules/base/CMakeLists.txt +++ b/modules/base/CMakeLists.txt @@ -35,7 +35,8 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrailorbit.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrailtrajectory.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.h - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimage.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimagelocal.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimageonline.h ${CMAKE_CURRENT_SOURCE_DIR}/translation/statictranslation.h ${CMAKE_CURRENT_SOURCE_DIR}/rotation/staticrotation.h ${CMAKE_CURRENT_SOURCE_DIR}/scale/staticscale.h @@ -53,7 +54,8 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrailorbit.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrailtrajectory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimage.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimagelocal.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimageonline.cpp ${CMAKE_CURRENT_SOURCE_DIR}/translation/statictranslation.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rotation/staticrotation.cpp ${CMAKE_CURRENT_SOURCE_DIR}/scale/staticscale.cpp diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index 530801d161..86e9e000b2 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -39,7 +39,8 @@ #include #include #include -#include +#include +#include #include #include @@ -67,7 +68,8 @@ void BaseModule::internalInitialize() { auto fScreenSpaceRenderable = FactoryManager::ref().factory(); ghoul_assert(fScreenSpaceRenderable, "ScreenSpaceRenderable factory was not created"); - fScreenSpaceRenderable->registerClass("ScreenSpaceImage"); + fScreenSpaceRenderable->registerClass("ScreenSpaceImageLocal"); + fScreenSpaceRenderable->registerClass("ScreenSpaceImageOnline"); fScreenSpaceRenderable->registerClass("ScreenSpaceFramebuffer"); auto fRenderable = FactoryManager::ref().factory(); @@ -108,7 +110,8 @@ std::vector BaseModule::documentations() const { RenderableTrailOrbit::Documentation(), RenderableTrailTrajectory::Documentation(), ScreenSpaceFramebuffer::Documentation(), - ScreenSpaceImage::Documentation(), + ScreenSpaceImageLocal::Documentation(), + ScreenSpaceImageOnline::Documentation(), StaticRotation::Documentation(), StaticScale::Documentation(), StaticTranslation::Documentation(), diff --git a/modules/base/rendering/screenspaceframebuffer.cpp b/modules/base/rendering/screenspaceframebuffer.cpp index 3f83cd16b4..ec04e19821 100644 --- a/modules/base/rendering/screenspaceframebuffer.cpp +++ b/modules/base/rendering/screenspaceframebuffer.cpp @@ -76,29 +76,14 @@ ScreenSpaceFramebuffer::ScreenSpaceFramebuffer(const ghoul::Dictionary& dictiona ScreenSpaceFramebuffer::~ScreenSpaceFramebuffer() {} bool ScreenSpaceFramebuffer::initialize() { - _originalViewportSize = OsEng.windowWrapper().currentWindowResolution(); - - createPlane(); - createShaders(); + ScreenSpaceRenderable::initialize(); createFragmentbuffer(); 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; - } + ScreenSpaceRenderable::deinitialize(); _framebuffer->detachAll(); removeAllRenderFunctions(); diff --git a/modules/base/rendering/screenspaceframebuffer.h b/modules/base/rendering/screenspaceframebuffer.h index 772e19e99b..f649698c78 100644 --- a/modules/base/rendering/screenspaceframebuffer.h +++ b/modules/base/rendering/screenspaceframebuffer.h @@ -31,8 +31,6 @@ #include #include -#include - namespace openspace { namespace documentation { struct Documentation; } diff --git a/modules/base/rendering/screenspaceimagelocal.cpp b/modules/base/rendering/screenspaceimagelocal.cpp new file mode 100644 index 0000000000..124d3ba988 --- /dev/null +++ b/modules/base/rendering/screenspaceimagelocal.cpp @@ -0,0 +1,123 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * 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 +#include +#include + +namespace { + const char* KeyName = "Name"; + const char* KeyUrl = "URL"; + + static const openspace::properties::Property::PropertyInfo TexturePathInfo = { + "TexturePath", + "Texture path", + "Sets the path of the texture that is displayed on this screen space plane. If " + "this value is changed, the image at the new path will automatically be loaded " + "and displayed. The size of the image will also automatically set the default " + "size of this plane." + }; +} // namespace + +namespace openspace { + +documentation::Documentation ScreenSpaceImageLocal::Documentation() { + using namespace openspace::documentation; + return { + "ScreenSpace Local Image", + "base_screenspace_image_local", + { + { + KeyName, + new StringVerifier, + Optional::Yes, + "Specifies the GUI name of the ScreenspaceImage" + }, + { + TexturePathInfo.identifier, + new StringVerifier, + Optional::Yes, + TexturePathInfo.description + } + } + }; +} + +ScreenSpaceImageLocal::ScreenSpaceImageLocal(const ghoul::Dictionary& dictionary) + : ScreenSpaceRenderable(dictionary) + , _texturePath(TexturePathInfo) + , _textureIsDirty(false) +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "ScreenSpaceImageLocal" + ); + + if (dictionary.hasKey(KeyName)) { + setName(dictionary.value(KeyName)); + } + else { + static int id = 0; + setName("ScreenSpaceImageLocal " + std::to_string(id)); + ++id; + } + + _texturePath.onChange([this]() { _textureIsDirty = true; }); + addProperty(_texturePath); + + if (dictionary.hasKey(TexturePathInfo.identifier)) { + _texturePath = dictionary.value(TexturePathInfo.identifier); + } +} + +void ScreenSpaceImageLocal::update() { + if (_textureIsDirty && !_texturePath.value().empty()) { + std::unique_ptr texture = + ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); + + if (texture) { + texture->uploadTexture(); + + // Textures of planets looks much smoother with AnisotropicMipMap rather than linear + texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + + _texture = std::move(texture); + _textureIsDirty = false; + } + + } +} + +} // namespace openspace diff --git a/modules/base/rendering/screenspaceimagelocal.h b/modules/base/rendering/screenspaceimagelocal.h new file mode 100644 index 0000000000..f113d0470d --- /dev/null +++ b/modules/base/rendering/screenspaceimagelocal.h @@ -0,0 +1,53 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2017 * + * * + * 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 __OPENSPACE_MODULE_BASE___SCREENSPACEIMAGELOCAL___H__ +#define __OPENSPACE_MODULE_BASE___SCREENSPACEIMAGELOCAL___H__ + +#include + +#include + +#include + +namespace openspace { + +namespace documentation { struct Documentation; } + +class ScreenSpaceImageLocal : public ScreenSpaceRenderable { +public: + ScreenSpaceImageLocal(const ghoul::Dictionary& dictionary); + + void update() override; + + static documentation::Documentation Documentation(); + +private: + properties::StringProperty _texturePath; + bool _textureIsDirty; +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_BASE___SCREENSPACEIMAGELOCAL___H__ diff --git a/modules/base/rendering/screenspaceimage.cpp b/modules/base/rendering/screenspaceimageonline.cpp similarity index 54% rename from modules/base/rendering/screenspaceimage.cpp rename to modules/base/rendering/screenspaceimageonline.cpp index 735e53c171..849c68fe10 100644 --- a/modules/base/rendering/screenspaceimage.cpp +++ b/modules/base/rendering/screenspaceimageonline.cpp @@ -22,7 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #include #include @@ -38,12 +38,11 @@ namespace { const char* KeyName = "Name"; const char* KeyTexturePath = "TexturePath"; - const char* KeyUrl = "URL"; static const openspace::properties::Property::PropertyInfo TexturePathInfo = { "TexturePath", "Texture path", - "Sets the path of the texture that is displayed on this screen space plane. If " + "Sets the URL of the texture that is displayed on this screen space plane. If " "this value is changed, the image at the new path will automatically be loaded " "and displayed. The size of the image will also automatically set the default " "size of this plane." @@ -52,11 +51,11 @@ namespace { namespace openspace { -documentation::Documentation ScreenSpaceImage::Documentation() { +documentation::Documentation ScreenSpaceImageOnline::Documentation() { using namespace openspace::documentation; return { - "ScreenSpace Image", - "base_screenspace_image", + "ScreenSpace Online Image", + "base_screenspace_image_online", { { KeyName, @@ -68,16 +67,14 @@ documentation::Documentation ScreenSpaceImage::Documentation() { KeyTexturePath, new StringVerifier, Optional::Yes, - "Specifies the image that is shown on the screenspace-aligned plane. If " - "this value is set and the URL is not, the disk image is used." + TexturePathInfo.description } } }; } -ScreenSpaceImage::ScreenSpaceImage(const ghoul::Dictionary& dictionary) +ScreenSpaceImageOnline::ScreenSpaceImageOnline(const ghoul::Dictionary& dictionary) : ScreenSpaceRenderable(dictionary) - , _downloadImage(false) , _textureIsDirty(false) , _texturePath(TexturePathInfo) { @@ -92,138 +89,75 @@ ScreenSpaceImage::ScreenSpaceImage(const ghoul::Dictionary& dictionary) } else { static int id = 0; - setName("ScreenSpaceImage " + std::to_string(id)); + setName("ScreenSpaceImageOnline " + std::to_string(id)); ++id; } - std::string texturePath; - if (dictionary.getValue(KeyTexturePath, texturePath)) { - _texturePath = dictionary.value(KeyTexturePath); - } - - if (dictionary.getValue(KeyUrl, _url)) { - _downloadImage = true; - } - _texturePath.onChange([this]() { _textureIsDirty = true; }); addProperty(_texturePath); -} -bool ScreenSpaceImage::initialize() { - _originalViewportSize = OsEng.windowWrapper().currentWindowResolution(); - - createPlane(); - createShaders(); - updateTexture(); - - return isReady(); -} - -bool ScreenSpaceImage::deinitialize() { - glDeleteVertexArrays(1, &_quad); - _quad = 0; - - glDeleteBuffers(1, &_vertexPositionBuffer); - _vertexPositionBuffer = 0; - - _texturePath = ""; - _texture = nullptr; - - if (_shader) { - OsEng.renderEngine().removeRenderProgram(_shader); - _shader = nullptr; + std::string texturePath; + if (dictionary.hasKey(TexturePathInfo.identifier)) { + _texturePath = dictionary.value(TexturePathInfo.identifier); } - return true; } -void ScreenSpaceImage::render() { - draw(rotationMatrix() * translationMatrix() * scaleMatrix()); -} +void ScreenSpaceImageOnline::update() { + if (_textureIsDirty) { + if (!_imageFuture.valid()) { + std::future future = downloadImageToMemory(_texturePath); + if (future.valid()) { + _imageFuture = std::move(future); + } + } -void ScreenSpaceImage::update() { - bool download = _downloadImage ? (_futureImage.valid() && DownloadManager::futureReady(_futureImage)) : true; - if (download && _textureIsDirty) { - loadTexture(); - } -} + if (_imageFuture.valid() && DownloadManager::futureReady(_imageFuture)) { + DownloadManager::MemoryFile imageFile = _imageFuture.get(); -bool ScreenSpaceImage::isReady() const { - return _shader && _texture; -} + if (imageFile.corrupted) { + LERRORC( + "ScreenSpaceImageOnline", + "Error loading image from URL '" << _texturePath << "'" + ); + return; + } -void ScreenSpaceImage::loadTexture() { - std::unique_ptr texture = nullptr; - if (!_downloadImage) - texture = loadFromDisk(); - else - texture = loadFromMemory(); + std::unique_ptr texture = + ghoul::io::TextureReader::ref().loadTexture( + reinterpret_cast(imageFile.buffer), + imageFile.size, + imageFile.format + ); - if (texture) { - // LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'"); - texture->uploadTexture(); + if (texture) { + // LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'"); + texture->uploadTexture(); - // Textures of planets looks much smoother with AnisotropicMipMap rather than linear - texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + // Textures of planets looks much smoother with AnisotropicMipMap rather than linear + texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - _texture = std::move(texture); - _textureIsDirty = false; - } -} - -void ScreenSpaceImage::updateTexture() { - if (!_downloadImage) { - loadTexture(); - } else { - if (_futureImage.valid()) - return; - - std::future future = downloadImageToMemory(_url); - if (future.valid()) { - _futureImage = std::move(future); + _texture = std::move(texture); + _textureIsDirty = false; + } } } } - std::unique_ptr ScreenSpaceImage::loadFromDisk() { - if (_texturePath.value() != "") - return (ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath.value()))); - return nullptr; - } - - std::unique_ptr ScreenSpaceImage::loadFromMemory() { - if (_futureImage.valid() && DownloadManager::futureReady(_futureImage)) { - DownloadManager::MemoryFile imageFile = _futureImage.get(); - - if (imageFile.corrupted) { - return nullptr; - } - - return (ghoul::io::TextureReader::ref().loadTexture( - reinterpret_cast(imageFile.buffer), - imageFile.size, - imageFile.format) - ); - } - else { - return nullptr; - } - } - -std::future ScreenSpaceImage::downloadImageToMemory( +std::future ScreenSpaceImageOnline::downloadImageToMemory( std::string url) { return OsEng.downloadManager().fetchFile( url, [url](const DownloadManager::MemoryFile&) { LDEBUGC( - "ScreenSpaceImage", + "ScreenSpaceImageOnline", "Download to memory finished for screen space image" ); }, [url](const std::string& err) { LDEBUGC( - "ScreenSpaceImage", + "ScreenSpaceImageOnline", "Download to memory failer for screen space image: " + err ); } diff --git a/modules/base/rendering/screenspaceimage.h b/modules/base/rendering/screenspaceimageonline.h similarity index 79% rename from modules/base/rendering/screenspaceimage.h rename to modules/base/rendering/screenspaceimageonline.h index 9130627ee9..e7e5b5c7c4 100644 --- a/modules/base/rendering/screenspaceimage.h +++ b/modules/base/rendering/screenspaceimageonline.h @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __OPENSPACE_MODULE_BASE___SCREENSPACEIMAGE___H__ -#define __OPENSPACE_MODULE_BASE___SCREENSPACEIMAGE___H__ +#ifndef __OPENSPACE_MODULE_BASE___SCREENSPACEIMAGEONLINE___H__ +#define __OPENSPACE_MODULE_BASE___SCREENSPACEIMAGEONLINE___H__ #include @@ -36,37 +36,24 @@ namespace openspace { namespace documentation { struct Documentation; } -class ScreenSpaceImage : public ScreenSpaceRenderable { +class ScreenSpaceImageOnline : public ScreenSpaceRenderable { public: - ScreenSpaceImage(const ghoul::Dictionary& dictionary); + ScreenSpaceImageOnline(const ghoul::Dictionary& dictionary); - bool initialize() override; - bool deinitialize() override; - void render() override; void update() override; - bool isReady() const override; static documentation::Documentation Documentation(); protected: - void loadTexture(); - void updateTexture(); - - std::string _url; bool _downloadImage; bool _textureIsDirty; - std::future _futureImage; - -private: - std::future downloadImageToMemory(std::string url); - std::unique_ptr loadFromDisk(); - std::unique_ptr loadFromMemory(); - + std::future _imageFuture; properties::StringProperty _texturePath; - +private: + std::future downloadImageToMemory(std::string url); }; } // namespace openspace -#endif // __OPENSPACE_MODULE_BASE___SCREENSPACEIMAGE___H__ +#endif // __OPENSPACE_MODULE_BASE___SCREENSPACEIMAGEONLINE___H__ diff --git a/modules/base/shaders/screenspace_vs.glsl b/modules/base/shaders/screenspace_vs.glsl index 4ffb61ee20..aa75d22719 100644 --- a/modules/base/shaders/screenspace_vs.glsl +++ b/modules/base/shaders/screenspace_vs.glsl @@ -24,7 +24,7 @@ #version __CONTEXT__ -layout(location = 0) in vec4 in_position; +layout(location = 0) in vec2 in_position; layout(location = 1) in vec2 in_st; out vec2 vs_st; @@ -36,6 +36,6 @@ uniform mat4 ViewProjectionMatrix; void main() { vs_st = in_st; - vs_position = ViewProjectionMatrix * ModelTransform * in_position; + vs_position = ViewProjectionMatrix * ModelTransform * vec4(in_position, 0.0, 1.0); gl_Position = vec4(vs_position); } diff --git a/modules/imgui/src/gui.cpp b/modules/imgui/src/gui.cpp index aaa07b3ffb..130daab6e2 100644 --- a/modules/imgui/src/gui.cpp +++ b/modules/imgui/src/gui.cpp @@ -211,17 +211,25 @@ static void RenderDrawLists(ImDrawData* drawData) { } -void addScreenSpaceRenderable(std::string texturePath) { +void addScreenSpaceRenderableLocal(std::string texturePath) { if (!FileSys.fileExists(texturePath)) { LWARNING("Could not find image '" << texturePath << "'"); return; } const std::string luaTable = - "{Type = 'ScreenSpaceImage', TexturePath = openspace.absPath('" + texturePath + "') }"; + "{Type = 'ScreenSpaceImageLocal', TexturePath = openspace.absPath('" + texturePath + "') }"; const std::string script = "openspace.registerScreenSpaceRenderable(" + luaTable + ");"; OsEng.scriptEngine().queueScript(script, openspace::scripting::ScriptEngine::RemoteScripting::Yes); } + +void addScreenSpaceRenderableOnline(std::string texturePath) { + const std::string luaTable = + "{Type = 'ScreenSpaceImageOnline', TexturePath = '" + texturePath + "' }"; + const std::string script = "openspace.registerScreenSpaceRenderable(" + luaTable + ");"; + OsEng.scriptEngine().queueScript(script, openspace::scripting::ScriptEngine::RemoteScripting::Yes); +} + } // namespace namespace openspace::gui { @@ -656,16 +664,27 @@ void GUI::render() { renderAndUpdatePropertyVisibility(); static const int addImageBufferSize = 256; - static char addImageBuffer[addImageBufferSize]; + static char addImageLocalBuffer[addImageBufferSize]; + static char addImageOnlineBuffer[addImageBufferSize]; - bool addImage = ImGui::InputText( - "addImage", - addImageBuffer, + bool addImageLocal = ImGui::InputText( + "Add Local Image", + addImageLocalBuffer, addImageBufferSize, ImGuiInputTextFlags_EnterReturnsTrue ); - if (addImage) { - addScreenSpaceRenderable(std::string(addImageBuffer)); + if (addImageLocal) { + addScreenSpaceRenderableLocal(std::string(addImageLocalBuffer)); + } + + bool addImageOnline = ImGui::InputText( + "Add Online Image", + addImageOnlineBuffer, + addImageBufferSize, + ImGuiInputTextFlags_EnterReturnsTrue + ); + if (addImageOnline) { + addScreenSpaceRenderableOnline(std::string(addImageOnlineBuffer)); } ImGui::Checkbox("ImGUI Internals", &_showInternals); diff --git a/modules/iswa/rendering/screenspacecygnet.cpp b/modules/iswa/rendering/screenspacecygnet.cpp index bb23066799..d2c9fda956 100644 --- a/modules/iswa/rendering/screenspacecygnet.cpp +++ b/modules/iswa/rendering/screenspacecygnet.cpp @@ -36,7 +36,7 @@ namespace { namespace openspace { ScreenSpaceCygnet::ScreenSpaceCygnet(const ghoul::Dictionary& dictionary) - : ScreenSpaceImage(dictionary) + : ScreenSpaceImageOnline(dictionary) { // hacky, have to first get as float and then cast to int. float cygnetid; @@ -48,7 +48,7 @@ ScreenSpaceCygnet::ScreenSpaceCygnet(const ghoul::Dictionary& dictionary) _updateTime = (int) interval; _downloadImage = true; - _url = IswaManager::ref().iswaUrl(_cygnetId); + _texturePath = IswaManager::ref().iswaUrl(_cygnetId); _openSpaceTime = OsEng.timeManager().time().j2000Seconds(); _lastUpdateOpenSpaceTime = _openSpaceTime; @@ -77,14 +77,9 @@ void ScreenSpaceCygnet::update(){ (_realTime.count()-_lastUpdateRealTime.count()) > _minRealTimeUpdateInterval); if((OsEng.timeManager().time().timeJumped() || timeToUpdate )){ - _url = IswaManager::ref().iswaUrl(_cygnetId); - updateTexture(); + _texturePath = IswaManager::ref().iswaUrl(_cygnetId); _lastUpdateRealTime = _realTime; _lastUpdateOpenSpaceTime = _openSpaceTime; } - - if(_futureImage.valid() && DownloadManager::futureReady(_futureImage)) { - loadTexture(); - } } } diff --git a/modules/iswa/rendering/screenspacecygnet.h b/modules/iswa/rendering/screenspacecygnet.h index ce6f6beb5d..c128fa0cbc 100644 --- a/modules/iswa/rendering/screenspacecygnet.h +++ b/modules/iswa/rendering/screenspacecygnet.h @@ -28,14 +28,14 @@ #include #include #include -#include +#include #include #include namespace openspace { -class ScreenSpaceCygnet : public ScreenSpaceImage { +class ScreenSpaceCygnet : public ScreenSpaceImageOnline { public: ScreenSpaceCygnet(const ghoul::Dictionary& dictionary); ~ScreenSpaceCygnet(); diff --git a/src/rendering/screenspacerenderable.cpp b/src/rendering/screenspacerenderable.cpp index 32b3e9c42b..0a6041c06a 100644 --- a/src/rendering/screenspacerenderable.cpp +++ b/src/rendering/screenspacerenderable.cpp @@ -37,11 +37,6 @@ namespace { const char* _loggerCat = "ScreenSpaceRenderable"; const char* KeyType = "Type"; - const char* KeyFlatScreen = "FlatScreen"; - const char* KeyPosition = "Position"; - const char* KeyScale = "Scale"; - const char* KeyDepth = "Depth"; - const char* KeyAlpha = "Alpha"; const char* KeyTag = "Tag"; const float PlaneDepth = -2.f; @@ -126,6 +121,59 @@ documentation::Documentation ScreenSpaceRenderable::Documentation() { "available types of Screenspace renderable depend on the configuration of" "the application and can be written to disk on application startup into " "the FactoryDocumentation." + }, + { + EnabledInfo.identifier, + new BoolVerifier, + Optional::Yes, + EnabledInfo.description + }, + { + FlatScreenInfo.identifier, + new BoolVerifier, + Optional::Yes, + FlatScreenInfo.description + }, + { + EuclideanPositionInfo.identifier, + new DoubleVector2Verifier, + Optional::Yes, + EuclideanPositionInfo.description + }, + { + SphericalPositionInfo.identifier, + new DoubleVector2Verifier, + Optional::Yes, + SphericalPositionInfo.description + }, + { + DepthInfo.identifier, + new DoubleVerifier, + Optional::Yes, + DepthInfo.description + }, + { + ScaleInfo.identifier, + new DoubleVerifier, + Optional::Yes, + ScaleInfo.description + }, + { + AlphaInfo.identifier, + new DoubleVerifier, + Optional::Yes, + AlphaInfo.description + }, + { + KeyTag, + new OrVerifier( + new StringVerifier, + new StringListVerifier + ), + Optional::Yes, + "Defines either a single or multiple tags that apply to this " + "ScreenSpaceRenderable, thus making it possible to address multiple, " + "seprate Renderables with a single property change." } } }; @@ -143,15 +191,7 @@ std::unique_ptr ScreenSpaceRenderable::createFromDictiona std::string renderableType = dictionary.value(KeyType); auto factory = FactoryManager::ref().factory(); - std::unique_ptr result = factory->create(renderableType, dictionary); - if (result == nullptr) { - LERROR("Failed to create a ScreenSpaceRenderable object of type '" << - renderableType << "'" - ); - return nullptr; - } - - return result; + return factory->create(renderableType, dictionary); } ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary) @@ -182,25 +222,61 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary { addProperty(_enabled); addProperty(_useFlatScreen); + addProperty(_euclideanPosition); + + // Setting spherical/euclidean onchange handler + _useFlatScreen.onChange([this]() { + if (_useFlatScreen) { + addProperty(_euclideanPosition); + removeProperty(_sphericalPosition); + } + else { + removeProperty(_euclideanPosition); + addProperty(_sphericalPosition); + } + useEuclideanCoordinates(_useFlatScreen); + }); + addProperty(_depth); addProperty(_scale); addProperty(_alpha); addProperty(_delete); - dictionary.getValue(KeyFlatScreen, _useFlatScreen); + if (dictionary.hasKey(EnabledInfo.identifier)) { + _enabled = dictionary.value(EnabledInfo.identifier); + } + + if (dictionary.hasKey(FlatScreenInfo.identifier)) { + _useFlatScreen = dictionary.value(FlatScreenInfo.identifier); + } useEuclideanCoordinates(_useFlatScreen); if (_useFlatScreen) { - dictionary.getValue(KeyPosition, _euclideanPosition); + if (dictionary.hasKey(EuclideanPositionInfo.identifier)) { + _euclideanPosition = dictionary.value( + EuclideanPositionInfo.identifier + ); + } } else { - dictionary.getValue(KeyPosition, _sphericalPosition); + if (dictionary.hasKey(SphericalPositionInfo.identifier)) { + _sphericalPosition = dictionary.value( + SphericalPositionInfo.identifier + ); + } } + if (dictionary.hasKey(ScaleInfo.identifier)) { + _scale = static_cast(dictionary.value(ScaleInfo.identifier)); + } - dictionary.getValue(KeyScale, _scale); - dictionary.getValue(KeyDepth, _depth); - dictionary.getValue(KeyAlpha, _alpha); + if (dictionary.hasKey(DepthInfo.identifier)) { + _depth = static_cast(dictionary.value(DepthInfo.identifier)); + } + + if (dictionary.hasKey(AlphaInfo.identifier)) { + _alpha = static_cast(dictionary.value(AlphaInfo.identifier)); + } if (dictionary.hasKeyAndValue(KeyTag)) { std::string tagName = dictionary.value(KeyTag); @@ -219,18 +295,6 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary } } - // Setting spherical/euclidean onchange handler - _useFlatScreen.onChange([this](){ - if (_useFlatScreen) { - addProperty(_euclideanPosition); - removeProperty(_sphericalPosition); - } else { - removeProperty(_euclideanPosition); - addProperty(_sphericalPosition); - } - useEuclideanCoordinates(_useFlatScreen); - }); - _delete.onChange([this](){ std::string script = "openspace.unregisterScreenSpaceRenderable('" + name() + "');"; @@ -241,7 +305,40 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary }); } -ScreenSpaceRenderable::~ScreenSpaceRenderable() {} +bool ScreenSpaceRenderable::initialize() { + _originalViewportSize = OsEng.windowWrapper().currentWindowResolution(); + + createPlane(); + createShaders(); + + return isReady(); +} + +bool ScreenSpaceRenderable::deinitialize() { + glDeleteVertexArrays(1, &_quad); + _quad = 0; + + glDeleteBuffers(1, &_vertexPositionBuffer); + _vertexPositionBuffer = 0; + + _texture = nullptr; + + RenderEngine& renderEngine = OsEng.renderEngine(); + if (_shader) { + renderEngine.removeRenderProgram(_shader); + _shader = nullptr; + } + + return true; +} + +void ScreenSpaceRenderable::render() { + draw(rotationMatrix() * translationMatrix() * scaleMatrix()); +} + +bool ScreenSpaceRenderable::isReady() const { + return _shader && _texture; +} bool ScreenSpaceRenderable::isEnabled() const { return _enabled; @@ -262,29 +359,27 @@ float ScreenSpaceRenderable::depth() const { void ScreenSpaceRenderable::createPlane() { glGenVertexArrays(1, &_quad); glGenBuffers(1, &_vertexPositionBuffer); - // ============================ - // GEOMETRY (quad) - // ============================ - const GLfloat vertex_data[] = { - // x y z w s t - -1, -1, 0.0f, 1, 0, 0, - 1, 1, 0.0f, 1, 1, 1, - -1, 1, 0.0f, 1, 0, 1, - -1, -1, 0.0f, 1, 0, 0, - 1, -1, 0.0f, 1, 1, 0, - 1, 1, 0.0f, 1, 1, 1, + + const GLfloat data[] = { + // x y s t + -1.f, -1.f, 0.f, 0.f, + 1.f, 1.f, 1.f, 1.f, + -1.f, 1.f, 0.f, 1.f, + -1.f, -1.f, 0.f, 0.f, + 1.f, -1.f, 1.f, 0.f, + 1.f, 1.f, 1.f, 1.f, }; glBindVertexArray(_quad); glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer( 0, - 4, + 2, GL_FLOAT, GL_FALSE, - sizeof(GLfloat) * 6, + sizeof(GLfloat) * 4, nullptr ); @@ -294,8 +389,8 @@ void ScreenSpaceRenderable::createPlane() { 2, GL_FLOAT, GL_FALSE, - sizeof(GLfloat) * 6, - reinterpret_cast(sizeof(GLfloat) * 4) + sizeof(GLfloat) * 4, + reinterpret_cast(sizeof(GLfloat) * 2) ); }