Remove file texture loading (since we can just use file URLs), don't add alpha

channels for opaque textures (and note when textures with alpha channels are
entirely opaque), enforce a maximum texture size of 1024 by 1024.
This commit is contained in:
Andrzej Kapolka 2014-03-19 16:11:15 -07:00
parent 08c5c49891
commit e34f2ca69b
2 changed files with 40 additions and 32 deletions

View file

@ -38,9 +38,6 @@ TextureCache::~TextureCache() {
if (_whiteTextureID != 0) {
glDeleteTextures(1, &_whiteTextureID);
}
foreach (GLuint id, _fileTextureIDs) {
glDeleteTextures(1, &id);
}
if (_primaryFramebufferObject) {
glDeleteTextures(1, &_primaryDepthTextureID);
}
@ -104,23 +101,6 @@ GLuint TextureCache::getBlueTextureID() {
return _blueTextureID;
}
GLuint TextureCache::getFileTextureID(const QString& filename) {
GLuint id = _fileTextureIDs.value(filename);
if (id == 0) {
QImage image = QImage(filename).convertToFormat(QImage::Format_ARGB32);
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1,
GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
_fileTextureIDs.insert(filename, id);
}
return id;
}
QSharedPointer<NetworkTexture> TextureCache::getTexture(const QUrl& url, bool normalMap, bool dilatable) {
if (!dilatable) {
return ResourceCache::getResource(url, QUrl(), false, &normalMap).staticCast<NetworkTexture>();
@ -293,27 +273,50 @@ void ImageReader::run() {
_reply->deleteLater();
return;
}
QUrl url = _reply->url();
QImage image = QImage::fromData(_reply->readAll());
_reply->deleteLater();
// enforce a fixed maximum
const int MAXIMUM_SIZE = 1024;
if (image.width() > MAXIMUM_SIZE || image.height() > MAXIMUM_SIZE) {
qDebug() << "Image greater than maximum size:" << url << image.width() << image.height();
image = image.scaled(MAXIMUM_SIZE, MAXIMUM_SIZE, Qt::KeepAspectRatio);
}
if (!image.hasAlphaChannel()) {
if (image.format() != QImage::Format_RGB888) {
image = image.convertToFormat(QImage::Format_RGB888);
}
QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image), Q_ARG(bool, false));
return;
}
if (image.format() != QImage::Format_ARGB32) {
image = image.convertToFormat(QImage::Format_ARGB32);
}
// check for translucency
// check for translucency/false transparency
int opaquePixels = 0;
int translucentPixels = 0;
const int EIGHT_BIT_MAXIMUM = 255;
const int RGB_BITS = 24;
for (int y = 0; y < image.height(); y++) {
for (int x = 0; x < image.width(); x++) {
int alpha = image.pixel(x, y) >> RGB_BITS;
if (alpha != 0 && alpha != EIGHT_BIT_MAXIMUM) {
if (alpha == EIGHT_BIT_MAXIMUM) {
opaquePixels++;
} else if (alpha != 0) {
translucentPixels++;
}
}
}
int imageArea = image.width() * image.height();
if (opaquePixels == imageArea) {
qDebug() << "Image with alpha channel is completely opaque:" << url;
image.convertToFormat(QImage::Format_RGB888);
}
QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image),
Q_ARG(bool, translucentPixels >= imageArea / 2));
_reply->deleteLater();
}
void NetworkTexture::downloadFinished(QNetworkReply* reply) {
@ -327,8 +330,13 @@ void NetworkTexture::setImage(const QImage& image, bool translucent) {
finishedLoading(true);
imageLoaded(image);
glBindTexture(GL_TEXTURE_2D, getID());
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1,
GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
if (image.hasAlphaChannel()) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 1,
GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 1,
GL_RGB, GL_UNSIGNED_BYTE, image.constBits());
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
}
@ -360,8 +368,13 @@ QSharedPointer<Texture> DilatableNetworkTexture::getDilatedTexture(float dilatio
painter.end();
glBindTexture(GL_TEXTURE_2D, texture->getID());
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dilatedImage.width(), dilatedImage.height(), 1,
GL_BGRA, GL_UNSIGNED_BYTE, dilatedImage.constBits());
if (dilatedImage.hasAlphaChannel()) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dilatedImage.width(), dilatedImage.height(), 1,
GL_BGRA, GL_UNSIGNED_BYTE, dilatedImage.constBits());
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dilatedImage.width(), dilatedImage.height(), 1,
GL_RGB, GL_UNSIGNED_BYTE, dilatedImage.constBits());
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
}

View file

@ -39,9 +39,6 @@ public:
/// Returns the ID of a pale blue texture (useful for a normal map).
GLuint getBlueTextureID();
/// Returns the ID of a texture containing the contents of the specified file, loading it if necessary.
GLuint getFileTextureID(const QString& filename);
/// Loads a texture from the specified URL.
QSharedPointer<NetworkTexture> getTexture(const QUrl& url, bool normalMap = false, bool dilatable = false);
@ -84,8 +81,6 @@ private:
GLuint _whiteTextureID;
GLuint _blueTextureID;
QHash<QString, GLuint> _fileTextureIDs;
QHash<QUrl, QWeakPointer<NetworkTexture> > _dilatableNetworkTextures;
GLuint _primaryDepthTextureID;