Merge pull request #4149 from huffman/improve-loading

Update ImageOverlay to use TextureCache
This commit is contained in:
Andrew Meadows 2015-01-22 09:26:10 -08:00
commit b2f2a3ad27
4 changed files with 56 additions and 57 deletions

View file

@ -22,88 +22,62 @@
#include "ImageOverlay.h" #include "ImageOverlay.h"
ImageOverlay::ImageOverlay() : ImageOverlay::ImageOverlay() :
_textureID(0), _imageURL(),
_renderImage(false), _renderImage(false),
_textureBound(false),
_wantClipFromImage(false) _wantClipFromImage(false)
{ {
_isLoaded = false;
} }
ImageOverlay::ImageOverlay(const ImageOverlay* imageOverlay) : ImageOverlay::ImageOverlay(const ImageOverlay* imageOverlay) :
Overlay2D(imageOverlay), Overlay2D(imageOverlay),
_texture(imageOverlay->_texture),
_imageURL(imageOverlay->_imageURL), _imageURL(imageOverlay->_imageURL),
_textureImage(imageOverlay->_textureImage), _textureImage(imageOverlay->_textureImage),
_textureID(0), _fromImage(imageOverlay->_fromImage),
_fromImage(),
_renderImage(imageOverlay->_renderImage), _renderImage(imageOverlay->_renderImage),
_textureBound(false), _wantClipFromImage(imageOverlay->_wantClipFromImage)
_wantClipFromImage(false)
{ {
} }
ImageOverlay::~ImageOverlay() { 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? // TODO: handle setting image multiple times, how do we manage releasing the bound texture?
void ImageOverlay::setImageURL(const QUrl& url) { void ImageOverlay::setImageURL(const QUrl& url) {
_imageURL = 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() { if (url.isEmpty()) {
QNetworkReply* reply = static_cast<QNetworkReply*>(sender()); _isLoaded = true;
_renderImage = false;
// replace our byte array with the downloaded data _texture.clear();
QByteArray rawData = reply->readAll(); } else {
_textureImage.loadFromData(rawData); _isLoaded = false;
_renderImage = true; _renderImage = true;
_isLoaded = true; }
reply->deleteLater();
} }
void ImageOverlay::render(RenderArgs* args) { void ImageOverlay::render(RenderArgs* args) {
if (!_visible || !_isLoaded) { if (!_isLoaded && _renderImage) {
return; // do nothing if we're not visible _isLoaded = true;
_texture = DependencyManager::get<TextureCache>()->getTexture(_imageURL);
} }
if (_renderImage && !_textureBound) {
_textureID = _parent->bindTexture(_textureImage); // If we are not visible or loaded, return. If we are trying to render an
_textureBound = true; // image but the texture hasn't loaded, return.
if (!_visible || !_isLoaded || (_renderImage && !_texture->isLoaded())) {
return;
} }
if (_renderImage) { if (_renderImage) {
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureID); glBindTexture(GL_TEXTURE_2D, _texture->getID());
} }
const float MAX_COLOR = 255.0f; const float MAX_COLOR = 255.0f;
xColor color = getColor(); xColor color = getColor();
float alpha = getAlpha(); float alpha = getAlpha();
glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
float imageWidth = _textureImage.width();
float imageHeight = _textureImage.height();
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 left = _bounds.left();
int right = _bounds.right() + 1; int right = _bounds.right() + 1;
int top = _bounds.top(); int top = _bounds.top();
@ -111,10 +85,29 @@ void ImageOverlay::render(RenderArgs* args) {
glm::vec2 topLeft(left, top); glm::vec2 topLeft(left, top);
glm::vec2 bottomRight(right, bottom); glm::vec2 bottomRight(right, bottom);
glm::vec2 texCoordTopLeft(x, 1.0f - y);
glm::vec2 texCoordBottomRight(x + w, 1.0f - (y + h));
if (_renderImage) { 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<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight); DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight);
} else { } else {
DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight); DependencyManager::get<GeometryCache>()->renderQuad(topLeft, bottomRight);
@ -153,7 +146,7 @@ void ImageOverlay::setProperties(const QScriptValue& properties) {
subImageRect.setHeight(oldSubImageRect.height()); subImageRect.setHeight(oldSubImageRect.height());
} }
setClipFromSource(subImageRect); setClipFromSource(subImageRect);
} }
QScriptValue imageURL = properties.property("imageURL"); QScriptValue imageURL = properties.property("imageURL");
if (imageURL.isValid()) { if (imageURL.isValid()) {

View file

@ -24,6 +24,7 @@
#include <NetworkAccessManager.h> #include <NetworkAccessManager.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <TextureCache.h>
#include "Overlay.h" #include "Overlay.h"
#include "Overlay2D.h" #include "Overlay2D.h"
@ -49,18 +50,14 @@ public:
virtual ImageOverlay* createClone() const; virtual ImageOverlay* createClone() const;
private slots:
void replyFinished(); // we actually want to hide this...
private: private:
QUrl _imageURL; QUrl _imageURL;
QImage _textureImage; QImage _textureImage;
GLuint _textureID; NetworkTexturePointer _texture;
QRect _fromImage; // where from in the image to sample 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 _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; bool _wantClipFromImage;
}; };

View file

@ -385,7 +385,9 @@ Texture::~Texture() {
NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content) : NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content) :
Resource(url, !content.isEmpty()), Resource(url, !content.isEmpty()),
_type(type), _type(type),
_translucent(false) { _translucent(false),
_width(0),
_height(0) {
if (!url.isValid()) { if (!url.isValid()) {
_loaded = true; _loaded = true;
@ -532,6 +534,8 @@ void NetworkTexture::loadContent(const QByteArray& content) {
void NetworkTexture::setImage(const QImage& image, bool translucent, const QColor& averageColor) { void NetworkTexture::setImage(const QImage& image, bool translucent, const QColor& averageColor) {
_translucent = translucent; _translucent = translucent;
_averageColor = averageColor; _averageColor = averageColor;
_width = image.width();
_height = image.height();
finishedLoading(true); finishedLoading(true);
imageLoaded(image); imageLoaded(image);

View file

@ -150,6 +150,9 @@ public:
/// Returns the lazily-computed average texture color. /// Returns the lazily-computed average texture color.
const QColor& getAverageColor() const { return _averageColor; } const QColor& getAverageColor() const { return _averageColor; }
int getWidth() const { return _width; }
int getHeight() const { return _height; }
protected: protected:
virtual void downloadFinished(QNetworkReply* reply); virtual void downloadFinished(QNetworkReply* reply);
@ -163,6 +166,8 @@ private:
TextureType _type; TextureType _type;
bool _translucent; bool _translucent;
QColor _averageColor; QColor _averageColor;
int _width;
int _height;
}; };
/// Caches derived, dilated textures. /// Caches derived, dilated textures.