From d25f2e60ab30f9de6df762dc17808da68845fabb Mon Sep 17 00:00:00 2001 From: Sebastian Piwell Date: Fri, 6 May 2016 16:12:30 -0400 Subject: [PATCH] ScreenSpaceImage can take urls and is parent to ScreenSpaceCygnet --- data/scene/default.scene | 17 ++- modules/base/rendering/screenspaceimage.cpp | 136 ++++++++++++++----- modules/base/rendering/screenspaceimage.h | 23 +++- modules/iswa/rendering/screenspacecygnet.cpp | 114 ++-------------- modules/iswa/rendering/screenspacecygnet.h | 19 +-- modules/iswa/util/iswamanager.cpp | 13 +- modules/iswa/util/iswamanager.h | 2 +- 7 files changed, 160 insertions(+), 164 deletions(-) diff --git a/data/scene/default.scene b/data/scene/default.scene index 97264e6e05..ee0605f4a9 100644 --- a/data/scene/default.scene +++ b/data/scene/default.scene @@ -30,17 +30,16 @@ function postInitialization() openspace.printInfo("Done setting default values") - openspace.iswa.addCygnet("0"); + --openspace.iswa.addCygnet("0"); --openspace.iswa.addCygnet("-1,Data,1"); --openspace.iswa.addCygnet("-2,Data,1"); --openspace.iswa.addCygnet("-3,Data,1"); - - --[[ + openspace.registerScreenSpaceRenderable( { Type = "ScreenSpaceCygnet", CygnetId = 7, - Position = {-0.8, 0.3}, + Position = {0.0, 0.0}, FlatScreen = true, Scale = 0.25, }); @@ -53,7 +52,15 @@ function postInitialization() FlatScreen = true, Scale = 0.25, }); - ]]-- + + openspace.registerScreenSpaceRenderable( + { + Type = "ScreenSpaceImage", + URL = "http://i.imgur.com/KUunHgr.jpg", + Position = {-0.8, 0.3}, + FlatScreen = true, + Scale = 0.25, + }); end diff --git a/modules/base/rendering/screenspaceimage.cpp b/modules/base/rendering/screenspaceimage.cpp index 37726a7725..fd7fdcec49 100644 --- a/modules/base/rendering/screenspaceimage.cpp +++ b/modules/base/rendering/screenspaceimage.cpp @@ -30,36 +30,36 @@ namespace { } namespace openspace { -// ScreenSpaceImage::ScreenSpaceImage(std::string texturePath) -// :ScreenSpaceRenderable() -// ,_texturePath("texturePath", "Texture path", texturePath) -// { -// _id = id(); -// setName("ScreenSpaceImage" + std::to_string(_id)); - -// registerProperties(); - -// addProperty(_texturePath); -// OsEng.gui()._screenSpaceProperty.registerProperty(&_texturePath); -// _texturePath.onChange([this](){ loadTexture(); }); -// } - ScreenSpaceImage::ScreenSpaceImage(const ghoul::Dictionary& dictionary) :ScreenSpaceRenderable(dictionary) ,_texturePath("texturePath", "Texture path", "") + ,_downloadImage(false) + ,_futureTexture(nullptr) { _id = id(); setName("ScreenSpaceImage" + std::to_string(_id)); - std::string texturePath; - dictionary.getValue("TexturePath", texturePath); - _texturePath.set(texturePath); - + addProperty(_texturePath); registerProperties(); - addProperty(_texturePath); - OsEng.gui()._screenSpaceProperty.registerProperty(&_texturePath); - _texturePath.onChange([this](){ loadTexture(); }); + std::string texturePath; + bool texturesucces = (dictionary.getValue("TexturePath", texturePath)); + if(texturesucces){ + _texturePath.set(texturePath); + OsEng.gui()._screenSpaceProperty.registerProperty(&_texturePath); + _texturePath.onChange([this](){ loadTexture(); }); + } + + bool urlsucces = dictionary.getValue("URL", _url); + if(urlsucces){ + _downloadImage =true; + } + + //screenspaceCygnet does not have url or texturePath + // if(!texturesucces && !urlsucces){ + // LERROR("Must specify TexturePath or URL"); + // } + } ScreenSpaceImage::~ScreenSpaceImage(){} @@ -69,7 +69,7 @@ bool ScreenSpaceImage::initialize(){ createPlane(); createShaders(); - loadTexture(); + updateTexture(); return isReady(); } @@ -92,10 +92,15 @@ bool ScreenSpaceImage::deinitialize(){ _shader = nullptr; } + _memorybuffer = ""; + return true; } void ScreenSpaceImage::render(){ + if(!isReady()) return; + if(!_enabled) return; + glm::mat4 rotation = rotationMatrix(); glm::mat4 translation = translationMatrix(); glm::mat4 scale = scaleMatrix(); @@ -105,7 +110,17 @@ void ScreenSpaceImage::render(){ } -void ScreenSpaceImage::update(){} +void ScreenSpaceImage::update(){ + if(_downloadImage && _futureTexture){ + if(_futureTexture->isAborted){ + LWARNING("Could not download image"); + _futureTexture = nullptr; + }else if(_futureTexture->isFinished){ + loadTexture(); + _futureTexture = nullptr; + } + } +} bool ScreenSpaceImage::isReady() const{ @@ -118,20 +133,79 @@ bool ScreenSpaceImage::isReady() const{ } void ScreenSpaceImage::loadTexture() { - if (_texturePath.value() != "") { - std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath.value())); - if (texture) { - LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'"); - texture->uploadTexture(); + std::unique_ptr texture = nullptr; + if(!_downloadImage) + texture = std::move(loadFromDisk()); + else + texture = std::move(loadFromMemory()); - // Textures of planets looks much smoother with AnisotropicMipMap rather than linear - texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + if (texture) { + // LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'"); + texture->uploadTexture(); - _texture = std::move(texture); + // Textures of planets looks much smoother with AnisotropicMipMap rather than linear + texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + + _texture = std::move(texture); + } +} + +void ScreenSpaceImage::updateTexture(){ + if(!_downloadImage){ + loadTexture(); + + }else{ + if(_futureTexture && !_futureTexture->isFinished && !_futureTexture->isAborted) + return; + + _memorybuffer = ""; + std::shared_ptr future = downloadImageToMemory(_url, _memorybuffer); + if(future){ + _futureTexture = future; } } } + 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(_memorybuffer != ""){ + std::string format; + std::stringstream ss(_futureTexture->format); + getline(ss, format ,'/'); + if(format != "image"){ + LWARNING("Something went wrong, not an image"); + return nullptr; + } + getline(ss, format); + + return (ghoul::io::TextureReader::ref().loadTexture( + (void*) _memorybuffer.c_str(), + _memorybuffer.size(), + format)); + } + return nullptr; + } + + +std::shared_ptr ScreenSpaceImage::downloadImageToMemory(std::string url, std::string& buffer){ + return DlManager.downloadToMemory( + url, + buffer, + [](const DownloadManager::FileFuture& f){ + if(f.isFinished){ + LDEBUG("Download to memory finished"); + } else if (f.isAborted){ + LWARNING("Download to memory was aborted: " + f.errorMessage); + } + } + ); +} + int ScreenSpaceImage::id(){ static int id = 0; return id++; diff --git a/modules/base/rendering/screenspaceimage.h b/modules/base/rendering/screenspaceimage.h index 58a693384e..0ae497fdca 100644 --- a/modules/base/rendering/screenspaceimage.h +++ b/modules/base/rendering/screenspaceimage.h @@ -26,6 +26,8 @@ #include #include +#include + namespace openspace { /** @@ -45,14 +47,27 @@ public: bool initialize() override; bool deinitialize() override; void render() override; - void update() override; + virtual void update() override; bool isReady() const override; -private: - void loadTexture(); - static int id(); +protected: + std::string _url; + bool _downloadImage; + std::shared_ptr _futureTexture; + void loadTexture(); + void updateTexture(); +private: + + static int id(); + std::shared_ptr downloadImageToMemory(std::string url, std::string& buffer); + std::unique_ptr loadFromDisk(); + std::unique_ptr loadFromMemory(); + properties::StringProperty _texturePath; + std::string _memorybuffer; + + int _id; }; diff --git a/modules/iswa/rendering/screenspacecygnet.cpp b/modules/iswa/rendering/screenspacecygnet.cpp index 12fe36f3bf..723064863c 100644 --- a/modules/iswa/rendering/screenspacecygnet.cpp +++ b/modules/iswa/rendering/screenspacecygnet.cpp @@ -34,19 +34,8 @@ namespace { namespace openspace { -// ScreenSpaceCygnet::ScreenSpaceCygnet(int cygnetId) -// : ScreenSpaceRenderable() -// , _updateInterval("updateInterval", "Update Interval", 1.0, 0.0 , 10.0) -// , _cygnetId(cygnetId) -// { -// setName("iSWACygnet" + std::to_string(_cygnetId)); -// addProperty(_updateInterval); - -// registerProperties(); -// } - ScreenSpaceCygnet::ScreenSpaceCygnet(const ghoul::Dictionary& dictionary) - : ScreenSpaceRenderable(dictionary) + : ScreenSpaceImage(dictionary) , _updateInterval("updateInterval", "Update Interval", 1.0, 0.0 , 10.0) { // hacky, have to first get as float and then cast to int. @@ -58,56 +47,16 @@ ScreenSpaceCygnet::ScreenSpaceCygnet(const ghoul::Dictionary& dictionary) addProperty(_updateInterval); registerProperties(); + + _downloadImage = true; + + _url = ISWAManager::ref().iSWAurl(_cygnetId); + _realTime = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); + _lastUpdateRealTime = _realTime; } ScreenSpaceCygnet::~ScreenSpaceCygnet(){} -bool ScreenSpaceCygnet::initialize(){ - _originalViewportSize = OsEng.windowWrapper().currentWindowResolution(); - createPlane(); - createShaders(); - updateTexture(); - - _realTime = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); - _lastUpdateRealTime = _realTime; - - return isReady(); -} - -bool ScreenSpaceCygnet::deinitialize(){ - OsEng.gui()._screenSpaceProperty.unregisterProperties(name()); - - glDeleteVertexArrays(1, &_quad); - _quad = 0; - - glDeleteBuffers(1, &_vertexPositionBuffer); - _vertexPositionBuffer = 0; - - _texture = nullptr; - - RenderEngine& renderEngine = OsEng.renderEngine(); - if (_shader) { - renderEngine.removeRenderProgram(_shader); - _shader = nullptr; - } - - _memorybuffer = ""; - return true; -} - -void ScreenSpaceCygnet::render(){ - - if(!isReady()) return; - if(!_enabled) return; - - glm::mat4 rotation = rotationMatrix(); - glm::mat4 translation = translationMatrix(); - glm::mat4 scale = scaleMatrix(); - glm::mat4 modelTransform = rotation*translation*scale; - - draw(modelTransform); -} - void ScreenSpaceCygnet::update(){ _realTime = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); int updateInterval = (int) (_updateInterval.value()*1000); @@ -115,6 +64,7 @@ void ScreenSpaceCygnet::update(){ (Time::ref().deltaTime() != 0); if(updateInterval != 0 && (Time::ref().timeJumped() || timeToUpdate )){ + _url = ISWAManager::ref().iSWAurl(_cygnetId); updateTexture(); _lastUpdateRealTime = _realTime; } @@ -125,52 +75,4 @@ void ScreenSpaceCygnet::update(){ } } -bool ScreenSpaceCygnet::isReady() const{ - bool ready = true; - if (!_shader) - ready &= false; - if(!_texture) - ready &= false; - return ready; -} - -void ScreenSpaceCygnet::updateTexture(){ - // If a download is in progress, dont send another request. - if(_futureTexture && !_futureTexture->isFinished && !_futureTexture->isAborted) - return; - - _memorybuffer = ""; - std::shared_ptr future = ISWAManager::ref().downloadImageToMemory(_cygnetId, _memorybuffer); - if(future){ - _futureTexture = future; - } - -} - -void ScreenSpaceCygnet::loadTexture() { - - if(_memorybuffer != ""){ - - std::string format; - std::stringstream ss(_futureTexture->format); - getline(ss, format ,'/'); - getline(ss, format); - - std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture( - (void*) _memorybuffer.c_str(), - _memorybuffer.size(), - format); - // std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_path)); - - if (texture) { - // LDEBUG("Loaded texture from '" << absPath(_path) << "'"); - - texture->uploadTexture(); - // Textures of planets looks much smoother with AnisotropicMipMap rather than linear - texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - - _texture = std::move(texture); - } - } -} } \ No newline at end of file diff --git a/modules/iswa/rendering/screenspacecygnet.h b/modules/iswa/rendering/screenspacecygnet.h index 60d4ff8c75..4040e48d09 100644 --- a/modules/iswa/rendering/screenspacecygnet.h +++ b/modules/iswa/rendering/screenspacecygnet.h @@ -27,35 +27,26 @@ #include #include +#include + #include #include namespace openspace{ -class ScreenSpaceCygnet : public ScreenSpaceRenderable { +class ScreenSpaceCygnet : public ScreenSpaceImage { public: - ScreenSpaceCygnet(int cygnetId); ScreenSpaceCygnet(const ghoul::Dictionary& dictionary); ~ScreenSpaceCygnet(); - void render() override; - bool initialize() override; - bool deinitialize() override; - void update() override; - bool isReady() const override; + virtual void update() override; + private: - void updateTexture(); - void loadTexture(); - int _cygnetId; - properties::FloatProperty _updateInterval; std::chrono::milliseconds _realTime; std::chrono::milliseconds _lastUpdateRealTime; - - std::shared_ptr _futureTexture; - std::string _memorybuffer; }; } // namespace openspace diff --git a/modules/iswa/util/iswamanager.cpp b/modules/iswa/util/iswamanager.cpp index c918431cd0..0ed60f59ec 100644 --- a/modules/iswa/util/iswamanager.cpp +++ b/modules/iswa/util/iswamanager.cpp @@ -257,9 +257,16 @@ std::shared_ptr ISWAManager::downloadMetadata(int id){ } void ISWAManager::createScreenSpace(int id){ - std::string luaTable = "{ Type='ScreenSpaceCygnet', CygnetId = "+std::to_string(id)+"}"; - std::string script = "openspace.registerScreenSpaceRenderable(" + luaTable + ");"; - OsEng.scriptEngine().queueScript(script); + + std::string name = "iSWACygnet" + std::to_string(id); + if(OsEng.renderEngine().screenSpaceRenderable(name)){ + LERROR("A cygnet with the name \"" + name +"\" already exist"); + return; + }else{ + std::string luaTable = "{ Type='ScreenSpaceCygnet', CygnetId = "+std::to_string(id)+"}"; + std::string script = "openspace.registerScreenSpaceRenderable(" + luaTable + ");"; + OsEng.scriptEngine().queueScript(script); + } } void ISWAManager::createPlane(std::shared_ptr data){ diff --git a/modules/iswa/util/iswamanager.h b/modules/iswa/util/iswamanager.h index 756fd8cc8c..4a29c00ba5 100644 --- a/modules/iswa/util/iswamanager.h +++ b/modules/iswa/util/iswamanager.h @@ -87,8 +87,8 @@ public: static scripting::ScriptEngine::LuaLibrary luaLibrary(); -private: std::string iSWAurl(int id, std::string type = "image"); +private: std::shared_ptr downloadMetadata(int id); void createScreenSpace(int id);