From 53a70c43e1b6f2cbd4d99cc522945749b6f2f6d1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 21 Jan 2015 15:08:38 -0800 Subject: [PATCH 1/4] Add width and height to NetworkTexture --- libraries/render-utils/src/TextureCache.cpp | 6 +++++- libraries/render-utils/src/TextureCache.h | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libraries/render-utils/src/TextureCache.cpp b/libraries/render-utils/src/TextureCache.cpp index 3bd05a14ee..4c9abc74a1 100644 --- a/libraries/render-utils/src/TextureCache.cpp +++ b/libraries/render-utils/src/TextureCache.cpp @@ -385,7 +385,9 @@ Texture::~Texture() { NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content) : Resource(url, !content.isEmpty()), _type(type), - _translucent(false) { + _translucent(false), + _width(0), + _height(0) { if (!url.isValid()) { _loaded = true; @@ -532,6 +534,8 @@ void NetworkTexture::loadContent(const QByteArray& content) { void NetworkTexture::setImage(const QImage& image, bool translucent, const QColor& averageColor) { _translucent = translucent; _averageColor = averageColor; + _width = image.width(); + _height = image.height(); finishedLoading(true); imageLoaded(image); diff --git a/libraries/render-utils/src/TextureCache.h b/libraries/render-utils/src/TextureCache.h index 54c98a61cb..efcccc4b8c 100644 --- a/libraries/render-utils/src/TextureCache.h +++ b/libraries/render-utils/src/TextureCache.h @@ -150,6 +150,9 @@ public: /// Returns the lazily-computed average texture color. const QColor& getAverageColor() const { return _averageColor; } + int getWidth() const { return _width; } + int getHeight() const { return _height; } + protected: virtual void downloadFinished(QNetworkReply* reply); @@ -163,6 +166,8 @@ private: TextureType _type; bool _translucent; QColor _averageColor; + int _width; + int _height; }; /// Caches derived, dilated textures. From ba2f7d88ce3cdd7c8ad372457fc5cf9c7c709345 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 21 Jan 2015 15:09:09 -0800 Subject: [PATCH 2/4] Update ImageOverlay to use TextureCache --- interface/src/ui/overlays/ImageOverlay.cpp | 51 ++++++++-------------- interface/src/ui/overlays/ImageOverlay.h | 7 +-- 2 files changed, 19 insertions(+), 39 deletions(-) diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index 1ecfc74e44..164b3916db 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -22,9 +22,7 @@ #include "ImageOverlay.h" ImageOverlay::ImageOverlay() : - _textureID(0), _renderImage(false), - _textureBound(false), _wantClipFromImage(false) { _isLoaded = false; @@ -32,63 +30,48 @@ ImageOverlay::ImageOverlay() : ImageOverlay::ImageOverlay(const ImageOverlay* imageOverlay) : Overlay2D(imageOverlay), + _texture(imageOverlay->_texture), _imageURL(imageOverlay->_imageURL), _textureImage(imageOverlay->_textureImage), - _textureID(0), - _fromImage(), + _fromImage(imageOverlay->_fromImage), _renderImage(imageOverlay->_renderImage), - _textureBound(false), - _wantClipFromImage(false) + _wantClipFromImage(imageOverlay->_wantClipFromImage) { } ImageOverlay::~ImageOverlay() { - if (_parent && _textureID) { - // do we need to call this? - //_parent->deleteTexture(_textureID); - } } // TODO: handle setting image multiple times, how do we manage releasing the bound texture? void ImageOverlay::setImageURL(const QUrl& url) { _imageURL = url; _isLoaded = false; - QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url)); - connect(reply, &QNetworkReply::finished, this, &ImageOverlay::replyFinished); -} - -void ImageOverlay::replyFinished() { - QNetworkReply* reply = static_cast(sender()); - - // replace our byte array with the downloaded data - QByteArray rawData = reply->readAll(); - _textureImage.loadFromData(rawData); - _renderImage = true; - _isLoaded = true; - reply->deleteLater(); } void ImageOverlay::render(RenderArgs* args) { - if (!_visible || !_isLoaded) { - return; // do nothing if we're not visible + if (!_isLoaded && !_imageURL.isEmpty()) { + _isLoaded = true; + _renderImage = true; + qDebug() << "Now loding texture for ImageOverlay"; + _texture = DependencyManager::get()->getTexture(_imageURL); } - if (_renderImage && !_textureBound) { - _textureID = _parent->bindTexture(_textureImage); - _textureBound = true; + + if (!_visible || !_isLoaded || !_texture || !_texture->isLoaded()) { + return; } if (_renderImage) { + qDebug() << "Rendering: " << _imageURL << ", " << _texture->getWidth() << ", " << _texture->getHeight(); glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, _textureID); + glBindTexture(GL_TEXTURE_2D, _texture->getID()); } const float MAX_COLOR = 255.0f; xColor color = getColor(); float alpha = getAlpha(); glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); - float imageWidth = _textureImage.width(); - float imageHeight = _textureImage.height(); + float imageWidth = _texture->getWidth(); + float imageHeight = _texture->getHeight(); QRect fromImage; if (_wantClipFromImage) { @@ -111,8 +94,8 @@ void ImageOverlay::render(RenderArgs* args) { glm::vec2 topLeft(left, top); glm::vec2 bottomRight(right, bottom); - glm::vec2 texCoordTopLeft(x, 1.0f - y); - glm::vec2 texCoordBottomRight(x + w, 1.0f - (y + h)); + glm::vec2 texCoordTopLeft(x, y); + glm::vec2 texCoordBottomRight(x + w, y + h); if (_renderImage) { DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight); diff --git a/interface/src/ui/overlays/ImageOverlay.h b/interface/src/ui/overlays/ImageOverlay.h index cff557654f..e167c4e755 100644 --- a/interface/src/ui/overlays/ImageOverlay.h +++ b/interface/src/ui/overlays/ImageOverlay.h @@ -24,6 +24,7 @@ #include #include +#include #include "Overlay.h" #include "Overlay2D.h" @@ -49,18 +50,14 @@ public: virtual ImageOverlay* createClone() const; -private slots: - void replyFinished(); // we actually want to hide this... - private: QUrl _imageURL; QImage _textureImage; - GLuint _textureID; + NetworkTexturePointer _texture; QRect _fromImage; // where from in the image to sample bool _renderImage; // is there an image associated with this overlay, or is it just a colored rectangle - bool _textureBound; // has the texture been bound bool _wantClipFromImage; }; From 52193fce387e1d4511838d4d5691de25e8c62771 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 22 Jan 2015 08:35:38 -0800 Subject: [PATCH 3/4] Remove qDebug --- interface/src/ui/overlays/ImageOverlay.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index 164b3916db..b5c235d828 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -52,7 +52,6 @@ void ImageOverlay::render(RenderArgs* args) { if (!_isLoaded && !_imageURL.isEmpty()) { _isLoaded = true; _renderImage = true; - qDebug() << "Now loding texture for ImageOverlay"; _texture = DependencyManager::get()->getTexture(_imageURL); } From 0e9e77f1667c15a2ab032ed362c00c5a54e46914 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 22 Jan 2015 08:58:55 -0800 Subject: [PATCH 4/4] Fix broken support for color-only ImageOverlay --- interface/src/ui/overlays/ImageOverlay.cpp | 63 +++++++++++++--------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index b5c235d828..e18f99072f 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -22,10 +22,10 @@ #include "ImageOverlay.h" ImageOverlay::ImageOverlay() : + _imageURL(), _renderImage(false), _wantClipFromImage(false) { - _isLoaded = false; } ImageOverlay::ImageOverlay(const ImageOverlay* imageOverlay) : @@ -45,47 +45,39 @@ ImageOverlay::~ImageOverlay() { // TODO: handle setting image multiple times, how do we manage releasing the bound texture? void ImageOverlay::setImageURL(const QUrl& url) { _imageURL = url; - _isLoaded = false; + + if (url.isEmpty()) { + _isLoaded = true; + _renderImage = false; + _texture.clear(); + } else { + _isLoaded = false; + _renderImage = true; + } } void ImageOverlay::render(RenderArgs* args) { - if (!_isLoaded && !_imageURL.isEmpty()) { + if (!_isLoaded && _renderImage) { _isLoaded = true; - _renderImage = true; _texture = DependencyManager::get()->getTexture(_imageURL); } - if (!_visible || !_isLoaded || !_texture || !_texture->isLoaded()) { + // If we are not visible or loaded, return. If we are trying to render an + // image but the texture hasn't loaded, return. + if (!_visible || !_isLoaded || (_renderImage && !_texture->isLoaded())) { return; } if (_renderImage) { - qDebug() << "Rendering: " << _imageURL << ", " << _texture->getWidth() << ", " << _texture->getHeight(); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, _texture->getID()); } + const float MAX_COLOR = 255.0f; xColor color = getColor(); float alpha = getAlpha(); glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); - float imageWidth = _texture->getWidth(); - float imageHeight = _texture->getHeight(); - - QRect fromImage; - if (_wantClipFromImage) { - fromImage = _fromImage; - } else { - fromImage.setX(0); - fromImage.setY(0); - fromImage.setWidth(imageWidth); - fromImage.setHeight(imageHeight); - } - float x = fromImage.x() / imageWidth; - float y = fromImage.y() / imageHeight; - float w = fromImage.width() / imageWidth; // ?? is this what we want? not sure - float h = fromImage.height() / imageHeight; - int left = _bounds.left(); int right = _bounds.right() + 1; int top = _bounds.top(); @@ -93,10 +85,29 @@ void ImageOverlay::render(RenderArgs* args) { glm::vec2 topLeft(left, top); glm::vec2 bottomRight(right, bottom); - glm::vec2 texCoordTopLeft(x, y); - glm::vec2 texCoordBottomRight(x + w, y + h); if (_renderImage) { + float imageWidth = _texture->getWidth(); + float imageHeight = _texture->getHeight(); + + QRect fromImage; + if (_wantClipFromImage) { + fromImage = _fromImage; + } else { + fromImage.setX(0); + fromImage.setY(0); + fromImage.setWidth(imageWidth); + fromImage.setHeight(imageHeight); + } + + float x = fromImage.x() / imageWidth; + float y = fromImage.y() / imageHeight; + float w = fromImage.width() / imageWidth; // ?? is this what we want? not sure + float h = fromImage.height() / imageHeight; + + glm::vec2 texCoordTopLeft(x, y); + glm::vec2 texCoordBottomRight(x + w, y + h); + DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight); } else { DependencyManager::get()->renderQuad(topLeft, bottomRight); @@ -135,7 +146,7 @@ void ImageOverlay::setProperties(const QScriptValue& properties) { subImageRect.setHeight(oldSubImageRect.height()); } setClipFromSource(subImageRect); - } + } QScriptValue imageURL = properties.property("imageURL"); if (imageURL.isValid()) {