} if (opaquePixels == imageArea) { qDebug() << "Image with alpha channel is completely opaque:" << _url; image = image.convertToFormat(QImage::Format_RGB888); } QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image), Q_ARG(bool, translucentPixels >= imageArea / 2), Q_ARG(const QColor&, QColor(redTotal / imageArea, greenTotal / imageArea, blueTotal / imageArea, alphaTotal / imageArea)));} void NetworkTexture::downloadFinished(QNetworkReply* reply) { // send the reader off to the thread pool QThreadPool::globalInstance()->start(new ImageReader(_self, reply));} void NetworkTexture::loadContent(const QByteArray& content) { QThreadPool::globalInstance()->start(new ImageReader(_self, NULL, _url, content));} void NetworkTexture::setImage(const QImage& image, bool translucent, const QColor& averageColor) { _translucent = translucent; _averageColor = averageColor; finishedLoading(true); imageLoaded(image); glBindTexture(GL_TEXTURE_2D, getID()); if (image.hasAlphaChannel()) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits()); } else { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits()); } // generate mipmaps glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0);} void NetworkTexture::imageLoaded(const QImage& image) { // nothing by default} DilatableNetworkTexture::DilatableNetworkTexture(const QUrl& url, const QByteArray& content) : NetworkTexture(url, DEFAULT_TEXTURE, content), _innerRadius(0), _outerRadius(0){} QSharedPointer<Texture> DilatableNetworkTexture::getDilatedTexture(float dilation) { QSharedPointer<Texture> texture = _dilatedTextures.value(dilation); if (texture.isNull()) { texture = QSharedPointer<Texture>(new Texture()); if (!_image.isNull()) { QImage dilatedImage = _image; QPainter painter; painter.begin(&dilatedImage); QPainterPath path; qreal radius = glm::mix((float) _innerRadius, (float) _outerRadius, dilation); path.addEllipse(QPointF(_image.width() / 2.0, _image.height() / 2.0), radius, radius); painter.fillPath(path, Qt::black); painter.end(); glBindTexture(GL_TEXTURE_2D, texture->getID()); if (dilatedImage.hasAlphaChannel()) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dilatedImage.width(), dilatedImage.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, dilatedImage.constBits()); } else { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dilatedImage.width(), dilatedImage.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, dilatedImage.constBits()); } glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); } _dilatedTextures.insert(dilation, texture); } return texture;} void DilatableNetworkTexture::imageLoaded(const QImage& image) { _image = image; // scan out from the center to find inner and outer radii int halfWidth = image.width() / 2; int halfHeight = image.height() / 2; const int BLACK_THRESHOLD = 32; while (_innerRadius < halfWidth && qGray(image.pixel(halfWidth + _innerRadius, halfHeight)) < BLACK_THRESHOLD) { _innerRadius++; } _outerRadius = _innerRadius; const int TRANSPARENT_THRESHOLD = 32; while (_outerRadius < halfWidth && qAlpha(image.pixel(halfWidth + _outerRadius, halfHeight)) > TRANSPARENT_THRESHOLD) { _outerRadius++; } // clear out any textures we generated before loading _dilatedTextures.clear();} void DilatableNetworkTexture::reinsert() { static_cast<TextureCache*>(_cache.data())->_dilatableNetworkTextures.insert(_url, qWeakPointerCast<NetworkTexture, Resource>(_self)); } Lines 501–608 of 608. Previous lines
} if (opaquePixels == imageArea) { qDebug() << "Image with alpha channel is completely opaque:" << _url; image = image.convertToFormat(QImage::Format_RGB888); } QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image), Q_ARG(bool, translucentPixels >= imageArea / 2), Q_ARG(const QColor&, QColor(redTotal / imageArea, greenTotal / imageArea, blueTotal / imageArea, alphaTotal / imageArea))); } void NetworkTexture::downloadFinished(QNetworkReply* reply) { // send the reader off to the thread pool QThreadPool::globalInstance()->start(new ImageReader(_self, reply)); } void NetworkTexture::loadContent(const QByteArray& content) { QThreadPool::globalInstance()->start(new ImageReader(_self, NULL, _url, content)); } void NetworkTexture::setImage(const QImage& image, bool translucent, const QColor& averageColor) { _translucent = translucent; _averageColor = averageColor; finishedLoading(true); imageLoaded(image); glBindTexture(GL_TEXTURE_2D, getID()); if (image.hasAlphaChannel()) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, image.constBits()); } else { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits()); } // generate mipmaps glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); } void NetworkTexture::imageLoaded(const QImage& image) { // nothing by default } DilatableNetworkTexture::DilatableNetworkTexture(const QUrl& url, const QByteArray& content) : NetworkTexture(url, DEFAULT_TEXTURE, content), _innerRadius(0), _outerRadius(0) { } QSharedPointer<Texture> DilatableNetworkTexture::getDilatedTexture(float dilation) { QSharedPointer<Texture> texture = _dilatedTextures.value(dilation); if (texture.isNull()) { texture = QSharedPointer<Texture>(new Texture()); if (!_image.isNull()) { QImage dilatedImage = _image; QPainter painter; painter.begin(&dilatedImage); QPainterPath path; qreal radius = glm::mix((float) _innerRadius, (float) _outerRadius, dilation); path.addEllipse(QPointF(_image.width() / 2.0, _image.height() / 2.0), radius, radius); painter.fillPath(path, Qt::black); painter.end(); glBindTexture(GL_TEXTURE_2D, texture->getID()); if (dilatedImage.hasAlphaChannel()) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dilatedImage.width(), dilatedImage.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, dilatedImage.constBits()); } else { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dilatedImage.width(), dilatedImage.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, dilatedImage.constBits()); } glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); } _dilatedTextures.insert(dilation, texture); } return texture; } void DilatableNetworkTexture::imageLoaded(const QImage& image) { _image = image; // scan out from the center to find inner and outer radii int halfWidth = image.width() / 2; int halfHeight = image.height() / 2; const int BLACK_THRESHOLD = 32; while (_innerRadius < halfWidth && qGray(image.pixel(halfWidth + _innerRadius, halfHeight)) < BLACK_THRESHOLD) { _innerRadius++; } _outerRadius = _innerRadius; const int TRANSPARENT_THRESHOLD = 32; while (_outerRadius < halfWidth && qAlpha(image.pixel(halfWidth + _outerRadius, halfHeight)) > TRANSPARENT_THRESHOLD) { _outerRadius++; } // clear out any textures we generated before loading _dilatedTextures.clear(); } void DilatableNetworkTexture::reinsert() { static_cast<TextureCache*>(_cache.data())->_dilatableNetworkTextures.insert(_url, qWeakPointerCast<NetworkTexture, Resource>(_self)); }