From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/async__texture__manager_8cpp-source.html | 865 +++++++++++++++++++++ 1 file changed, 865 insertions(+) create mode 100644 docs/doxygen/nel/async__texture__manager_8cpp-source.html (limited to 'docs/doxygen/nel/async__texture__manager_8cpp-source.html') diff --git a/docs/doxygen/nel/async__texture__manager_8cpp-source.html b/docs/doxygen/nel/async__texture__manager_8cpp-source.html new file mode 100644 index 00000000..1f04a66c --- /dev/null +++ b/docs/doxygen/nel/async__texture__manager_8cpp-source.html @@ -0,0 +1,865 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# 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  
+

async_texture_manager.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000-2002 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/async_texture_manager.h"
+00029 #include "3d/async_file_manager_3d.h"
+00030 #include "3d/mesh_base_instance.h"
+00031 #include "3d/driver.h"
+00032 
+00033 
+00034 using   namespace std;
+00035 using   namespace NLMISC;
+00036 
+00037 namespace NL3D 
+00038 {
+00039 
+00040 // ***************************************************************************
+00041 #define NL3D_ATM_MIN_DISTANCE           1.0f
+00042 
+00043 // ***************************************************************************
+00044 CAsyncTextureManager::CTextureEntry::CTextureEntry()
+00045 {
+00046         IsTextureEntry= true;
+00047 
+00048         Loaded= false;
+00049         UpLoaded= false;
+00050         CanHaveLOD= false;
+00051         BuildFromHLSManager= false;
+00052         HLSManagerTextId= -1;
+00053         BaseSize= 0;
+00054         TotalTextureSizeAsked= 0;
+00055 }
+00056 
+00057 
+00058 // ***************************************************************************
+00059 void            CAsyncTextureManager::CTextureEntry::createCoarseBitmap()
+00060 {
+00061         // the texture must exist.
+00062         nlassert(Texture);
+00063         nlassert(Texture->getSize()>0);
+00064 
+00065         // copy the bitmap.
+00066         CoarseBitmap= *Texture;
+00067         // remove all mipmaps, and convert to DXTC1 (if possible, ie if was DXTC5 or DXTC3 as example)
+00068         CoarseBitmap.releaseMipMaps();
+00069         // TODODO: consersion to DXTC1
+00070         CoarseBitmap.convertToType(CBitmap::DXTC1);
+00071 }
+00072 
+00073 
+00074 // ***************************************************************************
+00075 CAsyncTextureManager::CTextureLod::CTextureLod()
+00076 {
+00077         IsTextureEntry= false;
+00078 
+00079         TextureEntry= NULL;
+00080         Weight= 0;
+00081         Level= 0;
+00082         Loaded= false;
+00083         UpLoaded= false;
+00084         ExtraSize= 0;
+00085 }
+00086 
+00087 
+00088 // ***************************************************************************
+00089 CAsyncTextureManager::~CAsyncTextureManager()
+00090 {
+00091         // For all remaining textures, delete them.
+00092         for(uint i=0;i<_TextureEntries.size();i++)
+00093         {
+00094                 if(_TextureEntries[i])
+00095                         deleteTexture(i);
+00096         }
+00097 
+00098         // there must be no waitting textures, nor map, nor current upload texture
+00099         nlassert(_WaitingTextures.empty() && _TextureEntryMap.empty() && _CurrentUploadTexture==NULL 
+00100                 && _CurrentTextureLodLoaded==NULL);
+00101 }
+00102 
+00103 // ***************************************************************************
+00104 CAsyncTextureManager::CAsyncTextureManager()
+00105 {
+00106         _BaseLodLevel= 3;
+00107         _MaxLodLevel= 1;
+00108         _MaxUploadPerFrame= 65536;
+00109         _MaxHLSColoringPerFrame= 20*1024;
+00110         _CurrentUploadTexture= NULL;
+00111         _MaxTotalTextureSize= 10*1024*1024;
+00112         _TotalTextureSizeAsked= 0;
+00113         _LastTextureSizeGot= 0;
+00114 
+00115         // Do not share this texture, to force uploading of the lods.
+00116         _CurrentTextureLodLoaded= NULL;
+00117 }
+00118 
+00119 
+00120 // ***************************************************************************
+00121 void                    CAsyncTextureManager::setupLod(uint baseLevel, uint maxLevel)
+00122 {
+00123         nlassert(baseLevel>=maxLevel);
+00124         _BaseLodLevel= baseLevel;
+00125         _MaxLodLevel= maxLevel;
+00126 }
+00127 
+00128 
+00129 // ***************************************************************************
+00130 void                    CAsyncTextureManager::setupMaxUploadPerFrame(uint maxup)
+00131 {
+00132         if(maxup>0)
+00133                 _MaxUploadPerFrame= maxup;
+00134 }
+00135 
+00136 // ***************************************************************************
+00137 void                    CAsyncTextureManager::setupMaxHLSColoringPerFrame(uint maxCol)
+00138 {
+00139         if(maxCol>0)
+00140                 _MaxHLSColoringPerFrame= maxCol;
+00141 }
+00142 
+00143 // ***************************************************************************
+00144 void                    CAsyncTextureManager::setupMaxTotalTextureSize(uint maxText)
+00145 {
+00146         _MaxTotalTextureSize= maxText;
+00147 }
+00148 
+00149 
+00150 // ***************************************************************************
+00151 uint                    CAsyncTextureManager::addTextureRef(const string &textNameNotLwr, CMeshBaseInstance *instance)
+00152 {
+00153         uint    ret;
+00154 
+00155         // strlwr name
+00156         string  textName= textNameNotLwr;
+00157         strlwr(textName);
+00158 
+00159         // find the texture in map
+00160         ItTextureEntryMap       it;
+00161         it= _TextureEntryMap.find(textName);
+00162 
+00163         // not found, create.
+00164         if(it==_TextureEntryMap.end())
+00165         {
+00166                 // search a free id.
+00167                 uint    i= _TextureEntries.size();
+00168                 if(!_FreeTextureIds.empty())
+00169                 {
+00170                         i= _FreeTextureIds.back();
+00171                         _FreeTextureIds.pop_back();
+00172                 }
+00173                 // resize if needed.
+00174                 if(i>=_TextureEntries.size())
+00175                 {
+00176                         _TextureEntries.push_back(NULL);
+00177                         _FreeTextureIds.reserve(_TextureEntries.capacity());
+00178                 }
+00179 
+00180                 // alloc new.
+00181                 CTextureEntry   *text= new CTextureEntry();
+00182                 _TextureEntries[i]= text;
+00183                 text->Texture= new CTextureFile;
+00184                 // Do not allow degradation.
+00185                 text->Texture->setAllowDegradation(false);
+00186 
+00187                 // add to map.
+00188                 it= _TextureEntryMap.insert(make_pair(textName, i)).first;
+00189                 // bkup the it for deletion
+00190                 text->ItMap= it;
+00191 
+00192                 // Start Color or Async loading.
+00193                 text->Texture->setFileName(textName);
+00194                 // First try with the HLSManager
+00195                 sint    colorTextId= HLSManager.findTexture(textName);
+00196                 // If found
+00197                 if(colorTextId!=-1)
+00198                 {
+00199                         // Mark the texture as Loaded, and ready to colorize (done in update()).
+00200                         text->Loaded= true;
+00201                         text->BuildFromHLSManager= true;
+00202                         text->HLSManagerTextId= colorTextId;
+00203                 }
+00204                 // else must async load it.
+00205                 else
+00206                 {
+00207                         // start to load a small DDS version if possible
+00208                         text->Texture->setMipMapSkipAtLoad(_BaseLodLevel);
+00209                         // load it async.
+00210                         CAsyncFileManager3D::getInstance().loadTexture(text->Texture, &text->Loaded);
+00211                 }
+00212                 // Add to a list so we can check each frame if it has ended.
+00213                 _WaitingTextures.push_back(i);
+00214         }
+00215 
+00216         // get the id of the text entry.
+00217         ret= it->second;
+00218 
+00219         // add this instance to the list of ones which use this texture.
+00220         CTextureEntry   *text= _TextureEntries[ret];
+00221         text->Instances.push_back(instance);
+00222 
+00223         // if the texture is not yet ready, must increment the instance refCount.
+00224         if(!text->UpLoaded)
+00225                 instance->_AsyncTextureToLoadRefCount++;
+00226 
+00227         return ret;
+00228 }
+00229 
+00230 
+00231 // ***************************************************************************
+00232 void                    CAsyncTextureManager::deleteTexture(uint id)
+00233 {
+00234         CTextureEntry   *text= _TextureEntries[id];
+00235 
+00236 
+00237         // **** Stop AsyncLoading/UpLoading of main texture.
+00238 
+00239         // stop async loading if not ended
+00240         if(!text->Loaded)
+00241         {
+00242                 CAsyncFileManager3D::getInstance().cancelLoadTexture(text->Texture);
+00243         }
+00244 
+00245         // remove map entry
+00246         _TextureEntryMap.erase(text->ItMap);
+00247 
+00248         // remove in list of waiting textures
+00249         vector<uint>::iterator  itWait= find(_WaitingTextures.begin(),_WaitingTextures.end(), id);
+00250         if(itWait!=_WaitingTextures.end())
+00251                 _WaitingTextures.erase(itWait);
+00252 
+00253         // If it was the currently uploaded one, abort
+00254         if(_CurrentUploadTexture==text)
+00255         {
+00256                 _CurrentUploadTexture= NULL;
+00257         }
+00258 
+00259         // If not uploaded.
+00260         if(!text->UpLoaded)
+00261         {
+00262                 // For all its remainding instances, dec refcount
+00263                 for(uint i=0;i<text->Instances.size();i++)
+00264                 {
+00265                         text->Instances[i]->_AsyncTextureToLoadRefCount--;
+00266                 }
+00267         }
+00268 
+00269         // remove from bench
+00270         _TotalTextureSizeAsked-= text->TotalTextureSizeAsked;
+00271 
+00272 
+00273         // **** Stop AsyncLoading/UpLoading of HDLod 's texture.
+00274 
+00275         // Check if must stop TextureLod loading/uploading.
+00276         CTextureLod             *textLod= &text->HDLod;
+00277         if(textLod==_CurrentTextureLodLoaded)
+00278         {
+00279                 // stop the async loading if not ended.
+00280                 if(!textLod->Loaded)
+00281                 {
+00282                         CAsyncFileManager3D::getInstance().cancelLoadTexture(textLod->Texture);
+00283                 }
+00284                 // stop uploading if was me
+00285                 if(_CurrentUploadTexture==textLod)
+00286                 {
+00287                         _CurrentUploadTexture= NULL;
+00288                 }
+00289                 // stop loading me.
+00290                 _CurrentTextureLodLoaded= NULL;
+00291         }
+00292 
+00293         // At last delete texture entry.
+00294         delete text;
+00295         _TextureEntries[id]= NULL;
+00296         // add a new free id.
+00297         _FreeTextureIds.push_back(id);
+00298 }
+00299 
+00300 
+00301 // ***************************************************************************
+00302 void                    CAsyncTextureManager::releaseTexture(uint id, CMeshBaseInstance *instance)
+00303 {
+00304         nlassert(id<_TextureEntries.size());
+00305         nlassert(_TextureEntries[id]);
+00306 
+00307         // find an instance in this texture an remove it.
+00308         CTextureEntry   *text= _TextureEntries[id];
+00309         uint                    instSize= text->Instances.size();
+00310         for(uint i=0;i<instSize;i++)
+00311         {
+00312                 if(text->Instances[i]== instance)
+00313                 {
+00314                         // Must first release the refCount if the texture is not uploaded
+00315                         if(!text->UpLoaded)
+00316                                 text->Instances[i]->_AsyncTextureToLoadRefCount--;
+00317                         // remove it by swapping with last texture
+00318                         text->Instances[i]= text->Instances[instSize-1];
+00319                         text->Instances.pop_back();
+00320                         // must stop: remove only the first occurence of instance.
+00321                         break;
+00322                 }
+00323         }
+00324 
+00325         // if no more instance occurence, the texture is no more used => release it.
+00326         if(text->Instances.empty())
+00327         {
+00328                 // do all the good stuff
+00329                 deleteTexture(id);
+00330         }
+00331 }
+00332 
+00333 // ***************************************************************************
+00334 bool                    CAsyncTextureManager::isTextureUpLoaded(uint id) const
+00335 {
+00336         nlassert(id<_TextureEntries.size());
+00337         nlassert(_TextureEntries[id]);
+00338         return _TextureEntries[id]->UpLoaded;
+00339 }
+00340 
+00341 
+00342 // ***************************************************************************
+00343 const NLMISC::CBitmap   *CAsyncTextureManager::getCoarseBitmap(uint id) const
+00344 {
+00345         if(id>=_TextureEntries.size())
+00346                 return NULL;
+00347         CTextureEntry   *textEntry= _TextureEntries[id];
+00348         if(!textEntry)
+00349                 return NULL;
+00350 
+00351         // if the textEntry not uploaded, return NULL
+00352         if(!textEntry->UpLoaded)
+00353                 return NULL;
+00354 
+00355         // ok return the CoarseBitmap
+00356         return &textEntry->CoarseBitmap;
+00357 }
+00358 
+00359 
+00360 // ***************************************************************************
+00361 void                    CAsyncTextureManager::update(IDriver *pDriver)
+00362 {
+00363         uint    nTotalUploaded = 0;
+00364         uint    nTotalColored = 0;
+00365 
+00366         // if no texture to upload, get the next one
+00367         if(_CurrentUploadTexture==NULL)
+00368                 getNextTextureToUpLoad(nTotalColored, pDriver);
+00369 
+00370         // while some texture to upload
+00371         while(_CurrentUploadTexture)
+00372         {
+00373                 ITexture        *pText= _CurrentUploadTexture->Texture;
+00374                 if(uploadTexturePart(pText, pDriver, nTotalUploaded))
+00375                 {
+00376                         // Stuff for TextureEntry
+00377                         if(_CurrentUploadTexture->isTextureEntry())
+00378                         {
+00379                                 uint    i;
+00380                                 CTextureEntry   *textEntry= static_cast<CTextureEntry*>(_CurrentUploadTexture);
+00381                                 // If we are here, the texture is finally entirely uploaded. Compile it!
+00382                                 textEntry->UpLoaded= true;
+00383                                 // Can Have lod if texture is DXTC and have mipMaps! Also disalbe if system disable it
+00384                                 textEntry->CanHaveLOD= validDXTCMipMap(pText) && _BaseLodLevel>_MaxLodLevel;
+00385                                 // compute the size it takes in VRAM
+00386                                 uint    baseMipMapSize= pText->getSize(0)*CBitmap::bitPerPixels[pText->getPixelFormat()]/8;
+00387                                 // full size with mipmap
+00388                                 textEntry->BaseSize= (uint)(baseMipMapSize*1.33f);
+00389                                 // UpLoaded !! => signal all instances.
+00390                                 for(i=0;i<textEntry->Instances.size();i++)
+00391                                 {
+00392                                         textEntry->Instances[i]->_AsyncTextureToLoadRefCount--;
+00393                                 }
+00394 
+00395                                 // Create the coarse bitmap with the text (NB: still in memory here)
+00396                                 textEntry->createCoarseBitmap();
+00397 
+00398                                 // If CanHaveLOD, create now the lods entries.
+00399                                 if(textEntry->CanHaveLOD)
+00400                                 {
+00401                                         /* Allow only the MaxLod to be loaded async
+00402                                                 This is supposed to be faster since a fseek is much longer than a texture Read.
+00403                                                 Then it is more intelligent to read only One texture (the High Def), than to try to
+00404                                                 read intermediate ones (512, 256, 128) because this made 3 more fseek.
+00405                                         */
+00406                                         // create only the MaxLod possible entry
+00407                                         CTextureLod             &textLod= textEntry->HDLod;
+00408                                         // fill textLod
+00409                                         textLod.TextureEntry= textEntry;
+00410                                         textLod.Level= _MaxLodLevel;
+00411                                         // extra size of the lod only (important for LoadBalacing in updateTextureLodSystem())
+00412                                         textLod.ExtraSize= textEntry->BaseSize*(1<<(2*(_BaseLodLevel-_MaxLodLevel))) - textEntry->BaseSize;
+00413                                         // not yet loaded/upLoaded
+00414                                         textLod.Loaded= false;
+00415                                         textLod.UpLoaded= false;
+00416                                 }
+00417 
+00418                                 // compute texture size for bench
+00419                                 textEntry->TotalTextureSizeAsked= textEntry->BaseSize + textEntry->HDLod.ExtraSize;
+00420 
+00421                                 // Add texture size to global texture size
+00422                                 _TotalTextureSizeAsked+= textEntry->TotalTextureSizeAsked;
+00423                         }
+00424                         // else, stuff for textureLod.
+00425                         else
+00426                         {
+00427                                 CTextureLod             *textLod= static_cast<CTextureLod*>(_CurrentUploadTexture);
+00428                                 // Swap the uploaded Driver Handle with the Main texture.
+00429                                 pDriver->swapTextureHandle(*textLod->Texture, *textLod->TextureEntry->Texture);
+00430                                 // Flag the Lod.
+00431                                 textLod->UpLoaded= true;
+00432                                 // Ok, ended to completly load this textureLod.
+00433                                 _CurrentTextureLodLoaded= NULL;
+00434                         }
+00435 
+00436                         // finally uploaded in VRAM, can release the RAM texture memory
+00437                         pText->release();
+00438 
+00439                         // if not break because can't upload all parts, get next texture to upload
+00440                         _CurrentUploadTexture= NULL;
+00441                         getNextTextureToUpLoad(nTotalColored, pDriver);
+00442                 }
+00443                 else
+00444                         // Fail to upload all, abort.
+00445                         return;
+00446         }
+00447 }
+00448 
+00449 
+00450 // ***************************************************************************
+00451 bool                    CAsyncTextureManager::uploadTexturePart(ITexture *pText, IDriver *pDriver, uint &nTotalUploaded)
+00452 {
+00453         uint            nMipMap;
+00454         nMipMap = pText->getMipMapCount();
+00455 
+00456 
+00457         // If this is the start of uploading, setup the texture in driver.
+00458         if(_CurrentUploadTextureMipMap==0 && _CurrentUploadTextureLine==0)
+00459         {
+00460                 // If the texture is not a valid DXTC with mipmap
+00461                 if(!validDXTCMipMap(pText))
+00462                 {
+00463                         /* For now, prefer do nothing, because this may be an error (texture not found)
+00464                                 and the texture may not be used at all, so don't take VRAM for nothing.
+00465                                 => if the texture is used, it will be loaded synchronously by the caller later in the process
+00466                                 => frame freeze.
+00467                         */
+00468                         /*
+00469                         // upload All now.
+00470                         // MipMap generation and compression may be done here => Maybe Big Freeze.
+00471                         // approximate*2 instead of *1.33 for mipmaps.
+00472                         uint    nWeight = pText->getSize (0) * 2;
+00473                         nWeight= (nWeight*CBitmap::bitPerPixels[pText->getPixelFormat()])/8;
+00474                         nTotalUploaded+= nWeight;
+00475                         pDriver->setupTexture(*pText);
+00476                         return true;*/
+00477                         return true;
+00478                 }
+00479                 else
+00480                 {
+00481                         // Create the texture only and do not upload anything
+00482                         bool isRel = pText->getReleasable ();
+00483                         pText->setReleasable (false);
+00484                         bool isAllUploaded = false;
+00485                         /* Even if the shared texture is still referenced and so still exist in driver, we MUST recreate with good size
+00486                                 the texture. This is important for Texture Memory Load Balancing
+00487                                 (this may means that is used elsewhere than in the CAsyncTextureManager)
+00488                                 Hence: bMustRecreateSharedTexture==true
+00489                         */
+00490                         pDriver->setupTextureEx (*pText, false, isAllUploaded, true);
+00491                         pText->setReleasable (isRel);
+00492                         // if the texture is already uploaded, abort partial uploading.
+00493                         if (isAllUploaded)
+00494                                 return true;
+00495                 }
+00496         }
+00497 
+00498 
+00499         // try to upload all mipmap
+00500         for(; _CurrentUploadTextureMipMap<nMipMap; _CurrentUploadTextureMipMap++)
+00501         {
+00502                 CRect zeRect;
+00503                 uint nMM= _CurrentUploadTextureMipMap;
+00504 
+00505                 // What is left to upload ?
+00506                 uint    nWeight = pText->getSize (nMM) - _CurrentUploadTextureLine*pText->getWidth(nMM);
+00507                 nWeight= (nWeight*CBitmap::bitPerPixels[pText->getPixelFormat()])/8;
+00508 
+00509                 if ((nTotalUploaded  + nWeight) > _MaxUploadPerFrame)
+00510                 {
+00511                         // We cannot upload the whole mipmap -> we have to cut it
+00512                         uint nSizeToUpload = _MaxUploadPerFrame - nTotalUploaded ;
+00513                         uint nLineWeight = (pText->getWidth(nMM)*CBitmap::bitPerPixels[pText->getPixelFormat()])/8;
+00514                         uint nNbLineToUpload = nSizeToUpload / nLineWeight;
+00515                         // Upload 4 line by 4 line, and upload at leat one 4*line.
+00516                         nNbLineToUpload = nNbLineToUpload / 4;
+00517                         nNbLineToUpload= max(nNbLineToUpload, 1U);
+00518                         nNbLineToUpload *= 4;
+00519                         // comput rect to upload
+00520                         uint32 nNewLine = _CurrentUploadTextureLine + nNbLineToUpload;
+00521                         nNewLine= min(nNewLine, pText->getHeight(nMM));
+00522                         zeRect.set (0, _CurrentUploadTextureLine, pText->getWidth(nMM), nNewLine);
+00523                         _CurrentUploadTextureLine = nNewLine;
+00524                         // if fill all the mipmap, must go to next
+00525                         if (_CurrentUploadTextureLine == pText->getHeight(nMM))
+00526                         {
+00527                                 _CurrentUploadTextureLine = 0;
+00528                                 _CurrentUploadTextureMipMap++;
+00529                         }
+00530                 }
+00531                 else
+00532                 {
+00533                         // We can upload the whole mipmap (or the whole rest of the mipmap)
+00534                         zeRect.set (0, _CurrentUploadTextureLine, pText->getWidth(nMM), pText->getHeight(nMM));
+00535                         _CurrentUploadTextureLine= 0;
+00536                 }
+00537 
+00538                 // upload the texture 
+00539                 pDriver->uploadTexture (*pText, zeRect, (uint8)nMM);
+00540 
+00541                 nTotalUploaded += nWeight;
+00542                 // If outpass max allocated upload, abort.
+00543                 if (nTotalUploaded > _MaxUploadPerFrame)
+00544                         return false;
+00545         }
+00546 
+00547         return true;
+00548 }
+00549 
+00550 
+00551 // ***************************************************************************
+00552 void                    CAsyncTextureManager::getNextTextureToUpLoad(uint &nTotalColored, IDriver *pDriver)
+00553 {
+00554         // Reset texture uploading
+00555         _CurrentUploadTexture= NULL;
+00556         _CurrentUploadTextureMipMap= 0;
+00557         _CurrentUploadTextureLine= 0;
+00558 
+00559         // Search in WaitingTextures if one has ended async loading
+00560         vector<uint>::iterator  it;
+00561         for(it=_WaitingTextures.begin();it!=_WaitingTextures.end();it++)
+00562         {
+00563                 CTextureEntry   *text= _TextureEntries[*it];
+00564                 // If Async loading done.
+00565                 if(text->Loaded)
+00566                 {
+00567                         // Is it a "texture to color" with HLSManager? yes=> color it now.
+00568                         if(text->BuildFromHLSManager)
+00569                         {
+00570                                 // If not beyond the max coloring texture
+00571                                 if(nTotalColored<_MaxHLSColoringPerFrame)
+00572                                 {
+00573                                         // Build the texture directly in the TextureFile.
+00574                                         nlverify(HLSManager.buildTexture(text->HLSManagerTextId, *text->Texture));
+00575                                         // Must validate the textureFile generation. NB: little weird since this is not really a textureFile.
+00576                                         // But it is the easier way to do it.
+00577                                         text->Texture->validateGenerateFlag();
+00578                                         // compute the texture size (approx). NB: DXTC5 means 1 pixel==1 byte.
+00579                                         uint    size= (uint)(text->Texture->getSize(0)*1.33);
+00580                                         // Add it to the num of colorised texture done in current update().
+00581                                         nTotalColored+= size;
+00582                                 }
+00583                                 // Else must quit and don't update any more texture this frame (_CurrentUploadTexture==NULL)
+00584                                 else
+00585                                         return;
+00586                         }
+00587 
+00588                         // upload this one
+00589                         _CurrentUploadTexture= text;
+00590                         // remove it from list of waiting textures
+00591                         _WaitingTextures.erase(it);
+00592                         // found => end.
+00593                         return;
+00594                 }
+00595         }
+00596 
+00597         // If here, and if no more waiting textures, update the Lod system.
+00598         if(_WaitingTextures.empty())
+00599         {
+00600                 // if end to load the current lod.
+00601                 if(_CurrentTextureLodLoaded && _CurrentTextureLodLoaded->Loaded)
+00602                 {
+00603                         // upload this one
+00604                         _CurrentUploadTexture= _CurrentTextureLodLoaded;
+00605                         return;
+00606                 }
+00607 
+00608                 // if no Lod texture currently loading, try to load/unload one
+00609                 if(_CurrentTextureLodLoaded == NULL)
+00610                 {
+00611                         updateTextureLodSystem(pDriver);
+00612                 }
+00613         }
+00614 }
+00615 
+00616 
+00617 // ***************************************************************************
+00618 bool                    CAsyncTextureManager::validDXTCMipMap(ITexture *pText)
+00619 {
+00620         return pText->getMipMapCount()>1 && (
+00621                 pText->getPixelFormat() == CBitmap::DXTC1 ||
+00622                 pText->getPixelFormat() == CBitmap::DXTC1Alpha ||
+00623                 pText->getPixelFormat() == CBitmap::DXTC3 ||
+00624                 pText->getPixelFormat() == CBitmap::DXTC5 );
+00625 }
+00626 
+00627 
+00628 // ***************************************************************************
+00629 void                    CAsyncTextureManager::updateTextureLodSystem(IDriver *pDriver)
+00630 {
+00631         sint    i;
+00632 
+00633         // the array to sort
+00634         static  vector<CTextureLod*>    lodArray;
+00635         lodArray.clear();
+00636         uint    reserveSize= 0;
+00637 
+00638         // for each texture entry compute min distance of use
+00639         //=============
+00640         uint    currentBaseSize= 0;
+00641         for(i=0;i<(sint)_TextureEntries.size();i++)
+00642         {
+00643                 if(!_TextureEntries[i])
+00644                         continue;
+00645                 CTextureEntry   &text= *_TextureEntries[i];
+00646                 // do it only for Lodable textures
+00647                 if(text.CanHaveLOD)
+00648                 {
+00649                         text.MinDistance= FLT_MAX;
+00650                         // for all instances.
+00651                         for(uint j=0;j<text.Instances.size();j++)
+00652                         {
+00653                                 float   instDist= text.Instances[j]->getAsyncTextureDistance();
+00654                                 text.MinDistance= min(text.MinDistance, instDist);
+00655                         }
+00656 
+00657                         // avoid /0
+00658                         text.MinDistance= max(NL3D_ATM_MIN_DISTANCE, text.MinDistance);
+00659 
+00660                         // how many textLods to add
+00661                         reserveSize++;
+00662 
+00663                         // the minimum mem size the system take with base lod.
+00664                         currentBaseSize+= text.BaseSize;
+00665                 }
+00666         }
+00667         // reserve space
+00668         lodArray.reserve(reserveSize);
+00669 
+00670 
+00671         // for each texture lod compute weight, and append
+00672         //=============
+00673         for(i=0;i<(sint)_TextureEntries.size();i++)
+00674         {
+00675                 if(!_TextureEntries[i])
+00676                         continue;
+00677                 CTextureEntry   &text= *_TextureEntries[i];
+00678                 // do it only for Lodable textures
+00679                 if(text.CanHaveLOD)
+00680                 {
+00681                         // This Weight is actually a screen Pixel Ratio! (divide by distance)
+00682                         CTextureLod     *textLod= &text.HDLod;
+00683                         textLod->Weight= (1<<textLod->Level) / text.MinDistance;
+00684                         // add to array
+00685                         lodArray.push_back(textLod);
+00686                 }
+00687         }
+00688 
+00689 
+00690         // sort
+00691         //=============
+00692         CPredTextLod    pred;
+00693         sort(lodArray.begin(), lodArray.end(), pred);
+00694 
+00695 
+00696         // Compute lod to load/unload
+00697         //=============
+00698         // Compute Pivot, ie what lods have to be loaded, and what lods do not
+00699         uint    pivot= 0;
+00700         uint    currentWantedSize= currentBaseSize;
+00701         uint    currentLoadedSize= currentBaseSize;
+00702         for(i=lodArray.size()-1;i>=0;i--)
+00703         {
+00704                 uint    lodSize= lodArray[i]->ExtraSize;
+00705                 currentWantedSize+= lodSize;
+00706                 if(lodArray[i]->UpLoaded)
+00707                         currentLoadedSize+= lodSize;
+00708                 // if > max allowed, stop the pivot here. NB: the pivot is included in the "must load them" part.
+00709                 if(currentWantedSize > _MaxTotalTextureSize)
+00710                 {
+00711                         pivot= i;
+00712                         break;
+00713                 }
+00714         }
+00715         // continue to count currentLoadedSize
+00716         for(;i>=0;i--)
+00717         {
+00718                 if(lodArray[i]->UpLoaded)
+00719                         currentLoadedSize+= lodArray[i]->ExtraSize;
+00720         }
+00721         // save bench.
+00722         _LastTextureSizeGot= currentLoadedSize;
+00723 
+00724 
+00725         // if the loadedSize is inferior to the wanted size, we can load a new LOD
+00726         CTextureLod             *textLod= NULL;
+00727         bool                    unload;
+00728         if(currentLoadedSize<currentWantedSize)
+00729         {
+00730                 unload= false;
+00731                 // search from end of the list to pivot (included), the first LOD (ie the most important) to load.
+00732                 for(i=lodArray.size()-1;i>=(sint)pivot;i--)
+00733                 {
+00734                         if(!lodArray[i]->UpLoaded)
+00735                         {
+00736                                 textLod= lodArray[i];
+00737                                 break;
+00738                         }
+00739                 }
+00740                 // One must have been found, since currentLoadedSize<currentWantedSize
+00741                 nlassert(textLod);
+00742         }
+00743         else
+00744         {
+00745                 unload= true;
+00746                 // search from start to pivot (exclued), the first LOD (ie the less important) to unload.
+00747                 for(i=0;i<(sint)pivot;i++)
+00748                 {
+00749                         if(lodArray[i]->UpLoaded)
+00750                         {
+00751                                 textLod= lodArray[i];
+00752                                 break;
+00753                         }
+00754                 }
+00755                 // it is possible that not found here. It means that All is Ok!!
+00756                 if(textLod==NULL)
+00757                         // no-op.
+00758                         return;
+00759         }
+00760 
+00761 
+00762         // load/unload
+00763         //=============
+00764         if(!unload)
+00765         {
+00766                 // create a new TextureFile, with no sharing system.
+00767                 nlassert(textLod->Texture==NULL);
+00768                 textLod->Texture= new CTextureFile;
+00769                 // Do not allow degradation.
+00770                 textLod->Texture->setAllowDegradation(false);
+00771                 textLod->Texture->enableSharing(false);
+00772                 textLod->Texture->setFileName(textLod->TextureEntry->Texture->getFileName());
+00773                 textLod->Texture->setMipMapSkipAtLoad(textLod->Level);
+00774                 // setup async loading
+00775                 _CurrentTextureLodLoaded= textLod;
+00776                 // load it async.
+00777                 CAsyncFileManager3D::getInstance().loadTexture(textLod->Texture, &textLod->Loaded);
+00778         }
+00779         else
+00780         {
+00781                 // Swap now the lod.
+00782                 nlassert(textLod->Texture!=NULL);
+00783                 // Swap the uploaded Driver Handle with the Main texture (ot get the Ugly one)
+00784                 pDriver->swapTextureHandle(*textLod->Texture, *textLod->TextureEntry->Texture);
+00785                 // Flag the Lod.
+00786                 textLod->UpLoaded= false;
+00787                 textLod->Loaded= false;
+00788                 // Release completly the texture in driver. (SmartPtr delete)
+00789                 textLod->Texture= NULL;
+00790         }
+00791 
+00792 }
+00793 
+00794 
+00795 
+00796 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1