#include <hls_color_texture.h>
Nevrax France
Definition at line 70 of file hls_color_texture.h.
Public Member Functions | |
void | addMask (const NLMISC::CBitmap &bmp, uint threshold=15) |
void | buildColorVersion (const CHLSColorDelta *colDeltaList, NLMISC::CBitmap &out) |
CHLSColorTexture () | |
uint | getNumMasks () const |
get num of masks | |
void | reset () |
reset the build | |
void | serial (NLMISC::IStream &f) |
void | setBitmap (const NLMISC::CBitmap &bmp) |
Static Public Member Functions | |
void | compressBlockRGB (CRGBA *srcRGBA, uint8 *dstDXTC) |
compress DXTC5 RGB only block, from a RGBA raw array. dstDXTC Alpha part is not modified. srcRGBA->A are setup to 0!! | |
Static Private Member Functions | |
void | colorizeDXTCBlockRGB (const uint8 *srcPtr, uint8 *dstPtr, uint8 dHue, uint dLum, uint dSat) |
apply colDelta to the block. Alpha part is not modified. MMX with no EMMS called here !!! | |
void | computeMinMax (sint *diffBlock, CVectorInt &v, sint mean[3], sint rgb0[3], sint rgb1[3]) |
used by compressBlockRGB() | |
void | uncompressBlockRGB (const uint8 *srcDXTC, CRGBA *dstRGBA) |
uncompress DXTC5 RGB only block, into a RGBA raw array. Alpha is setup with undefined values | |
Private Attributes | |
uint32 | _BlockToCompressIndex |
uint32 | _Height |
std::vector< CMask > | _Masks |
uint32 | _NumMipMap |
std::vector< uint8 > | _Texture |
uint32 | _Width |
|
Definition at line 76 of file hls_color_texture.cpp. References reset().
00077 { 00078 reset(); 00079 } |
|
add a mask to the texture. R is taken as the mask value. must be same size as in setBitmap()
Definition at line 152 of file hls_color_texture.cpp. References _BlockToCompressIndex, _Masks, _NumMipMap, BLOCK_ALPHA_SIZE, NL3D::CMaskInfo::Blocks, NLMISC::CBitmap::buildMipMaps(), NLMISC::CBitmap::convertToType(), NL3D::CHLSColorTexture::CMask::Data, NL3D::CHLSColorTexture::CMask::FullBlockIndex, NLMISC::CBitmap::getHeight(), NLMISC::CBitmap::getMipMapCount(), NLMISC::CBitmap::getPixels(), NLMISC::CBitmap::getWidth(), NL3D::CMaskInfo::HBlock, MASK_BLOCK_EMPTY, MASK_BLOCK_FULL, MASK_BLOCK_MIXT, min, NL3D::CHLSColorTexture::CMask::MixtBlockIndex, nlassert, NL3D::CMaskInfo::NumBlock, NL3D::CHLSColorTexture::CMask::setBit(), src, uint, uint8, w, NL3D::CMaskInfo::WBlock, x, and y.
00153 { 00154 // copy the bitmap and set RGBA/mipmaps. 00155 CBitmap bmp= bmpIn; 00156 bmp.convertToType(CBitmap::RGBA); 00157 bmp.buildMipMaps(); 00158 00159 // verify widht... 00160 nlassert(bmp.getWidth()== _Width); 00161 nlassert(bmp.getHeight()== _Height); 00162 nlassert(bmp.getMipMapCount()== _NumMipMap); 00163 00164 // ***** build the information for all mipmaps 00165 vector<CMaskInfo> masks; 00166 masks.resize(_NumMipMap); 00167 uint m; 00168 uint numMixtBlock= 0; 00169 uint numTotalBlock= 0; 00170 for(m=0;m<_NumMipMap;m++) 00171 { 00172 CMaskInfo &mask= masks[m]; 00173 uint mmWidth= bmp.getWidth(m); 00174 uint mmHeight= bmp.getHeight(m); 00175 mask.WBlock= (mmWidth+3)/4; 00176 mask.HBlock= (mmHeight+3)/4; 00177 mask.NumBlock= mask.WBlock*mask.HBlock; 00178 mask.Blocks.resize(mask.NumBlock); 00179 00180 numTotalBlock+= mask.NumBlock; 00181 00182 CRGBA *src= (CRGBA*)(&bmp.getPixels(m)[0]); 00183 00184 for(uint yB=0;yB<mask.HBlock;yB++) 00185 { 00186 for(uint xB=0;xB<mask.WBlock;xB++) 00187 { 00188 uint accum= 0; 00189 uint w= min(mmWidth, 4U); 00190 uint h= min(mmHeight, 4U); 00191 for(uint y= 0;y< h;y++) 00192 { 00193 for(uint x= 0;x< w;x++) 00194 { 00195 uint yPix= yB*4+y; 00196 uint xPix= xB*4+x; 00197 // read the color 00198 uint8 alphaMask = src[yPix*mmWidth+xPix].R; 00199 // remove some dummy precision. 00200 if(alphaMask<threshold) 00201 alphaMask= 0; 00202 if(alphaMask>255-threshold) 00203 alphaMask= 255; 00204 // Add to the accum 00205 accum+= alphaMask; 00206 } 00207 } 00208 00209 // full black? 00210 if(accum==0) 00211 mask.Blocks[yB*mask.WBlock+xB]= MASK_BLOCK_EMPTY; 00212 else if(accum==w*h*255) 00213 mask.Blocks[yB*mask.WBlock+xB]= MASK_BLOCK_FULL; 00214 // if not full white or full black, mixt block 00215 else 00216 { 00217 mask.Blocks[yB*mask.WBlock+xB]= MASK_BLOCK_MIXT; 00218 numMixtBlock++; 00219 } 00220 } 00221 } 00222 } 00223 00224 // ***** compress into CMask 00225 CMask newMask; 00226 uint newMaskDataSize= 0; 00227 00228 // add the mixt block data size (16*uint8 per block) 00229 newMaskDataSize+= numMixtBlock*BLOCK_ALPHA_SIZE; 00230 // compute the bit size. NB: use uint32 to blocks bits. => data is aligned. 00231 uint bitDataSize= 4*((numTotalBlock+31)/32); 00232 // add fullBlock bits 00233 newMask.FullBlockIndex= newMaskDataSize; 00234 newMaskDataSize+= bitDataSize; 00235 // add mixtBlock bits 00236 newMask.MixtBlockIndex= newMaskDataSize; 00237 newMaskDataSize+= bitDataSize; 00238 00239 // allocate. Fill with 0 to initialize bits per default EMPTY value 00240 newMask.Data.resize(newMaskDataSize, 0); 00241 00242 // compress each mipMaps from bigger to smaller 00243 uint bitId= 0; 00244 uint mixtBlockId= 0; 00245 for(m=0;m<_NumMipMap;m++) 00246 { 00247 CMaskInfo &mask= masks[m]; 00248 00249 // ---- build the mixtBlock alpha Mask 00250 for(uint yB=0;yB<mask.HBlock;yB++) 00251 { 00252 for(uint xB=0;xB<mask.WBlock;xB++) 00253 { 00254 uint id= yB*mask.WBlock+xB; 00255 // if mixt block 00256 if(mask.Blocks[id]==MASK_BLOCK_MIXT) 00257 { 00258 nlassert(mixtBlockId<numMixtBlock); 00259 // Fill Alpha data. 00260 uint8 *dst= &newMask.Data[mixtBlockId*BLOCK_ALPHA_SIZE]; 00261 uint mmWidth= bmp.getWidth(m); 00262 uint mmHeight= bmp.getHeight(m); 00263 // point to the src alpha color 00264 CRGBA *src= (CRGBA*)(&bmp.getPixels(m)[0]); 00265 src= src + yB*4*mmWidth + xB*4; 00266 00267 // for the 4*4 pixels 00268 uint w= min(mmWidth, 4U); 00269 uint h= min(mmHeight, 4U); 00270 for(uint y=0;y<h;y++) 00271 { 00272 for(uint x=0;x<w;x++) 00273 { 00274 dst[y*4+x]= src[y*mmWidth+x].R; 00275 } 00276 } 00277 00278 // inc 00279 mixtBlockId++; 00280 } 00281 } 00282 } 00283 00284 // ---- build the fullBlock and mixtBlocks bits. 00285 for(uint i=0; i<mask.NumBlock; i++) 00286 { 00287 nlassert(bitId<numTotalBlock); 00288 00289 // fill bits 00290 if(mask.Blocks[i]==MASK_BLOCK_FULL) 00291 newMask.setBit(newMask.FullBlockIndex*8 + bitId); 00292 else if(mask.Blocks[i]==MASK_BLOCK_MIXT) 00293 newMask.setBit(newMask.MixtBlockIndex*8 + bitId); 00294 00295 // inc 00296 bitId++; 00297 } 00298 } 00299 00300 // ***** Add the CMask 00301 _Masks.push_back(newMask); 00302 00303 // Or the BlockToCompress info with the MixtBlocks bits. 00304 nlassert(bitDataSize==_Texture.size()-_BlockToCompressIndex); 00305 for(uint i=0;i<bitDataSize;i++) 00306 { 00307 _Texture[_BlockToCompressIndex+i]|= newMask.Data[newMask.MixtBlockIndex+i]; 00308 } 00309 } |
|
build a texture with a HLS Color Delta
Definition at line 337 of file hls_color_texture.cpp. References _BlockToCompressIndex, _Masks, _NumMipMap, NLMISC::CRGBA::blendFromuiRGBOnly(), BLOCK_DXTC_SIZE, BLOCK_NUM_PIXEL, colorizeDXTCBlockRGB(), compressBlockRGB(), NL3D::CHLSColorTexture::CMask::Data, NL3D::CHLSColorDelta::DHue, NL3D::CHLSColorTexture::CMask::FullBlockIndex, NL3D::getBitPack(), NLMISC::CBitmap::getPixels(), min, NL3D::CHLSColorTexture::CMask::MixtBlockIndex, nlassert, NLMISC::CBitmap::reset(), NLMISC::CBitmap::resize(), NLMISC::CBitmap::resizeMipMap(), NLMISC::CBitmap::setMipMapCount(), NLMISC::CObjectVector< uint8 >::size(), size, uint, uint32, uint8, uncompressBlockRGB(), and w. Referenced by NL3D::CHLSTextureBank::CTextureInstance::buildColorVersion().
00338 { 00339 // static to avoid realloc 00340 static vector<uint8> dstTexture; 00341 static vector<CRGBA> dstUnCompTexture; 00342 uint32 *bitPtr; 00343 uint8 *srcPtr; 00344 uint8 *dstPtr; 00345 CRGBA *dstUnCompPtr; 00346 uint32 bitMask; 00347 00348 // **** prepare Data 00349 00350 // count number of DXTC5 block in _Texture. 00351 uint numBlocks= _BlockToCompressIndex/BLOCK_DXTC_SIZE; 00352 00353 // create a tmp compressed block array, copy of Texture. 00354 dstTexture.resize(numBlocks*BLOCK_DXTC_SIZE); 00355 // copy from texture (to have non colored version already copied, and also ALPHA ok) 00356 memcpy(&dstTexture[0], &_Texture[0], dstTexture.size()); 00357 00358 // create a tmp uncompressed block array, which will receive coloring of mixt blocks 00359 dstUnCompTexture.resize(numBlocks*BLOCK_NUM_PIXEL); 00360 00361 // For all blockToCompress, uncompress them in dstUnCompTexture, because they will blend with future mask coloring 00362 uint n= numBlocks; 00363 bitPtr= (uint32*)(&_Texture[_BlockToCompressIndex]); 00364 dstUnCompPtr= &dstUnCompTexture[0]; 00365 srcPtr= &_Texture[0]; 00366 while(n>0) 00367 { 00368 uint nBits= min(n, 32U); 00369 getBitPack(bitPtr, bitMask); 00370 n-= nBits; 00371 bitPtr++; 00372 for(;nBits>0;nBits--) 00373 { 00374 // need to compress/uncompress ?? 00375 if(bitMask&1) 00376 { 00377 // uncompress this block. ignore alpha 00378 uncompressBlockRGB(srcPtr, dstUnCompPtr); 00379 } 00380 bitMask>>=1; 00381 dstUnCompPtr+= BLOCK_NUM_PIXEL; 00382 srcPtr+= BLOCK_DXTC_SIZE; 00383 } 00384 } 00385 00386 // **** build the color version for all masks. 00387 00388 for(uint maskId= 0; maskId<_Masks.size();maskId++) 00389 { 00390 CMask &mask= _Masks[maskId]; 00391 // unpack colDelta, and prepare for use with CFastHLSModifier. 00392 uint8 dHue= colDeltaList[maskId].DHue; 00393 uint dLum= 0xFFFFFF00 + colDeltaList[maskId].DLum*2; 00394 uint dSat= 0xFFFFFF00 + colDeltaList[maskId].DSat*2; 00395 00396 // get a ptr on alpha of mixt block. 00397 uint8 *alphaMixtBlock= &mask.Data[0]; 00398 00399 00400 // ---- for all Fullblock ot this mask, color and store in dstTexture 00401 // start at full Block bits desc 00402 bitPtr= (uint32*)(&mask.Data[mask.FullBlockIndex]); 00403 uint32 *bitCompPtr= (uint32*)(&_Texture[_BlockToCompressIndex]); 00404 srcPtr= &_Texture[0]; 00405 dstPtr= &dstTexture[0]; 00406 dstUnCompPtr= &dstUnCompTexture[0]; 00407 n= numBlocks; 00408 // run all blocks. 00409 while(n>0) 00410 { 00411 uint nBits= min(n, 32U); 00412 // get Full block mask. 00413 getBitPack(bitPtr, bitMask); 00414 n-= nBits; 00415 bitPtr++; 00416 // get Compress mask. 00417 uint32 bitCompMask; 00418 getBitPack(bitCompPtr, bitCompMask); 00419 bitCompPtr++; 00420 // for all bits 00421 for(;nBits>0;nBits--) 00422 { 00423 // need to colorize?? 00424 if(bitMask&1) 00425 { 00426 // colorize this block. ignore alpha 00427 colorizeDXTCBlockRGB(srcPtr, dstPtr, dHue, dLum, dSat); 00428 // If this block is "a block to recompress", then must uncompress it in dstUnCompPtr 00429 uncompressBlockRGB(dstPtr, dstUnCompPtr); 00430 } 00431 bitMask>>=1; 00432 bitCompMask>>=1; 00433 srcPtr+= BLOCK_DXTC_SIZE; 00434 dstPtr+= BLOCK_DXTC_SIZE; 00435 dstUnCompPtr+= BLOCK_NUM_PIXEL; 00436 } 00437 } 00438 00439 // ---- for all mixtblock ot this mask, color, uncompress and blend in store in dstUnCompTexture 00440 static uint8 tmpColoredBlockDXTC[BLOCK_NUM_PIXEL]; 00441 static CRGBA tmpColoredBlockRGBA[BLOCK_NUM_PIXEL]; 00442 // start at mixt Block bits desc 00443 bitPtr= (uint32*)(&mask.Data[mask.MixtBlockIndex]); 00444 srcPtr= &_Texture[0]; 00445 dstUnCompPtr= &dstUnCompTexture[0]; 00446 n= numBlocks; 00447 // run all blocks. 00448 while(n>0) 00449 { 00450 uint nBits= min(n, 32U); 00451 getBitPack(bitPtr, bitMask); 00452 n-= nBits; 00453 bitPtr++; 00454 for(;nBits>0;nBits--) 00455 { 00456 // need to colorize?? 00457 if(bitMask&1) 00458 { 00459 // colorize this block. store 2 colors in tmp 00460 colorizeDXTCBlockRGB(srcPtr, tmpColoredBlockDXTC, dHue, dLum, dSat); 00461 // copy RGB bits from src to tmp 00462 ((uint32*)tmpColoredBlockDXTC)[3]= ((uint32*)srcPtr)[3]; 00463 00464 // uncompress the block. 00465 uncompressBlockRGB(tmpColoredBlockDXTC, tmpColoredBlockRGBA); 00466 00467 // blend tmpColoredBlockRGBA into dstUnCompPtr, according to alphaMixtBlock. 00468 for(uint i=0;i<16;i++) 00469 { 00470 dstUnCompPtr[i].blendFromuiRGBOnly(dstUnCompPtr[i], tmpColoredBlockRGBA[i], *alphaMixtBlock); 00471 // next pixel 00472 alphaMixtBlock++; 00473 } 00474 } 00475 bitMask>>=1; 00476 srcPtr+= BLOCK_DXTC_SIZE; 00477 dstUnCompPtr+= BLOCK_NUM_PIXEL; 00478 } 00479 } 00480 00481 } 00482 00483 00484 // Since colorizeDXTCBlockRGB() use MMX, must end with emms. 00485 #ifdef NL_OS_WINDOWS 00486 if(CSystemInfo::hasMMX()) 00487 _asm emms; 00488 #endif 00489 00490 00491 // **** compress needed blocks 00492 n= numBlocks; 00493 bitPtr= (uint32*)(&_Texture[_BlockToCompressIndex]); 00494 dstUnCompPtr= &dstUnCompTexture[0]; 00495 dstPtr= &dstTexture[0]; 00496 while(n>0) 00497 { 00498 uint nBits= min(n, 32U); 00499 getBitPack(bitPtr, bitMask); 00500 n-= nBits; 00501 bitPtr++; 00502 for(;nBits>0;nBits--) 00503 { 00504 // need to compress ?? 00505 if(bitMask&1) 00506 { 00507 // uncompress this block. ignore alpha 00508 compressBlockRGB(dstUnCompPtr, dstPtr); 00509 } 00510 bitMask>>=1; 00511 dstUnCompPtr+= BLOCK_NUM_PIXEL; 00512 dstPtr+= BLOCK_DXTC_SIZE; 00513 } 00514 } 00515 00516 // **** format bitmap out with dstTexture. 00517 out.reset(CBitmap::DXTC5); 00518 out.resize(_Width, _Height, CBitmap::DXTC5); 00519 00520 // create and fill all the mipMaps 00521 uint w= _Width, h=_Height; 00522 dstPtr= &dstTexture[0]; 00523 for(uint m=0;m<_NumMipMap;m++) 00524 { 00525 // allocate. 00526 out.resizeMipMap(m, w, h); 00527 // get the size of this DXTC5 level. 00528 uint size= out.getPixels(m).size(); 00529 // fill 00530 memcpy(&out.getPixels(m)[0], dstPtr, size); 00531 // next mipmap 00532 dstPtr+= size; 00533 w= (w+1)/2; 00534 h= (h+1)/2; 00535 } 00536 // verify all filled 00537 nlassert( dstPtr== (&dstTexture[0] + dstTexture.size()) ); 00538 00539 // set the correct num of mipmap 00540 out.setMipMapCount(_NumMipMap); 00541 } |
|
apply colDelta to the block. Alpha part is not modified. MMX with no EMMS called here !!!
Definition at line 545 of file hls_color_texture.cpp. References NL3D::CFastHLSModifier::applyHLSMod(), uint, uint16, and uint8. Referenced by buildColorVersion().
00546 { 00547 // get modifier. 00548 CFastHLSModifier &fastHLS= CFastHLSModifier::getInstance(); 00549 00550 // apply the color on the 2 DXTC colors 00551 *(uint16*)(dstPtr+8 )= fastHLS.applyHLSMod(*(uint16*)(srcPtr+8 ) , dHue, dLum, dSat); 00552 *(uint16*)(dstPtr+10)= fastHLS.applyHLSMod(*(uint16*)(srcPtr+10) , dHue, dLum, dSat); 00553 } |
|
compress DXTC5 RGB only block, from a RGBA raw array. dstDXTC Alpha part is not modified. srcRGBA->A are setup to 0!!
Definition at line 628 of file hls_color_texture.cpp. References NLMISC::CRGBA::A, NLMISC::CRGBA::B, NLMISC::CRGBA::blendFromui(), computeMinMax(), NLMISC::CRGBA::G, NLMISC::OptFastFloor(), NLMISC::CRGBA::R, NLMISC::CRGBA::set565(), sint, sint32, size, NLMISC::sqr(), src, uint, uint16, uint32, uint64, uint8, v, NL3D::CHLSColorTexture::CVectorInt::x, NL3D::CHLSColorTexture::CVectorInt::y, and NL3D::CHLSColorTexture::CVectorInt::z. Referenced by buildColorVersion().
00629 { 00630 // skip alpha part. 00631 uint8 *dstBlock= dstDXTC+8; 00632 00633 00634 // **** compute RGB0 and RGB1. 00635 uint i,j,n; 00636 00637 // compute the mean color of 16 pixels 00638 sint mean[3]; 00639 mean[0]= 0; 00640 mean[1]= 0; 00641 mean[2]= 0; 00642 CRGBA *src= srcRGBA; 00643 for(n=16;n>0;n--,src++) 00644 { 00645 mean[0]+= src->R; 00646 mean[1]+= src->G; 00647 mean[2]+= src->B; 00648 // at same time, setup alpha to 0. Important for "compute bits" part (see MMX)!! 00649 src->A= 0; 00650 } 00651 mean[0]>>= 4; 00652 mean[1]>>= 4; 00653 mean[2]>>= 4; 00654 00655 // compute col-mean 00656 sint diffBlock[16*3]; 00657 src= srcRGBA; 00658 sint *srcDiff= diffBlock; 00659 for(n=16;n>0;n--,src++,srcDiff+=3) 00660 { 00661 srcDiff[0]= (sint)src->R - mean[0]; 00662 srcDiff[1]= (sint)src->G - mean[1]; 00663 srcDiff[2]= (sint)src->B - mean[2]; 00664 } 00665 00666 00667 // compute the covariant matrix. 00668 sint coMat[3][3]; 00669 // Apply std RGB factor (0.3, 0.56, 0.14) to choose the best Axis. This give far much best results. 00670 sint rgbFact[3]= {77, 143, 36}; 00671 for(i=0;i<3;i++) 00672 { 00673 // OPTIMIZE SINCE SYMETRIX MATRIX 00674 for(j=i;j<3;j++) 00675 { 00676 sint32 factor= 0; 00677 // divide / 16 to avoid overflow sint32 00678 uint colFactor= (rgbFact[i]*rgbFact[j]) >> 4; 00679 // run all 16 pixels. 00680 sint *srcDiff= diffBlock; 00681 for(n=16;n>0;n--,srcDiff+=3) 00682 { 00683 factor+= srcDiff[i] * srcDiff[j] * colFactor; 00684 } 00685 coMat[i][j]= factor; 00686 } 00687 } 00688 // Fill symetrix matrix 00689 coMat[1][0]= coMat[0][1]; 00690 coMat[2][0]= coMat[0][2]; 00691 coMat[2][1]= coMat[1][2]; 00692 00693 00694 // take the bigger vector 00695 sint maxSize= 0; 00696 uint axis= 0; 00697 for(i=0;i<3;i++) 00698 { 00699 // Use abs since sqr fails because all sint32 range may be used. 00700 sint size= abs(coMat[i][0]) + abs(coMat[i][1]) + abs(coMat[i][2]); 00701 if(size>maxSize) 00702 { 00703 maxSize= size; 00704 axis= i; 00705 } 00706 } 00707 00708 // normalize this vector 00709 CVector v; 00710 // remove some rgb factor... 00711 v.x= (float)coMat[axis][0]/rgbFact[0]; 00712 v.y= (float)coMat[axis][1]/rgbFact[1]; 00713 v.z= (float)coMat[axis][2]/rgbFact[2]; 00714 v.normalize(); 00715 // set a Fixed 16:16. 00716 CVectorInt vInt; 00717 // don't bother if OptFastFloorBegin() has been called. 16:16 precision is sufficient. 00718 vInt.x= OptFastFloor(v.x*65536); 00719 vInt.y= OptFastFloor(v.y*65536); 00720 vInt.z= OptFastFloor(v.z*65536); 00721 00722 00723 // For all pixels, choose the 2 colors along the axis 00724 sint rgb0[3]; 00725 sint rgb1[3]; 00726 computeMinMax(diffBlock, vInt, mean, rgb0, rgb1); 00727 00728 // Average to 16 bits. NB: correclty encode 0..255 to 0.31 or 0..63. 00729 uint R,G,B; 00730 R= ((rgb0[0]*7967+32768)>>16); 00731 G= ((rgb0[1]*16191+32768)>>16); 00732 B= ((rgb0[2]*7967+32768)>>16); 00733 uint16 rgb016= (R<<11) + (G<<5) + (B); 00734 R= ((rgb1[0]*7967+32768)>>16); 00735 G= ((rgb1[1]*16191+32768)>>16); 00736 B= ((rgb1[2]*7967+32768)>>16); 00737 uint16 rgb116= (R<<11) + (G<<5) + (B); 00738 // copy to block 00739 ((uint16*)dstBlock)[0]= rgb016; 00740 ((uint16*)dstBlock)[1]= rgb116; 00741 00742 00743 // **** compute bits 00744 CRGBA c[4]; 00745 c[0].set565(rgb016); 00746 c[1].set565(rgb116); 00747 c[2].blendFromui(c[0],c[1],85); 00748 c[3].blendFromui(c[0],c[1],171); 00749 // it is important that c[] and src Alpha are set to 0, because of "pmaddwd" use in MMX code... 00750 c[0].A= 0; 00751 c[1].A= 0; 00752 c[2].A= 0; 00753 c[3].A= 0; 00754 CRGBA *cPtr= c; 00755 00756 // result. 00757 uint32 bits= 0; 00758 00759 #ifdef NL_OS_WINDOWS 00760 if(CSystemInfo::hasMMX()) 00761 { 00762 // preapre mmx 00763 uint64 blank= 0; 00764 __asm 00765 { 00766 movq mm7, blank 00767 } 00768 00769 // for 16 pixels 00770 src= srcRGBA; 00771 for(n=16;n>0;n--,src++) 00772 { 00773 /* // C Version (+ little asm). 00774 uint minDist= 0xFFFFFFFF; 00775 uint id= 0; 00776 for(i=0;i<4;i++) 00777 { 00778 // applying factors such *23, *80, *6 gives better results, but slower (in MMX). 00779 uint dist= sqr((sint)src->R-(sint)c[i].R); 00780 dist+= sqr((sint)src->G-(sint)c[i].G); 00781 dist+= sqr((sint)src->B-(sint)c[i].B); 00782 if(dist<minDist) 00783 { 00784 minDist= dist; 00785 id= i; 00786 } 00787 } 00788 bits|=id; 00789 __asm 00790 { 00791 mov eax, bits 00792 ror eax, 2 00793 mov bits, eax 00794 }*/ 00795 __asm 00796 { 00797 mov esi, src 00798 mov edi, cPtr 00799 00800 mov ecx, 4 00801 mov edx, 0xFFFFFFFF // edx= minDist 00802 00803 movd mm0, [esi] 00804 punpcklbw mm0, mm7 00805 00806 mov esi, 4 // esi= id MinDist (inverted) 00807 00808 // compare 4 cases. 00809 myLoop: 00810 movd mm1, [edi] 00811 punpcklbw mm1, mm7 00812 psubsw mm1, mm0 00813 pmaddwd mm1, mm1 00814 movd eax, mm1 00815 psrlq mm1, 32 00816 movd ebx, mm1 00817 add eax, ebx 00818 00819 // take smaller of A and B. here: eax= A, edx= B 00820 sub eax, edx // eax= A-B 00821 sbb ebx, ebx // ebx= FF if A<B. 00822 and eax, ebx // eax= A-B if A<B 00823 add edx, eax // if A<B, edx= B+A-B= A, else, edx= B. => minimum 00824 // setup the "smaller" id. here esi= iB, ecx= iA 00825 not ebx // ebx= 0 if A<B, FF else 00826 sub esi, ecx // esi= iB-iA 00827 and esi, ebx // esi= 0 if A<B, iB-iA else 00828 add esi, ecx // esi= 0+iA= iA if A<B, else esi= iB-iA+iA= iB 00829 00830 add edi, 4 00831 dec ecx 00832 jnz myLoop 00833 00834 // reverse id 00835 mov edx, 4 00836 mov eax, bits 00837 sub edx, esi 00838 // and store into bits 00839 or eax, edx 00840 ror eax, 2 00841 mov bits, eax 00842 } 00843 } 00844 00845 00846 // end MMX block. 00847 __asm emms; 00848 } 00849 else 00850 #endif // NL_OS_WINDOWS 00851 { 00852 src= srcRGBA; 00853 for(n=16;n>0;n--,src++) 00854 { 00855 // C Version (+ little asm). 00856 uint minDist= 0xFFFFFFFF; 00857 uint id= 0; 00858 for(i=0;i<4;i++) 00859 { 00860 // applying factors such *23, *80, *6 gives better results, but slower (in MMX). 00861 uint dist= sqr((sint)src->R-(sint)c[i].R); 00862 dist+= sqr((sint)src->G-(sint)c[i].G); 00863 dist+= sqr((sint)src->B-(sint)c[i].B); 00864 if(dist<minDist) 00865 { 00866 minDist= dist; 00867 id= i; 00868 } 00869 } 00870 // a ror is faster, but full C version 00871 bits|= id<<30; 00872 // don't do it for the last. 00873 if(n>1) 00874 bits>>=2; 00875 } 00876 } 00877 00878 // copy 00879 ((uint32*)dstBlock)[1]= bits; 00880 } |
|
used by compressBlockRGB()
Definition at line 586 of file hls_color_texture.cpp. Referenced by compressBlockRGB().
00587 { 00588 // compute the min and max distance along the axis v. 00589 sint mind= INT_MAX; 00590 sint maxd= INT_MIN; 00591 sint *srcDiff= diffBlock; 00592 // for the 16 pixels 00593 for(uint n=16;n>0;n--,srcDiff+=3) 00594 { 00595 sint R= srcDiff[0]; 00596 sint G= srcDiff[1]; 00597 sint B= srcDiff[2]; 00598 sint d= R*v.x + G*v.y + B*v.z; 00599 if(d<mind) 00600 mind= d; 00601 if(d>maxd) 00602 maxd= d; 00603 } 00604 00605 // avoid overflow. here, Higher possible bit is 16+8+2 (add of 3 values=> *4) == 26 00606 // 26-12= 14. 14+16=30 => ok. 00607 mind>>= 12; 00608 maxd>>= 12; 00609 00610 // compute the 2 colors: rgb0 on the min, and rgb1 on the max 00611 rgb0[0]= mean[0]+ (mind*v.x>>20); 00612 rgb0[1]= mean[1]+ (mind*v.y>>20); 00613 rgb0[2]= mean[2]+ (mind*v.z>>20); 00614 rgb1[0]= mean[0]+ (maxd*v.x>>20); 00615 rgb1[1]= mean[1]+ (maxd*v.y>>20); 00616 rgb1[2]= mean[2]+ (maxd*v.z>>20); 00617 // clamp to 0..255 00618 fastClamp8(rgb0[0]); 00619 fastClamp8(rgb0[1]); 00620 fastClamp8(rgb0[2]); 00621 fastClamp8(rgb1[0]); 00622 fastClamp8(rgb1[1]); 00623 fastClamp8(rgb1[2]); 00624 } |
|
get num of masks
Definition at line 90 of file hls_color_texture.h. Referenced by NL3D::CHLSTextureBank::addTextureInstance().
00090 {return _Masks.size();} |
|
reset the build
Definition at line 82 of file hls_color_texture.cpp. References _Masks, and _NumMipMap. Referenced by CHLSColorTexture(), and setBitmap().
00083 { 00084 _Width= 0; 00085 _Height= 0; 00086 _NumMipMap= 0; 00087 contReset(_Texture); 00088 contReset(_Masks); 00089 } |
|
Definition at line 313 of file hls_color_texture.cpp. References _BlockToCompressIndex, _Masks, _NumMipMap, NLMISC::IStream::serial(), NLMISC::IStream::serialCont(), and NLMISC::IStream::serialVersion().
00314 { 00315 f.serialVersion(0); 00316 00317 f.serial(_Width, _Height, _NumMipMap, _BlockToCompressIndex); 00318 f.serialCont(_Texture); 00319 f.serialCont(_Masks); 00320 } |
|
setup the un-colored bitmap for the texture.
Definition at line 92 of file hls_color_texture.cpp. References _BlockToCompressIndex, _NumMipMap, NLMISC::CBitmap::getHeight(), NLMISC::CBitmap::getMipMapCount(), NLMISC::CBitmap::getPixelFormat(), NLMISC::CBitmap::getPixels(), NLMISC::CBitmap::getWidth(), height, nlassert, reset(), NLMISC::CObjectVector< uint8 >::size(), uint, uint8, and width.
00093 { 00094 nlassert(bmp.getPixelFormat()==CBitmap::DXTC5); 00095 uint width= bmp.getWidth(); 00096 uint height= bmp.getHeight(); 00097 uint mmCount= bmp.getMipMapCount(); 00098 nlassert(width>=1 && height>=1); 00099 nlassert(mmCount>1 || width*height==1); 00100 00101 // restart 00102 reset(); 00103 00104 // resize. 00105 uint m; 00106 uint pixelSize= 0; 00107 uint numTotalBlock= 0; 00108 for(m=0;m<mmCount;m++) 00109 { 00110 pixelSize+= bmp.getPixels(m).size(); 00111 uint mmWidth= bmp.getWidth(m); 00112 uint mmHeight= bmp.getHeight(m); 00113 uint wBlock= (mmWidth+3)/4; 00114 uint hBlock= (mmHeight+3)/4; 00115 numTotalBlock+= wBlock*hBlock; 00116 } 00117 // add the info for the "Block to compress" 00118 uint blockToCompressSize= 4*((numTotalBlock+31)/32); 00119 // allocate good size, and reset to 0 => no block to re-compress. 00120 _Texture.resize(pixelSize+blockToCompressSize, 0); 00121 00122 // fill texture 00123 uint8 *ptr= &_Texture[0]; 00124 for(m=0;m<mmCount;m++) 00125 { 00126 uint mSize= bmp.getPixels(m).size(); 00127 memcpy(ptr, &bmp.getPixels(m)[0], mSize); 00128 ptr+= mSize; 00129 } 00130 00131 // header 00132 _BlockToCompressIndex= pixelSize; 00133 _Width= width; 00134 _Height= height; 00135 _NumMipMap= mmCount; 00136 } |
|
uncompress DXTC5 RGB only block, into a RGBA raw array. Alpha is setup with undefined values
Definition at line 557 of file hls_color_texture.cpp. References NLMISC::CRGBA::blendFromui(), NLMISC::CRGBA::set565(), uint, uint16, uint32, and uint8. Referenced by buildColorVersion().
00558 { 00559 CRGBA c[4]; 00560 00561 uint16 color0; 00562 uint16 color1; 00563 uint32 bits; 00564 color0= *(uint16*)(srcDXTC+8); 00565 color1= *(uint16*)(srcDXTC+10); 00566 bits= *(uint32*)(srcDXTC+12); 00567 00568 c[0].set565(color0); 00569 c[1].set565(color1); 00570 00571 // ignore color0>color1 for DXT3 and DXT5. 00572 c[2].blendFromui(c[0],c[1],85); 00573 c[3].blendFromui(c[0],c[1],171); 00574 00575 // bits to color (ignore alpha result) 00576 for(uint n= 16;n>0;n--) 00577 { 00578 *dstRGBA= c[bits&3]; 00579 bits>>=2; 00580 dstRGBA++; 00581 } 00582 } |
|
Definition at line 126 of file hls_color_texture.h. Referenced by addMask(), buildColorVersion(), serial(), and setBitmap(). |
|
Definition at line 125 of file hls_color_texture.h. |
|
Definition at line 130 of file hls_color_texture.h. Referenced by addMask(), buildColorVersion(), getNumMasks(), reset(), and serial(). |
|
Definition at line 125 of file hls_color_texture.h. Referenced by addMask(), buildColorVersion(), reset(), serial(), and setBitmap(). |
|
Definition at line 128 of file hls_color_texture.h. |
|
Definition at line 125 of file hls_color_texture.h. |