# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

texture_file.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "std3d.h"
00027 
00028 #include "3d/texture_file.h"
00029 #include "nel/misc/file.h"
00030 #include "nel/misc/path.h"
00031 #include "nel/misc/debug.h"
00032 using namespace std;
00033 using namespace NLMISC;
00034 
00035 
00036 namespace NL3D
00037 {
00038 
00039 
00041 void CTextureFile::buildBitmapFromFile(NLMISC::CBitmap &dest, const std::string &fileName, bool asyncload, uint8 mipMapSkip)
00042 {
00043         NLMISC::CIFile f;
00044         //nldebug(_FileName.c_str());
00045         try
00046         {
00047                 string file = CPath::lookup(fileName);
00048                 f.setAsyncLoading (asyncload);
00049                 f.setCacheFileOnOpen (asyncload);
00050 
00051                 // if mipmap skip, must not cache, because don't have to load all!!
00052                 if(asyncload && mipMapSkip>0)
00053                 {
00054                         f.setCacheFileOnOpen (false);
00055                         f.allowBNPCacheFileOnOpen(false);
00056                 }
00057 
00058                 // Load bitmap.
00059                 if (f.open(file))
00060                 {
00061                         // skip DDS mipmap if wanted
00062                         dest.load (f, mipMapSkip);
00063                 }
00064                 else throw EPathNotFound(fileName);
00065 
00066                 // *** Need usercolor computing ?
00067 
00068                 // Texture not compressed ?
00069                 if (dest.PixelFormat == RGBA)
00070                 {
00071                         // Make a filename
00072                         string path = CFile::getFilename(fileName);
00073                         string ext = strrchr (fileName.c_str(), '.');
00074                         path.resize (path.size () - ext.size());
00075                         path += "_usercolor" + ext;
00076 
00077                         // Loopup the texture
00078                         string file2 = CPath::lookup( path, false, false);
00079                         if (!file2.empty())
00080                         {
00081                                 // The file2 exist, load and compute it
00082                                 CBitmap bitmap;
00083                                 bitmap.loadGrayscaleAsAlpha (true);
00084 
00085                                 // Open and read the file2
00086                                 NLMISC::CIFile f2;
00087                                 f2.setAsyncLoading (asyncload);
00088                                 f2.setCacheFileOnOpen (asyncload); // Same as async loading
00089                                 if (f2.open(file2))
00090                                 {
00091                                         bitmap.load(f2);
00092                                 }
00093                                 else throw EPathNotFound(file2);
00094 
00095                                 // Texture are the same size ?
00096                                 if ((dest.getWidth() == bitmap.getWidth()) && (dest.getHeight() == bitmap.getHeight()))
00097                                 {
00098                                         // Convert in Alpha
00099                                         if (bitmap.convertToType (CBitmap::Alpha))
00100                                         {
00101                                                 // Compute it
00102                                                 uint8 *userColor = (uint8 *)&(bitmap.getPixels ()[0]);
00103                                                 CRGBA *color = (CRGBA *)&(dest.getPixels ()[0]);
00104 
00105                                                 // For each pixel
00106                                                 uint pixelCount = dest.getWidth()*dest.getHeight();
00107                                                 uint pixel;
00108                                                 for (pixel = 0; pixel<pixelCount; pixel++)
00109                                                 {
00110                                                         if (userColor[pixel]==0) 
00111                                                         {
00112                                                                 // New code: use new restrictions from IDriver.
00113                                                                 float   Rt, Gt, Bt, At;
00114                                                                 float   Lt;
00115                                                                 float   Rtm, Gtm, Btm, Atm;
00116 
00117                                                                 // read 0-1 RGB pixel.
00118                                                                 Rt= (float)color[pixel].R/255;
00119                                                                 Gt= (float)color[pixel].G/255;
00120                                                                 Bt= (float)color[pixel].B/255;
00121                                                                 Lt= Rt*0.3f + Gt*0.56f + Bt*0.14f;
00122 
00123                                                                 // take Alpha from userColor src.
00124                                                                 At= (float)userColor[pixel]/255;
00125                                                                 Atm= 1-Lt*(1-At);
00126 
00127                                                                 // If normal case.
00128                                                                 if(Atm>0)
00129                                                                 {
00130                                                                         Rtm= Rt*At / Atm;
00131                                                                         Gtm= Gt*At / Atm;
00132                                                                         Btm= Bt*At / Atm;
00133                                                                 }
00134                                                                 // Else special case: At==0, and Lt==1.
00135                                                                 else
00136                                                                 {
00137                                                                         Rtm= Gtm= Btm= 0;
00138                                                                 }
00139 
00140                                                                 // copy to buffer.
00141                                                                 sint    r,g,b,a;
00142                                                                 r= (sint)(Rtm*255+0.5f);
00143                                                                 g= (sint)(Gtm*255+0.5f);
00144                                                                 b= (sint)(Btm*255+0.5f);
00145                                                                 a= (sint)(Atm*255+0.5f);
00146                                                                 clamp(r, 0,255);
00147                                                                 clamp(g, 0,255);
00148                                                                 clamp(b, 0,255);
00149                                                                 clamp(a, 0,255);
00150                                                                 color[pixel].R = (uint8)r;
00151                                                                 color[pixel].G = (uint8)g;
00152                                                                 color[pixel].B = (uint8)b;
00153                                                                 color[pixel].A = (uint8)a;
00154                                                         }
00155                                                 }
00156                                         }
00157                                         else
00158                                         {
00159                                                 nlinfo ("Can't convert the usercolor texture %s in alpha mode", file2.c_str());
00160                                         }
00161                                 }
00162                                 else
00163                                 {
00164                                         // Error
00165                                         nlinfo ("User color texture is not the same size than the texture. (Tex : %s, Usercolor : %s)", file.c_str(), file2.c_str());
00166                                 }
00167                         }
00168                 }
00169         }
00170         catch(EPathNotFound &e)
00171         {
00172                 // Not found...
00173                 dest.makeDummy();
00174                 nlwarning("Missing textureFile: %s (%s)", fileName.c_str(), e.what());
00175         }
00176 }
00177 
00178 
00179 /*==================================================================*\
00180                                                         CTEXTUREFILE
00181 \*==================================================================*/
00182 
00183 /*------------------------------------------------------------------*\
00184                                                         doGenerate()
00185 \*------------------------------------------------------------------*/
00186 void CTextureFile::doGenerate()
00187 {
00188         buildBitmapFromFile(*this, _FileName, _AsyncLoading, _MipMapSkipAtLoad);
00189 }
00190 
00191 // ***************************************************************************
00192 void CTextureFile::setAsyncLoading (bool isAsync)
00193 {
00194         _AsyncLoading = isAsync;
00195 }
00196 
00197 
00198 // ***************************************************************************
00199 void    CTextureFile::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00200 {
00201         /*
00202         Version 1:
00203                 - AllowDegradation.
00204         Version 0:
00205                 - base version.
00206         */
00207         sint    ver= f.serialVersion(1);
00208 
00209         // serial the base part of ITexture.
00210         ITexture::serial(f);
00211 
00212         f.serial(_FileName);
00213         if(ver>=1)
00214                 f.serial(_AllowDegradation);
00215         else if(f.isReading())
00216                 _AllowDegradation= true;
00217 
00218         if(f.isReading())
00219                 touch();
00220 }
00221 
00222 
00223 // ***************************************************************************
00224 void    CTextureFile::setAllowDegradation(bool allow)
00225 {
00226         _AllowDegradation= allow;
00227 }
00228 
00229 // ***************************************************************************
00230 CTextureFile::CTextureFile(const CTextureFile &other) : ITexture(other)
00231 {
00232         dupInfo(other);
00233 }
00234 
00235 // ***************************************************************************
00236 CTextureFile &CTextureFile::operator = (const CTextureFile &other)
00237 {
00238         // copy base infos
00239         (ITexture &) *this = (ITexture &) other;
00240         dupInfo(other);
00241         return *this;
00242 }
00243 
00244 // ***************************************************************************
00245 void CTextureFile::dupInfo(const CTextureFile &other)
00246 {
00247         _FileName         = other._FileName;
00248         _AsyncLoading     =     other._AsyncLoading;
00249         _AllowDegradation = other._AllowDegradation;
00250         _SupportSharing   = other._SupportSharing;
00251         _MipMapSkipAtLoad = other._MipMapSkipAtLoad; 
00252 }
00253 
00254 
00255 // ***************************************************************************
00256 void                    CTextureFile::enableSharing(bool enable)
00257 {
00258         _SupportSharing = enable;
00259 }
00260 
00261 // ***************************************************************************
00262 void                    CTextureFile::setMipMapSkipAtLoad(uint8 level)
00263 {
00264         _MipMapSkipAtLoad= level;
00265 }
00266 
00267 // ***************************************************************************
00268 std::string             CTextureFile::getShareName() const
00269 {
00270         string  ret= _FileName;
00271         strlwr(ret);
00272         return ret;
00273 }
00274 
00275 
00276 } // NL3D