glc_texture.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  Version 2.0.0, packaged on July 2010.
00006 
00007  http://glc-lib.sourceforge.net
00008 
00009  GLC-lib is free software; you can redistribute it and/or modify
00010  it under the terms of the GNU Lesser General Public License as published by
00011  the Free Software Foundation; either version 3 of the License, or
00012  (at your option) any later version.
00013 
00014  GLC-lib is distributed in the hope that it will be useful,
00015  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  GNU Lesser General Public License for more details.
00018 
00019  You should have received a copy of the GNU Lesser General Public License
00020  along with GLC-lib; if not, write to the Free Software
00021  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023 *****************************************************************************/
00024 
00026 
00027 
00028 #include "glc_texture.h"
00029 #include "../glc_exception.h"
00030 #include "../glc_global.h"
00031 
00032 // Quazip library
00033 #include "../quazip/quazip.h"
00034 #include "../quazip/quazipfile.h"
00035 
00036 #include <QtDebug>
00037 
00038 // The default maximum texture size
00039 QSize GLC_Texture::m_MaxTextureSize(676, 676);
00040 
00041 // The Minimum texture size
00042 const QSize GLC_Texture::m_MinTextureSize(10, 10);
00043 
00044 QHash<GLuint, int> GLC_Texture::m_TextureIdUsage;
00045 
00047 // Constructor Destructor
00049 
00051 GLC_Texture::GLC_Texture(const QGLContext *pContext)
00052 : m_pQGLContext(const_cast<QGLContext*>(pContext))
00053 , m_FileName()
00054 , m_GlTextureID(0)
00055 , m_textureImage()
00056 , m_TextureSize()
00057 , m_HasAlphaChannel(false)
00058 {
00059 
00060 }
00061 
00062 // Constructor with fileName
00063 GLC_Texture::GLC_Texture(const QGLContext *pContext, const QString &Filename)
00064 : m_pQGLContext(const_cast<QGLContext*>(pContext))
00065 , m_FileName(Filename)
00066 , m_GlTextureID(0)
00067 , m_textureImage(loadFromFile(m_FileName))
00068 , m_TextureSize()
00069 , m_HasAlphaChannel(m_textureImage.hasAlphaChannel())
00070 {
00071         if (m_textureImage.isNull())
00072         {
00073                 QString ErrorMess("GLC_Texture::GLC_Texture open image : ");
00074                 ErrorMess.append(m_FileName).append(" Failed");
00075                 qDebug() << ErrorMess;
00076                 GLC_Exception e(ErrorMess);
00077                 throw(e);
00078         }
00079 }
00080 // Constructor with QFile
00081 GLC_Texture::GLC_Texture(const QGLContext *pContext, const QFile &file)
00082 : m_pQGLContext(const_cast<QGLContext*>(pContext))
00083 , m_FileName(file.fileName())
00084 , m_GlTextureID(0)
00085 , m_textureImage()
00086 , m_TextureSize()
00087 , m_HasAlphaChannel(m_textureImage.hasAlphaChannel())
00088 {
00089         m_textureImage.load(const_cast<QFile*>(&file), QFileInfo(m_FileName).suffix().toLocal8Bit());
00090         if (m_textureImage.isNull())
00091         {
00092                 QString ErrorMess("GLC_Texture::GLC_Texture open image : ");
00093                 ErrorMess.append(m_FileName).append(" Failed");
00094                 qDebug() << ErrorMess;
00095                 GLC_Exception e(ErrorMess);
00096                 throw(e);
00097         }
00098 }
00099 
00100 // Constructor with QImage
00101 GLC_Texture::GLC_Texture(const QGLContext* pContext, const QImage& image, const QString& fileName)
00102 : m_pQGLContext(const_cast<QGLContext*>(pContext))
00103 , m_FileName(fileName)
00104 , m_GlTextureID(0)
00105 , m_textureImage(image)
00106 , m_TextureSize()
00107 , m_HasAlphaChannel(m_textureImage.hasAlphaChannel())
00108 {
00109         Q_ASSERT(!m_textureImage.isNull());
00110 }
00111 
00112 GLC_Texture::GLC_Texture(const GLC_Texture &TextureToCopy)
00113 : m_pQGLContext(TextureToCopy.m_pQGLContext)
00114 , m_FileName(TextureToCopy.m_FileName)
00115 , m_GlTextureID(TextureToCopy.m_GlTextureID)
00116 , m_textureImage(TextureToCopy.m_textureImage)
00117 , m_TextureSize(TextureToCopy.m_TextureSize)
00118 , m_HasAlphaChannel(m_textureImage.hasAlphaChannel())
00119 {
00120         if (m_textureImage.isNull())
00121         {
00122                 QString ErrorMess("GLC_Texture::GLC_Texture open image : ");
00123                 ErrorMess.append(m_FileName).append(" Failed");
00124                 qDebug() << ErrorMess;
00125                 GLC_Exception e(ErrorMess);
00126                 throw(e);
00127         }
00128         addThisOpenGLTextureId();
00129 
00130 }
00131 
00132 // Overload "=" operator
00133 GLC_Texture& GLC_Texture::operator=(const GLC_Texture& texture)
00134 {
00135         if (!(*this == texture))
00136         {
00137                 removeThisOpenGLTextureId();
00138                 m_pQGLContext= texture.m_pQGLContext;
00139                 m_FileName= texture.m_FileName;
00140                 m_GlTextureID= texture.m_GlTextureID;
00141                 addThisOpenGLTextureId();
00142                 m_textureImage= texture.m_textureImage;
00143                 m_TextureSize= texture.m_TextureSize;
00144                 m_HasAlphaChannel= m_textureImage.hasAlphaChannel();
00145         }
00146 
00147         return *this;
00148 }
00149 
00150 GLC_Texture::~GLC_Texture()
00151 {
00152         //qDebug() << "GLC_Texture::~GLC_Texture Texture ID : " << m_GlTextureID;
00153         removeThisOpenGLTextureId();
00154 }
00156 // Get Functions
00158 
00159 // Return true if texture are the same
00160 bool GLC_Texture::operator==(const GLC_Texture& texture) const
00161 {
00162         bool result;
00163         if (this == &texture)
00164         {
00165                 result= true;
00166         }
00167         else
00168         {
00169                 result= (m_FileName == texture.m_FileName) && (m_textureImage == texture.m_textureImage);
00170         }
00171         return result;
00172 }
00173 
00175 // Set Functions
00177 
00178 // Set the maximum texture size
00179 void GLC_Texture::setMaxTextureSize(const QSize& size)
00180 {
00181         if ((size.height() > m_MinTextureSize.height()) && (size.width() > m_MinTextureSize.width()))
00182         {
00183                 m_MaxTextureSize= size;
00184         }
00185         else
00186         {
00187                 qDebug() << "GLC_Texture::setMaxTextureSize m_MaxTextureSize set to m_MinTextureSize";
00188                 m_MaxTextureSize= m_MinTextureSize;
00189         }
00190 }
00191 
00193 // Private OpenGL functions
00195 // Load the texture
00196 void GLC_Texture::glLoadTexture(void)
00197 {
00198         if (m_GlTextureID == 0)
00199         {
00200                 if (NULL == m_pQGLContext)
00201                 {
00202                         m_pQGLContext= const_cast<QGLContext*>(QGLContext::currentContext());
00203                 }
00204                 // Test image size
00205                 if ((m_textureImage.height() > m_MaxTextureSize.height())
00206                                 || (m_textureImage.width() > m_MaxTextureSize.width()))
00207                 {
00208                         QImage rescaledImage;
00209                         if(m_textureImage.height() > m_textureImage.width())
00210                         {
00211                                 rescaledImage= m_textureImage.scaledToHeight(m_MaxTextureSize.height(), Qt::SmoothTransformation);
00212                         }
00213                         else
00214                         {
00215                                 rescaledImage= m_textureImage.scaledToWidth(m_MaxTextureSize.width(), Qt::SmoothTransformation);
00216                         }
00217                         m_textureImage= rescaledImage;
00218                         m_TextureSize= m_textureImage.size();
00219                 }
00220                 else
00221                 {
00222                         m_TextureSize= m_textureImage.size();
00223                 }
00224                 m_GlTextureID= m_pQGLContext->bindTexture(m_textureImage);
00225                 addThisOpenGLTextureId();
00226 
00227                 //qDebug() << "GLC_Texture::glcBindTexture Texture ID = " << m_GlTextureID;
00228         }
00229 }
00230 
00231 // Bind texture in 2D mode
00232 void GLC_Texture::glcBindTexture(void)
00233 {
00234         if (m_GlTextureID == 0)
00235         {
00236                 glLoadTexture();
00237         }
00238         glBindTexture(GL_TEXTURE_2D, m_GlTextureID);
00239         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00240         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00241 }
00242 
00243 QImage GLC_Texture::loadFromFile(const QString& fileName)
00244 {
00245         QImage resultImage;
00246         if (glc::isArchiveString(fileName))
00247         {
00248 
00249                 // Load the image from a zip archive
00250                 QuaZip* p3dxmlArchive= new QuaZip(glc::archiveFileName(fileName));
00251                 // Trying to load archive
00252                 if(!p3dxmlArchive->open(QuaZip::mdUnzip))
00253                 {
00254                   delete p3dxmlArchive;
00255                   return QImage();
00256                 }
00257                 else
00258                 {
00259                         // Set the file Name Codec
00260                         p3dxmlArchive->setFileNameCodec("IBM866");
00261                 }
00262                 QString imageFileName= glc::archiveEntryFileName(fileName);
00263 
00264                 // Create QuaZip File
00265                 QuaZipFile* p3dxmlFile= new QuaZipFile(p3dxmlArchive);
00266 
00267                 // Get the file of the 3dxml
00268                 if (!p3dxmlArchive->setCurrentFile(imageFileName, QuaZip::csInsensitive))
00269                 {
00270                         delete p3dxmlFile;
00271                         delete p3dxmlArchive;
00272                         return QImage();
00273                 }
00274 
00275                 // Open the file of the 3dxml
00276                 if(!p3dxmlFile->open(QIODevice::ReadOnly))
00277             {
00278                         delete p3dxmlFile;
00279                         delete p3dxmlArchive;
00280                         return QImage();
00281             }
00282                 resultImage.load(p3dxmlFile, QFileInfo(imageFileName).suffix().toLocal8Bit());
00283                 p3dxmlFile->close();
00284                 delete p3dxmlFile;
00285                 delete p3dxmlArchive;
00286         }
00287         else
00288         {
00289                 resultImage.load(fileName);
00290         }
00291 
00292         return resultImage;
00293 }
00294 
00295 void GLC_Texture::removeThisOpenGLTextureId()
00296 {
00297         if ( 0 != m_GlTextureID)
00298         {
00299                 Q_ASSERT(m_TextureIdUsage.contains(m_GlTextureID));
00300                 --m_TextureIdUsage[m_GlTextureID];
00301                 if (m_TextureIdUsage.value(m_GlTextureID) == 0)
00302                 {
00303                         m_pQGLContext->deleteTexture(m_GlTextureID);
00304                         m_TextureIdUsage.remove(m_GlTextureID);
00305                         m_GlTextureID= 0;
00306                 }
00307         }
00308 }
00309 
00310 void GLC_Texture::addThisOpenGLTextureId()
00311 {
00312         if (0 != m_GlTextureID)
00313         {
00314                 if (m_TextureIdUsage.contains(m_GlTextureID))
00315                 {
00316                         ++m_TextureIdUsage[m_GlTextureID];
00317                 }
00318                 else
00319                 {
00320                         m_TextureIdUsage.insert(m_GlTextureID, 1);
00321                 }
00322         }
00323 }
00324 
00325 // Non-member stream operator
00326 QDataStream &operator<<(QDataStream &stream, const GLC_Texture &texture)
00327 {
00328         stream << texture.fileName();
00329 
00330         return stream;
00331 }
00332 QDataStream &operator>>(QDataStream &stream, GLC_Texture &texture)
00333 {
00334         QString fileName;
00335         stream >> fileName;
00336         texture= GLC_Texture(texture.context(), fileName);
00337 
00338         return stream;
00339 }
00340 

SourceForge.net Logo

©2005-2010 Laurent Ribon