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

texture_dlm.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/texture_dlm.h"
+00029 #include "nel/misc/common.h"
+00030 #include "nel/misc/fast_mem.h"
+00031 
+00032 
+00033 using namespace std;
+00034 using namespace NLMISC;
+00035 
+00036 
+00037 namespace NL3D 
+00038 {
+00039 
+00040 
+00041 // ***************************************************************************
+00042 CTextureDLM::CTextureDLM(uint width, uint height)
+00043 {
+00044         nlassert(width>=NL_DLM_BLOCK_SIZE);
+00045         nlassert(height>=NL_DLM_BLOCK_SIZE);
+00046         nlassert(NLMISC::isPowerOf2(width));
+00047         nlassert(NLMISC::isPowerOf2(height));
+00048 
+00049         // verify there is sufficient blocks.
+00050         _WBlock= width/NL_DLM_BLOCK_SIZE;
+00051         uint    nBlocks= _WBlock * (height/NL_DLM_BLOCK_SIZE);
+00052         nlassert(nBlocks>=NL_DLM_LIGHTMAP_TYPE_SIZE);
+00053 
+00054 
+00055         // The DLM texture always reside in memory...
+00056         // NB: this is simplier like that, and this is not a problem, since actually only 256Ko is allocated :o)
+00057         setReleasable(false);
+00058         // create the bitmap.
+00059         CBitmap::resize(width, height, CBitmap::RGBA);
+00060         // Format of texture, 32 bits and no mipmaps.
+00061         // NB: 16 bits is not a good idea, because implies lot of flicking
+00062         setUploadFormat(ITexture::RGBA8888);
+00063         setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff);
+00064 
+00065         // Fill the array of blocks.
+00066         _Blocks.resize(nBlocks);
+00067         _EmptyBlocks.resize(nBlocks);
+00068         sint i;
+00069         for(i=0;i<(sint)_Blocks.size();i++)
+00070         {
+00071                 // compute position of the block in the texture
+00072                 _Blocks[i].PosX= (i%_WBlock) * NL_DLM_BLOCK_SIZE;
+00073                 _Blocks[i].PosY= (i/_WBlock) * NL_DLM_BLOCK_SIZE;
+00074 
+00075                 // This block is free!!
+00076                 _EmptyBlocks[i]=i;
+00077         }
+00078 
+00079         // init list to NULL.
+00080         for(i=0;i<(sint)NL_DLM_LIGHTMAP_TYPE_SIZE;i++)
+00081         {
+00082                 _FreeBlocks[i]= NULL;
+00083         }
+00084 
+00085         // Since NL_DLM_BLOCK_SIZE is 10 or 18 (a factor of prime number 5 or 3 respectively), we are sure there is 
+00086         // at least one pixel which is not used by blcks. The last pixel is filled with black (see CTextureDLm doc)
+00087         nlassert(NL_DLM_BLOCK_SIZE==10 || NL_DLM_BLOCK_SIZE==18);
+00088         CRGBA   *ptr= (CRGBA*)(&CBitmap::getPixels(0)[0]);
+00089         // fill last pixel with black.
+00090         ptr[width*height-1]= CRGBA::Black;
+00091         // Also, to ensure the texture do not wrap around, disable Tiling.
+00092         ITexture::setWrapS(ITexture::Clamp);
+00093         ITexture::setWrapT(ITexture::Clamp);
+00094 }
+00095 
+00096 
+00097 // ***************************************************************************
+00098 uint                            CTextureDLM::getTypeForSize(uint width, uint height)
+00099 {
+00100 #ifdef NL_DLM_TILE_RES
+00101         nlassert(width==3 || width==5 || width==9 || width==17);
+00102         nlassert(height==3 || height==5 || height==9 || height==17);
+00103 #else
+00104         nlassert(width==2 || width==3 || width==5 || width==9);
+00105         nlassert(height==2 || height==3 || height==5 || height==9);
+00106 #endif
+00107 
+00108         // 0 for 2, 1 for 3, 2 for 5, and 3 for 9, and 4 for 17
+00109         width= getPowerOf2(width-1);
+00110         height= getPowerOf2(height-1);
+00111 #ifdef NL_DLM_TILE_RES
+00112         // 0 for 3, 1 for 5, 2, for 9, and 3 for 17
+00113         width--; height--;
+00114 #endif
+00115 
+00116         uint id= width + height*4;
+00117         nlassert(id<NL_DLM_LIGHTMAP_TYPE_SIZE);
+00118 
+00119         return id;
+00120 }
+00121 
+00122 
+00123 // ***************************************************************************
+00124 bool                    CTextureDLM::canCreateLightMap(uint w, uint h)
+00125 {
+00126         // First test if the list is not empty.
+00127         if(_FreeBlocks[getTypeForSize(w,h)])
+00128                 return true;
+00129 
+00130         // If empty, test if there is an empty block.
+00131         return _EmptyBlocks.size()>0;
+00132 }
+00133 
+00134 
+00135 // ***************************************************************************
+00136 void                    CTextureDLM::linkFreeBlock(uint lMapType, CBlock *block)
+00137 {
+00138         // link me to others
+00139         block->FreeNext= _FreeBlocks[lMapType];
+00140         block->FreePrec= NULL;
+00141         // link other to me
+00142         if(_FreeBlocks[lMapType])
+00143                 _FreeBlocks[lMapType]->FreePrec= block;
+00144         _FreeBlocks[lMapType]= block;
+00145 }
+00146 
+00147 // ***************************************************************************
+00148 void                    CTextureDLM::unlinkFreeBlock(uint lMapType, CBlock *block)
+00149 {
+00150         // unlink other from me
+00151         if(block->FreeNext)
+00152                 block->FreeNext->FreePrec= block->FreePrec;
+00153         if(block->FreePrec)
+00154                 block->FreePrec->FreeNext= block->FreeNext;
+00155         else
+00156                 _FreeBlocks[lMapType]= block->FreeNext;
+00157         // reset me
+00158         block->FreePrec= NULL;
+00159         block->FreeNext= NULL;
+00160 }
+00161 
+00162 
+00163 // ***************************************************************************
+00164 bool                    CTextureDLM::createLightMap(uint w, uint h, uint &x, uint &y)
+00165 {
+00166         // at least cna create it??
+00167         if(!canCreateLightMap(w, h))
+00168                 return false;
+00169 
+00170         // the type of lightmap.
+00171         uint    lMapType= getTypeForSize(w,h);
+00172 
+00173         // First manage case list is empty.
+00174         //===================
+00175         if(_FreeBlocks[lMapType]==NULL)
+00176         {
+00177                 // list is empty => allocate a block from _EmptyBlocks.
+00178                 nlassert(_EmptyBlocks.size()>0);
+00179 
+00180                 // pop a block from empty list
+00181                 CBlock  *block= &_Blocks[_EmptyBlocks.back()];
+00182                 _EmptyBlocks.pop_back();
+00183 
+00184                 // init this block.
+00185                 nlassert(block->FreeSpace==0);
+00186                 // set size of lightmaps for this blocks.
+00187                 block->Width= w;
+00188                 block->Height= h;
+00189 
+00190                 // Link this block to the list.
+00191                 linkFreeBlock(lMapType, block);
+00192         }
+00193 
+00194         // Get the block from the list.
+00195         CBlock  *block= _FreeBlocks[lMapType];
+00196 
+00197         // Allocate block lightmap.
+00198         //===================
+00199 
+00200         // compute block info.
+00201         uint    nLMapOnX= NL_DLM_BLOCK_SIZE / block->Width;
+00202         uint    nLMapOnY= NL_DLM_BLOCK_SIZE / block->Height;
+00203         uint    nLMapPerBlock= nLMapOnX * nLMapOnY;
+00204         // bit must fit in a uint64
+00205         nlassert(nLMapPerBlock<=64);
+00206 
+00207         // get an id in the FreeSpace bitField.
+00208         uint    i;
+00209         for(i= 0;i<nLMapPerBlock; i++)
+00210         {
+00211                 uint    mask= 1<<i;
+00212                 // If the bit is not set, then this id is free.
+00213                 if( (block->FreeSpace & mask)==0 )
+00214                 {
+00215                         // take this id, hence set this bit
+00216                         block->FreeSpace|= mask;
+00217                         // stop, found.
+00218                         break;
+00219                 }
+00220         }
+00221         nlassert(i<nLMapPerBlock);
+00222 
+00223         // compute x/y texture pos for this id.
+00224         x= block->PosX + (i%nLMapOnX) * w;
+00225         y= block->PosY + (i/nLMapOnX) * h;
+00226 
+00227 
+00228         // if lightmap full
+00229         //===================
+00230         // if bitfield is full
+00231         if( block->FreeSpace == (uint)(1<<nLMapPerBlock)-1 )
+00232         {
+00233                 // Must remove it from free list.
+00234                 unlinkFreeBlock(lMapType, block);
+00235         }
+00236 
+00237         return true;
+00238 }
+00239 
+00240 // ***************************************************************************
+00241 void                    CTextureDLM::copyRect(uint x, uint y, uint w, uint h, CRGBA  *textMap)
+00242 {
+00243         // copy image.
+00244         CRGBA   *src= textMap;
+00245         CRGBA   *dst= (CRGBA*)&(*getPixels().begin());
+00246         dst+= y*getWidth()+x;
+00247         for(sint n= h;n>0;n--, src+= w, dst+= getWidth())
+00248         {
+00249                 memcpy(dst, src, w*sizeof(CRGBA));
+00250         }
+00251 
+00252         // Invalidate the rectangle.
+00253         ITexture::touchRect(CRect(x, y, w, h));
+00254 }
+00255 
+00256 // ***************************************************************************
+00257 void                    CTextureDLM::fillRect(uint x, uint y, uint w, uint h, uint8 value)
+00258 {
+00259         // copy image.
+00260         CRGBA   *dst= (CRGBA*)&(*getPixels().begin());
+00261         dst+= y*getWidth()+x;
+00262         for(sint n= h;n>0;n--, dst+= getWidth())
+00263         {
+00264                 memset(dst, value, w*sizeof(CRGBA));
+00265         }
+00266 
+00267         // Invalidate the rectangle.
+00268         ITexture::touchRect(CRect(x, y, w, h));
+00269 }
+00270 
+00271 
+00272 // ***************************************************************************
+00273 void                    CTextureDLM::modulateAndfillRect565(uint x, uint y, uint w, uint h, CRGBA  *textMap, uint16 *modColor)
+00274 {
+00275         // compute start dst to copy.
+00276         CRGBA   *dst= (CRGBA*)&(*getPixels().begin());
+00277         dst+= y*getWidth()+x;
+00278 
+00279         // precahce Data in memory (best CPU support)
+00280         CFastMem::precache(textMap, w*h*sizeof(CRGBA));
+00281         CFastMem::precache(modColor, w*h*sizeof(uint16));
+00282 
+00283         // For all lines
+00284         for(sint n= h;n>0;n--, dst+= (getWidth()-w) )
+00285         {
+00286                 // For all the line.
+00287                 for(sint nc= w;nc>0;nc--, textMap++, modColor++, dst++)
+00288                 {
+00289                         uint16  tc= *modColor;
+00290                         // modulate R.
+00291                         dst->R= ( (tc>>11) * textMap->R)>>5;
+00292                         // modulate G.
+00293                         dst->G= (((tc>>5)&63) * textMap->G)>>6;
+00294                         // modulate B.
+00295                         dst->B= ( (tc&31) * textMap->B)>>5;
+00296                 }
+00297         }
+00298 
+00299         // Invalidate the rectangle.
+00300         ITexture::touchRect(CRect(x, y, w, h));
+00301 }
+00302 
+00303 
+00304 // ***************************************************************************
+00305 void                    CTextureDLM::modulateAndfillRect8888(uint x, uint y, uint w, uint h, CRGBA  *textMap, CRGBA *modColor)
+00306 {
+00307         // compute start dst to copy.
+00308         CRGBA   *dst= (CRGBA*)&(*getPixels().begin());
+00309         dst+= y*getWidth()+x;
+00310 
+00311         // precahce Data in memory (best CPU support)
+00312         CFastMem::precache(textMap, w*h*sizeof(CRGBA));
+00313         CFastMem::precache(modColor, w*h*sizeof(CRGBA));
+00314 
+00315         // For all lines
+00316         for(sint n= h;n>0;n--, dst+= (getWidth()-w) )
+00317         {
+00318                 // For all the line.
+00319                 for(sint nc= w;nc>0;nc--, textMap++, modColor++, dst++)
+00320                 {
+00321                         CRGBA           mc= *modColor;
+00322                         // modulate RGB only
+00323                         dst->R= ( mc.R * textMap->R)>>8;
+00324                         dst->G= ( mc.G * textMap->G)>>8;
+00325                         dst->B= ( mc.B * textMap->B)>>8;
+00326                 }
+00327         }
+00328 
+00329         // Invalidate the rectangle.
+00330         ITexture::touchRect(CRect(x, y, w, h));
+00331 }
+00332 
+00333 
+00334 // ***************************************************************************
+00335 void                    CTextureDLM::modulateConstantAndfillRect(uint x, uint y, uint w, uint h, CRGBA  *textMap, CRGBA mc)
+00336 {
+00337         // compute start dst to copy.
+00338         CRGBA   *dst= (CRGBA*)&(*getPixels().begin());
+00339         dst+= y*getWidth()+x;
+00340 
+00341         // precahce Data in memory (best CPU support)
+00342         CFastMem::precache(textMap, w*h*sizeof(CRGBA));
+00343 
+00344         // For all lines
+00345         for(sint n= h;n>0;n--, dst+= (getWidth()-w) )
+00346         {
+00347                 // For all the line.
+00348                 for(sint nc= w;nc>0;nc--, textMap++, dst++)
+00349                 {
+00350                         // modulate RGB only
+00351                         dst->R= ( mc.R * textMap->R)>>8;
+00352                         dst->G= ( mc.G * textMap->G)>>8;
+00353                         dst->B= ( mc.B * textMap->B)>>8;
+00354                 }
+00355         }
+00356 
+00357         // Invalidate the rectangle.
+00358         ITexture::touchRect(CRect(x, y, w, h));
+00359 }
+00360 
+00361 
+00362 // ***************************************************************************
+00363 void                    CTextureDLM::releaseLightMap(uint x, uint y)
+00364 {
+00365         // Search what block is under this pos.
+00366         uint    blockId= (y/NL_DLM_BLOCK_SIZE)*_WBlock + (x/NL_DLM_BLOCK_SIZE);
+00367         nlassert(blockId<_Blocks.size());
+00368         CBlock  *block= &_Blocks[blockId];
+00369 
+00370         // compute block info.
+00371         uint    nLMapOnX= NL_DLM_BLOCK_SIZE / block->Width;
+00372         uint    nLMapOnY= NL_DLM_BLOCK_SIZE / block->Height;
+00373         uint    nLMapPerBlock= nLMapOnX * nLMapOnY;
+00374         // was Full (ie all bits set) before this release
+00375         bool    wasFull= (block->FreeSpace == (uint)(1<<nLMapPerBlock)-1);
+00376         // the type of lightmap.
+00377         uint    lMapType= getTypeForSize(block->Width, block->Height);
+00378 
+00379 
+00380         // get relative pos to the block.
+00381         x-= block->PosX;
+00382         y-= block->PosY;
+00383 
+00384         // compute bit number.
+00385         uint    bitX= x/block->Width;
+00386         uint    bitY= y/block->Height;
+00387         // assert good pos param.
+00388         nlassert(x == bitX*block->Width);
+00389         nlassert(y == bitY*block->Height);
+00390 
+00391         // compute bitId, as done in createLightMap()
+00392         uint    bitId= bitY * nLMapOnX + bitX;
+00393         uint    mask= 1<<bitId;
+00394 
+00395         // Free this bit in the block.
+00396         nlassert(block->FreeSpace & mask);
+00397         block->FreeSpace&= ~mask;
+00398 
+00399 
+00400         // Free the block if necessary.
+00401         //=======================
+00402         bool    isEmpty= block->FreeSpace==0;
+00403 
+00404         // If wasFull and now it is empty (nLMapPerBlock==1 case), just append to EmptyBlocks.
+00405         if(wasFull && isEmpty)
+00406         {
+00407                 // add the id to the empty list.
+00408                 _EmptyBlocks.push_back(blockId);
+00409         }
+00410         // if wasFull, but still have some lightmap now, must insert into FreeList
+00411         else if(wasFull && !isEmpty)
+00412         {
+00413                 linkFreeBlock(lMapType, block);
+00414         }
+00415         // if was not full but now it is empty, must remove from free list and insert into EmptyBlocks
+00416         else if(!wasFull && isEmpty)
+00417         {
+00418                 // remove the block from Free List
+00419                 unlinkFreeBlock(lMapType, block);
+00420                 // add the id to the empty list.
+00421                 _EmptyBlocks.push_back(blockId);
+00422         }
+00423         // else (!wasFull && !isEmpty) no-op, since must be kept in the FreeList.
+00424 
+00425 }
+00426 
+00427 
+00428 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1