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

SourceForge.net Logo

©2005-2011 Laurent Ribon