• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KGLLib

texture.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008 Rivo Laks <rivolaks@hot.ee>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either 
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public 
00015  * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #include <texture.h>
00019 
00020 #include <renderer.h>
00021 
00022 #include <qpixmap.h>
00023 #include <qimage.h>
00024 #include <qrect.h>
00025 #include <qstring.h>
00026 #include <QtDebug>
00027 
00028 
00029 namespace
00030 {
00031 
00032 GLint determineFormat(GLint internalformat)
00033 {
00034     switch (internalformat) {
00035         // From OpenGL 2.1 spec
00036         case GL_ALPHA:
00037         case GL_ALPHA4:
00038         case GL_ALPHA8:
00039         case GL_ALPHA12:
00040         case GL_ALPHA16:
00041             return GL_ALPHA;
00042         case GL_DEPTH_COMPONENT16:
00043         case GL_DEPTH_COMPONENT24:
00044         case GL_DEPTH_COMPONENT32:
00045             return GL_DEPTH_COMPONENT;
00046         case GL_LUMINANCE:
00047         case GL_LUMINANCE4:
00048         case GL_LUMINANCE8:
00049         case GL_LUMINANCE12:
00050         case GL_LUMINANCE16:
00051             return GL_LUMINANCE;
00052         case GL_LUMINANCE_ALPHA:
00053         case GL_LUMINANCE4_ALPHA4:
00054         case GL_LUMINANCE6_ALPHA2:
00055         case GL_LUMINANCE8_ALPHA8:
00056         case GL_LUMINANCE12_ALPHA4:
00057         case GL_LUMINANCE12_ALPHA12:
00058         case GL_LUMINANCE16_ALPHA16:
00059             return GL_LUMINANCE_ALPHA;
00060         case GL_INTENSITY:
00061         case GL_INTENSITY4:
00062         case GL_INTENSITY8:
00063         case GL_INTENSITY12:
00064         case GL_INTENSITY16:
00065             return GL_INTENSITY;
00066         case GL_R3_G3_B2:
00067         case GL_RGB:
00068         case GL_RGB4:
00069         case GL_RGB5:
00070         case GL_RGB8:
00071         case GL_RGB10:
00072         case GL_RGB12:
00073         case GL_RGB16:
00074             return GL_RGB;
00075         case GL_RGBA:
00076         case GL_RGBA2:
00077         case GL_RGBA4:
00078         case GL_RGB5_A1:
00079         case GL_RGBA8:
00080         case GL_RGB10_A2:
00081         case GL_RGBA12:
00082         case GL_RGBA16:
00083             return GL_RGBA;
00084         // sRGB
00085         case GL_SRGB8:              return GL_RGB;
00086         case GL_SRGB8_ALPHA8:       return GL_RGBA;
00087         case GL_SLUMINANCE:         return GL_LUMINANCE;
00088         case GL_SLUMINANCE8_ALPHA8: return GL_LUMINANCE_ALPHA;
00089         // Generic compressed formats
00090         case GL_COMPRESSED_ALPHA:           return GL_ALPHA;
00091         case GL_COMPRESSED_LUMINANCE:       return GL_LUMINANCE;
00092         case GL_COMPRESSED_LUMINANCE_ALPHA: return GL_LUMINANCE_ALPHA;
00093         case GL_COMPRESSED_INTENSITY:       return GL_INTENSITY;
00094         case GL_COMPRESSED_RGB:             return GL_RGB;
00095         case GL_COMPRESSED_RGBA:            return GL_RGBA;
00096         case GL_COMPRESSED_SRGB:            return GL_RGB;
00097         case GL_COMPRESSED_SRGB_ALPHA:      return GL_RGBA;
00098         case GL_COMPRESSED_SLUMINANCE:      return GL_LUMINANCE;
00099         case GL_COMPRESSED_SLUMINANCE_ALPHA: return GL_LUMINANCE_ALPHA;
00100         // From EXT_texture_compression_s3tc extension
00101         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
00102             return GL_RGB;
00103         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
00104         case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
00105         case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
00106             return GL_RGBA;
00107         // From ARB_texture_float extension
00108         case GL_RGBA32F_ARB:                return GL_RGBA;
00109         case GL_RGB32F_ARB:                 return GL_RGB;
00110         case GL_ALPHA32F_ARB:               return GL_ALPHA;
00111         case GL_INTENSITY32F_ARB:           return GL_INTENSITY;
00112         case GL_LUMINANCE32F_ARB:           return GL_LUMINANCE;
00113         case GL_LUMINANCE_ALPHA32F_ARB:     return GL_LUMINANCE_ALPHA;
00114         case GL_RGBA16F_ARB:                return GL_RGBA;
00115         case GL_RGB16F_ARB:                 return GL_RGB;
00116         case GL_ALPHA16F_ARB:               return GL_ALPHA;
00117         case GL_INTENSITY16F_ARB:           return GL_INTENSITY;
00118         case GL_LUMINANCE16F_ARB:           return GL_LUMINANCE;
00119         case GL_LUMINANCE_ALPHA16F_ARB:     return GL_LUMINANCE_ALPHA;
00120 
00121         default:
00122             return 0;
00123     }
00124 }
00125 
00126 GLint determineDataType(GLint internalformat)
00127 {
00128     switch (internalformat) {
00129         case GL_RGBA32F_ARB:
00130         case GL_RGB32F_ARB:
00131         case GL_ALPHA32F_ARB:
00132         case GL_INTENSITY32F_ARB:
00133         case GL_LUMINANCE32F_ARB:
00134         case GL_LUMINANCE_ALPHA32F_ARB:
00135             return GL_FLOAT;
00136         case GL_RGBA16F_ARB:
00137         case GL_RGB16F_ARB:
00138         case GL_ALPHA16F_ARB:
00139         case GL_INTENSITY16F_ARB:
00140         case GL_LUMINANCE16F_ARB:
00141         case GL_LUMINANCE_ALPHA16F_ARB:
00142             return GL_HALF_FLOAT_ARB;
00143 
00144         default:
00145             return GL_UNSIGNED_BYTE;
00146     }
00147 }
00148 
00149 }
00150 
00151 namespace KGLLib
00152 {
00153 
00154 /*** TextureBase ***/
00155 TextureBase::TextureBase()
00156 {
00157     mValid = false;
00158     mGLId = 0;
00159 }
00160 
00161 TextureBase::TextureBase(const QString& name)
00162 {
00163     mValid = false;
00164     mGLId = 0;
00165     setName(name);
00166 }
00167 
00168 TextureBase::~TextureBase()
00169 {
00170     if (mGLId) {
00171         glDeleteTextures(1, &mGLId);
00172     }
00173 }
00174 
00175 void TextureBase::bind() const
00176 {
00177     renderer->bindTexture(this);
00178 }
00179 
00180 void TextureBase::unbind() const
00181 {
00182     renderer->unbindTexture(this);
00183 }
00184 
00185 void TextureBase::enable(bool _bind) const
00186 {
00187     renderer->enableTexture(this);
00188     if (_bind) {
00189         bind();
00190     }
00191 }
00192 
00193 void TextureBase::disable(bool _unbind) const
00194 {
00195     renderer->disableTexture(this);
00196     if (_unbind) {
00197         unbind();
00198     }
00199 }
00200 
00201 void TextureBase::setFilter(GLenum filter)
00202 {
00203     GLenum magfilter = (filter == GL_NEAREST) ? GL_NEAREST : GL_LINEAR;
00204     glTexParameteri(glTarget(), GL_TEXTURE_MAG_FILTER, magfilter);
00205     glTexParameteri(glTarget(), GL_TEXTURE_MIN_FILTER, filter);
00206 }
00207 
00208 void TextureBase::setWrapMode(GLenum coordinate, GLenum mode)
00209 {
00210     glTexParameteri(glTarget(), coordinate, mode);
00211 }
00212 
00213 void TextureBase::setName(const QString& name)
00214 {
00215     mName = name;
00216 }
00217 
00218 QString TextureBase::debugString() const
00219 {
00220     if (name().isEmpty()) {
00221         return QString("<Texture id %1>").arg(glId());
00222     } else {
00223         return QString("<Texture name %1>").arg(name());
00224     }
00225 }
00226 
00227 
00228 /*** Texture ***/
00229 Texture::Texture(int width, int height, GLint internalformat, GLint format)
00230 {
00231     mValid = init(width, height, internalformat, format);
00232 }
00233 
00234 Texture::Texture(const QImage& img, GLenum filter)
00235 {
00236     mValid = init(img, filter);
00237 }
00238 
00239 Texture::Texture(const QPixmap& pix, GLenum filter)
00240 {
00241     mValid = init(pix.toImage(), filter);
00242 }
00243 
00244 Texture::Texture(const QString& filename, GLenum filter) : TextureBase(filename)
00245 {
00246     mValid = init(filename, filter);
00247 }
00248 
00249 Texture::~Texture()
00250 {
00251 }
00252 
00253 bool Texture::init(int width, int height, GLint internalformat, GLint format)
00254 {
00255     mWidth = width;
00256     mHeight = height;
00257 
00258     glGenTextures(1, &mGLId);
00259     bind();
00260     setFilter(GL_LINEAR);
00261 
00262     if (!format) {
00263         format = determineFormat(internalformat);
00264         if (!format) {
00265             qCritical() << "Texture::init(): Couldn't determine matching format for internalformat" << internalformat;
00266             return false;
00267         }
00268     }
00269     mInternalFormat = internalformat;
00270     mFormat = format;
00271     glTexImage2D( glTarget(), 0, mInternalFormat, mWidth, mHeight, 0,
00272         mFormat, determineDataType(mInternalFormat), 0);
00273 
00274     checkGLError(QString("Texture::init(%1, %2)").arg(mWidth).arg(mHeight));
00275 
00276     return true;
00277 }
00278 
00279 bool Texture::init(const QImage& img, GLenum filter)
00280 {
00281     if (img.isNull()) {
00282         qWarning() << "Texture::init(): NULL QImage!";
00283         return false;
00284     }
00285     if (!init(img.width(), img.height())) {
00286         return false;
00287     }
00288 
00289     setFilter(filter);
00290     QImage glimg = convertToGLFormat( img );
00291     // TODO: make sure generate_mipmap is supported and use gluBuild2DMipmaps if it isn't
00292     // TODO: generate mipmaps only if filter requires them
00293     glTexParameteri(glTarget(), GL_GENERATE_MIPMAP, GL_TRUE);
00294     glTexImage2D( glTarget(), 0, mInternalFormat, glimg.width(), glimg.height(), 0,
00295         mFormat, GL_UNSIGNED_BYTE, glimg.bits());
00296     checkGLError("Texture::init(Qimage)");
00297 
00298     return true;
00299 }
00300 
00301 bool Texture::init(const QString& filename, GLenum filter)
00302 {
00303     QImage img(filename);
00304     if (img.isNull()) {
00305         qWarning() << "Texture::init(): failed to load from file" << filename;
00306         return false;
00307     }
00308     return init(img, filter);
00309 }
00310 
00311 void Texture::setWrapMode(GLenum mode)
00312 {
00313     TextureBase::setWrapMode(GL_TEXTURE_WRAP_S, mode);
00314     TextureBase::setWrapMode(GL_TEXTURE_WRAP_T, mode);
00315 }
00316 
00317 QImage Texture::convertToGLFormat(const QImage& img) const
00318 {
00319     // This method has been copied from Qt's QGLWidget::convertToGLFormat()
00320     QImage res = img.convertToFormat(QImage::Format_ARGB32);
00321     res = res.mirrored();
00322 
00323     if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
00324         // Qt has ARGB; OpenGL wants RGBA
00325         for (int i=0; i < res.height(); i++) {
00326             uint *p = (uint*)res.scanLine(i);
00327             uint *end = p + res.width();
00328             while (p < end) {
00329                 *p = (*p << 8) | ((*p >> 24) & 0xFF);
00330                 p++;
00331             }
00332         }
00333     } else {
00334         // Qt has ARGB; OpenGL wants ABGR (i.e. RGBA backwards)
00335         res = res.rgbSwapped();
00336     }
00337     return res;
00338 }
00339 
00340 
00341 /*** Texture ***/
00342 
00343 Texture3D::~Texture3D()
00344 {
00345 }
00346 
00347 void Texture3D::setWrapMode(GLenum mode)
00348 {
00349     TextureBase::setWrapMode(GL_TEXTURE_WRAP_S, mode);
00350     TextureBase::setWrapMode(GL_TEXTURE_WRAP_T, mode);
00351     TextureBase::setWrapMode(GL_TEXTURE_WRAP_R, mode);
00352 }
00353 
00354 }
00355 

KGLLib

Skip menu "KGLLib"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • KGLLib
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal