00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00045 try
00046 {
00047 string file = CPath::lookup(fileName);
00048 f.setAsyncLoading (asyncload);
00049 f.setCacheFileOnOpen (asyncload);
00050
00051
00052 if(asyncload && mipMapSkip>0)
00053 {
00054 f.setCacheFileOnOpen (false);
00055 f.allowBNPCacheFileOnOpen(false);
00056 }
00057
00058
00059 if (f.open(file))
00060 {
00061
00062 dest.load (f, mipMapSkip);
00063 }
00064 else throw EPathNotFound(fileName);
00065
00066
00067
00068
00069 if (dest.PixelFormat == RGBA)
00070 {
00071
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
00078 string file2 = CPath::lookup( path, false, false);
00079 if (!file2.empty())
00080 {
00081
00082 CBitmap bitmap;
00083 bitmap.loadGrayscaleAsAlpha (true);
00084
00085
00086 NLMISC::CIFile f2;
00087 f2.setAsyncLoading (asyncload);
00088 f2.setCacheFileOnOpen (asyncload);
00089 if (f2.open(file2))
00090 {
00091 bitmap.load(f2);
00092 }
00093 else throw EPathNotFound(file2);
00094
00095
00096 if ((dest.getWidth() == bitmap.getWidth()) && (dest.getHeight() == bitmap.getHeight()))
00097 {
00098
00099 if (bitmap.convertToType (CBitmap::Alpha))
00100 {
00101
00102 uint8 *userColor = (uint8 *)&(bitmap.getPixels ()[0]);
00103 CRGBA *color = (CRGBA *)&(dest.getPixels ()[0]);
00104
00105
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
00113 float Rt, Gt, Bt, At;
00114 float Lt;
00115 float Rtm, Gtm, Btm, Atm;
00116
00117
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
00124 At= (float)userColor[pixel]/255;
00125 Atm= 1-Lt*(1-At);
00126
00127
00128 if(Atm>0)
00129 {
00130 Rtm= Rt*At / Atm;
00131 Gtm= Gt*At / Atm;
00132 Btm= Bt*At / Atm;
00133 }
00134
00135 else
00136 {
00137 Rtm= Gtm= Btm= 0;
00138 }
00139
00140
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
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
00173 dest.makeDummy();
00174 nlwarning("Missing textureFile: %s (%s)", fileName.c_str(), e.what());
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
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
00203
00204
00205
00206
00207 sint ver= f.serialVersion(1);
00208
00209
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
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 }