diff --git a/data/dataplane.png b/data/dataplane.png new file mode 100644 index 0000000000..c1f2ce1a14 Binary files /dev/null and b/data/dataplane.png differ diff --git a/include/openspace/engine/downloadmanager.h b/include/openspace/engine/downloadmanager.h index 653dd1edd1..c4c7e4c8cc 100644 --- a/include/openspace/engine/downloadmanager.h +++ b/include/openspace/engine/downloadmanager.h @@ -76,6 +76,12 @@ public: DownloadProgressCallback progressCallback = DownloadProgressCallback() ); + FileFuture* getToMemory( + const std::string& url, std::string& memory, + DownloadFinishedCallback finishedCallback = DownloadFinishedCallback(), + DownloadProgressCallback progressCallback = DownloadProgressCallback() + ); + std::vector downloadRequestFiles(const std::string& identifier, const ghoul::filesystem::Directory& destination, int version, bool overrideFiles = true, diff --git a/modules/datasurface/rendering/renderabledataplane.cpp b/modules/datasurface/rendering/renderabledataplane.cpp index ea246f73c1..069d72c6b5 100644 --- a/modules/datasurface/rendering/renderabledataplane.cpp +++ b/modules/datasurface/rendering/renderabledataplane.cpp @@ -51,15 +51,39 @@ RenderableDataPlane::RenderableDataPlane(const ghoul::Dictionary& dictionary) addProperty(_roatation); _texturePath.onChange(std::bind(&RenderableDataPlane::loadTexture, this)); - + } RenderableDataPlane::~RenderableDataPlane(){ } +void RenderableDataPlane::updateTexture(){ + int imageSize = 1024; + DownloadManager::FileFuture* future; + while(true) { + std::this_thread::sleep_for(std::chrono::milliseconds(6000)); + future = DlManager.downloadFile( + std::string("http://placehold.it/" + std::to_string(imageSize) + "x" + std::to_string(imageSize)), + absPath("${OPENSPACE_DATA}/dataplane.png"), + true, + [](const DownloadManager::FileFuture& f){ + std::cout<<" =====Download finished===== " << std::endl; + } + ); + + if(future){ + _futureTexture = future; + imageSize-=1; + } + } +} + bool RenderableDataPlane::initialize() { + std::thread t = std::thread(std::bind(&RenderableDataPlane::updateTexture, this)); + t.detach(); + KameleonWrapper kw(absPath("${OPENSPACE_DATA}/BATSRUS.cdf")); _dimensions = glm::size3_t(1000,1000,1); @@ -93,6 +117,7 @@ bool RenderableDataPlane::initialize() { return isReady(); }; + bool RenderableDataPlane::deinitialize() { glDeleteVertexArrays(1, &_quad); _quad = 0; @@ -161,16 +186,23 @@ void RenderableDataPlane::render(const RenderData& data) void RenderableDataPlane::update(const UpdateData& data){ if (_planeIsDirty) createPlane(); + + if(_futureTexture && _futureTexture->isFinished){ + _texturePath.set(absPath("${OPENSPACE_DATA}/"+_futureTexture->filePath)); + loadTexture(); + delete _futureTexture; + _futureTexture = nullptr; + } }; void RenderableDataPlane::loadTexture() { if (_texturePath.value() != "") { - //std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); - ghoul::opengl::Texture::FilterMode filtermode = ghoul::opengl::Texture::FilterMode::Linear; + std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); +/* ghoul::opengl::Texture::FilterMode filtermode = ghoul::opengl::Texture::FilterMode::Linear; ghoul::opengl::Texture::WrappingMode wrappingmode = ghoul::opengl::Texture::WrappingMode::ClampToEdge; std::unique_ptr texture = - std::make_unique(_dataSlice, _dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, filtermode, wrappingmode); + std::make_unique(_dataSlice, _dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, filtermode, wrappingmode);*/ if (texture) { std::cout << "texture path: " << absPath(_texturePath) << std::endl; // LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'"); diff --git a/modules/datasurface/rendering/renderabledataplane.h b/modules/datasurface/rendering/renderabledataplane.h index 4d3378efa3..b874537ff0 100644 --- a/modules/datasurface/rendering/renderabledataplane.h +++ b/modules/datasurface/rendering/renderabledataplane.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace openspace{ @@ -49,6 +50,7 @@ private: void loadTexture(); void createPlane(); + void updateTexture(); properties::StringProperty _texturePath; properties::Vec3Property _roatation; @@ -61,6 +63,7 @@ glm::vec4 _pscOffset; glm::vec4 _modelScale; psc _parentPos; + DownloadManager::FileFuture* _futureTexture; GLuint _quad; GLuint _vertexPositionBuffer; diff --git a/src/engine/downloadmanager.cpp b/src/engine/downloadmanager.cpp index c094e11033..1cae469022 100644 --- a/src/engine/downloadmanager.cpp +++ b/src/engine/downloadmanager.cpp @@ -62,6 +62,12 @@ namespace { } + size_t writeToMemory(void *contents, size_t size, size_t nmemb, void *userp) + { + ((std::string*)userp)->append((char*)contents, size * nmemb); + return size * nmemb; + } + int xferinfo(void* p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) { @@ -196,6 +202,65 @@ DownloadManager::FileFuture* DownloadManager::downloadFile( return future; } +DownloadManager::FileFuture* DownloadManager::getToMemory( + const std::string& url, std::string& memoryBuffer, + DownloadFinishedCallback finishedCallback, DownloadProgressCallback progressCallback) +{ + FileFuture* future = new FileFuture(std::string("memory")); + + LDEBUG("Start downloading file: '" << url << "' into memory"); + + auto downloadFunction = [url, finishedCallback, progressCallback, future, &memoryBuffer]() { + CURL* curl = curl_easy_init(); + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &memoryBuffer); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeToMemory); + + ProgressInformation p = { + future, + std::chrono::system_clock::now(), + &progressCallback + }; + curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo); + curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &p); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); + + CURLcode res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + + if (res == CURLE_OK) + future->isFinished = true; + else + future->errorMessage = curl_easy_strerror(res); + + if (finishedCallback) + finishedCallback(*future); + } + }; + + if (_useMultithreadedDownload) { + std::thread t = std::thread(downloadFunction); + +#ifdef WIN32 + std::thread::native_handle_type h = t.native_handle(); + SetPriorityClass(h, IDLE_PRIORITY_CLASS); + SetThreadPriority(h, THREAD_PRIORITY_LOWEST); +#else + // TODO: Implement thread priority ---abock +#endif + + t.detach(); + } + else { + downloadFunction(); + } + + return future; +} + + std::vector DownloadManager::downloadRequestFiles( const std::string& identifier, const ghoul::filesystem::Directory& destination, int version, bool overrideFiles, DownloadFinishedCallback finishedCallback,