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_far.h"
00029 #include "3d/tile_far_bank.h"
00030 #include "3d/patch.h"
00031 #include "3d/tile_color.h"
00032 #include "3d/zone.h"
00033 #include "3d/landscape.h"
00034 #include "nel/misc/system_info.h"
00035
00036
00037 using namespace NLMISC;
00038 using namespace NL3D;
00039
00040 namespace NL3D {
00041
00042 CRGBA CTextureFar::_LightmapExpanded[NL_NUM_PIXELS_ON_FAR_TILE_EDGE*NL_MAX_TILES_BY_PATCH_EDGE*NL_NUM_PIXELS_ON_FAR_TILE_EDGE*NL_MAX_TILES_BY_PATCH_EDGE];
00043 uint8 CTextureFar::_LumelExpanded[(NL_MAX_TILES_BY_PATCH_EDGE*NL_LUMEL_BY_TILE+1)*(NL_MAX_TILES_BY_PATCH_EDGE*NL_LUMEL_BY_TILE+1)];
00044 CRGBA CTextureFar::_TileTLIColors[(NL_MAX_TILES_BY_PATCH_EDGE+1)*(NL_MAX_TILES_BY_PATCH_EDGE+1)];
00045
00046 CTextureFar::CTextureFar()
00047 {
00048
00049 setReleasable (true);
00050
00051 _ULPrec= this;
00052 _ULNext= this;
00053 }
00054
00055 CTextureFar::~CTextureFar()
00056 {
00057
00058 nlassert(_ULPrec==this && _ULNext==this);
00059 }
00060
00061
00062 void CTextureFar::linkBeforeUL(CTextureFar *textNext)
00063 {
00064 nlassert(textNext);
00065
00066
00067 _ULNext->_ULPrec= _ULPrec;
00068 _ULPrec->_ULNext= _ULNext;
00069
00070 _ULNext= textNext;
00071 _ULPrec= textNext->_ULPrec;
00072
00073 _ULNext->_ULPrec= this;
00074 _ULPrec->_ULNext= this;
00075 }
00076
00077 void CTextureFar::unlinkUL()
00078 {
00079
00080 _ULNext->_ULPrec= _ULPrec;
00081 _ULPrec->_ULNext= _ULNext;
00082
00083 _ULPrec= this;
00084 _ULNext= this;
00085 }
00086
00087
00088 void CTextureFar::setSizeOfFarPatch (sint width, sint height)
00089 {
00090
00091 _OriginalWidth=width*NL_NUM_FAR_PATCHES_BY_EDGE;
00092 _OriginalHeight=height*NL_NUM_FAR_PATCHES_BY_EDGE;
00093
00094
00095 contReset (_Patches);
00096 _Patches.resize (NL_NUM_FAR_PATCHES_BY_TEXTURE);
00097
00098
00099 _PatchCount=0;
00100
00101
00102 setUploadFormat(RGB565);
00103
00104
00105 setFilterMode (Linear, LinearMipMapOff);
00106
00107
00108 setWrapS (Clamp);
00109 setWrapT (Clamp);
00110
00111
00112 for (sint p=0; p<NL_NUM_FAR_PATCHES_BY_TEXTURE; p++)
00113 {
00114
00115 _Patches[p].Patch=NULL;
00116 }
00117 }
00118
00119
00120 bool CTextureFar::addPatch (CPatch *pPatch, float& farUScale, float& farVScale, float& farUBias, float& farVBias, bool& bRot)
00121 {
00122
00123 nlassert (_PatchCount<NL_NUM_FAR_PATCHES_BY_TEXTURE);
00124
00125
00126 sint p;
00127 for (p=0; p<NL_NUM_FAR_PATCHES_BY_TEXTURE; p++)
00128 {
00129
00130 if (_Patches[p].Patch==NULL)
00131 {
00132
00133 _Patches[p].Patch=pPatch;
00134 break;
00135 }
00136 }
00137
00138 nlassert (p<NL_NUM_FAR_PATCHES_BY_TEXTURE);
00139
00140
00141 int x = ((p & NL_NUM_FAR_PATCHES_BY_EDGE_MASK) * _OriginalWidth) >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT;
00142 int y = ((p >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT) * _OriginalHeight) >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT;
00143
00144
00145 CRect rect (x, y, _OriginalWidth>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT, _OriginalHeight>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT);
00146 ITexture::touchRect (rect);
00147
00148
00149
00150
00151 bRot = ( pPatch->getOrderS() < pPatch->getOrderT() );
00152
00153
00154 farUScale=(float)((_OriginalWidth>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)-1)/(float)_OriginalWidth;
00155 farVScale=(float)((_OriginalHeight>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)-1)/(float)_OriginalHeight;
00156
00157
00158 farUBias=((float)x+0.5f)/(float)_OriginalWidth;
00159
00160
00161 farVBias=((float)y+0.5f)/(float)_OriginalHeight;
00162
00163
00164 _PatchCount++;
00165
00166 return (_PatchCount == NL_NUM_FAR_PATCHES_BY_TEXTURE);
00167 }
00168
00169
00170 bool CTextureFar::removePatch (CPatch *pPatch)
00171 {
00172
00173 nlassert (_PatchCount>0);
00174
00175
00176 sint p;
00177 for (p=0; p<NL_NUM_FAR_PATCHES_BY_TEXTURE; p++)
00178 {
00179
00180 if (_Patches[p].Patch==pPatch)
00181 {
00182
00183 _Patches[p].Patch=NULL;
00184 break;
00185 }
00186 }
00187
00188
00189 nlassert (p<NL_NUM_FAR_PATCHES_BY_TEXTURE);
00190
00191
00192 _PatchCount--;
00193
00194
00195 return (_PatchCount == 0);
00196 }
00197
00198 uint CTextureFar::touchPatch(uint p)
00199 {
00200
00201 nlassert (p<NL_NUM_FAR_PATCHES_BY_TEXTURE);
00202
00203
00204 if( _Patches[p].Patch!=NULL )
00205 {
00206
00207 int x = ((p & NL_NUM_FAR_PATCHES_BY_EDGE_MASK) * _OriginalWidth) >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT;
00208 int y = ((p >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT) * _OriginalHeight) >> NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT;
00209
00210
00211 CRect rect (x, y, _OriginalWidth>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT, _OriginalHeight>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT);
00212 ITexture::touchRect (rect);
00213
00214
00215 return (_OriginalWidth>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT) * (_OriginalHeight>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT);
00216 }
00217 else
00218 {
00219
00220 return 0;
00221 }
00222 }
00223
00224
00225 void CTextureFar::doGenerate ()
00226 {
00227
00228 CBitmap::resize (_OriginalWidth, _OriginalHeight, RGBA);
00229
00230
00231 if (_ListInvalidRect.begin()!=_ListInvalidRect.end())
00232 {
00233
00234
00235
00236 std::list<NLMISC::CRect>::iterator ite=_ListInvalidRect.begin();
00237 while (ite!=_ListInvalidRect.end())
00238 {
00239
00240 sint x=(ite->left()<<NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)/_Width;
00241 sint y=(ite->top()<<NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)/_Height;
00242
00243
00244 nlassert (x>=0);
00245 nlassert (x<NL_NUM_FAR_PATCHES_BY_EDGE);
00246 nlassert (y>=0);
00247 nlassert (y<NL_NUM_FAR_PATCHES_BY_EDGE);
00248
00249
00250 if (_Patches[x+(y<<NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)].Patch)
00251 rebuildRectangle (x, y);
00252
00253
00254 ite++;
00255 }
00256 }
00257 else
00258 {
00259
00260 for (sint y=0; y<NL_NUM_FAR_PATCHES_BY_EDGE; y++)
00261 for (sint x=0; x<NL_NUM_FAR_PATCHES_BY_EDGE; x++)
00262 {
00263
00264 if (_Patches[x+(y<<NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)].Patch)
00265 rebuildRectangle (x, y);
00266 }
00267 }
00268 }
00269
00270
00271
00272 void CTextureFar::rebuildRectangle (uint x, uint y)
00273 {
00274
00275 CPatch* patch=_Patches[x+(y<<NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)].Patch;
00276
00277
00278 nlassert (patch);
00279
00280
00281 uint nS=patch->getOrderS();
00282 uint nT=patch->getOrderT();
00283
00284
00285 nlassert (getPixelFormat()==RGBA);
00286
00287
00288 nlassert (getPixels().size()!=0);
00289
00290
00291 uint nBaseOffset;
00292
00293
00294 sint dstDeltaX;
00295
00296
00297 sint dstDeltaY;
00298
00299
00300 uint larger;
00301
00302
00303 if (nS>=nT)
00304 {
00305
00306 nBaseOffset=((x*_Width)>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)+((y*_Height)>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)*_Width;
00307
00308
00309 dstDeltaX=1;
00310
00311
00312 dstDeltaY=_Width;
00313
00314
00315 larger=nS;
00316 }
00317
00318 else
00319 {
00320
00321 nBaseOffset=((x*_Width)>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)+((y*_Height)>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)*_Width;
00322 nBaseOffset+=((_Height>>NL_NUM_FAR_PATCHES_BY_EDGE_SHIFT)-1)*_Width;
00323
00324
00325 dstDeltaX=-(sint)_Width;
00326
00327
00328 dstDeltaY=1;
00329
00330
00331 larger=nT;
00332 }
00333
00334
00335 CTileFarBank::TFarOrder orderX=CTileFarBank::order0;
00336 uint tileSize=0;
00337 switch ((larger*NL_NUM_FAR_PATCHES_BY_EDGE*NL_NUM_PIXELS_ON_FAR_TILE_EDGE)/_Width)
00338 {
00339 case 4:
00340
00341 orderX=CTileFarBank::order2;
00342 tileSize=NL_NUM_PIXELS_ON_FAR_TILE_EDGE>>2;
00343 break;
00344 case 2:
00345
00346 orderX=CTileFarBank::order1;
00347 tileSize=NL_NUM_PIXELS_ON_FAR_TILE_EDGE>>1;
00348 break;
00349 case 1:
00350
00351 orderX=CTileFarBank::order0;
00352 tileSize=NL_NUM_PIXELS_ON_FAR_TILE_EDGE;
00353 break;
00354 default:
00355
00356 nlassert (0);
00357 }
00358
00359 #ifdef NL_DEBUG
00360
00361 CTileFarBank::TFarOrder orderY;
00362 switch ((std::min(nS, nT)*NL_NUM_FAR_PATCHES_BY_EDGE*NL_NUM_PIXELS_ON_FAR_TILE_EDGE)/_Height)
00363 {
00364 case 4:
00365
00366 orderY=CTileFarBank::order2;
00367 break;
00368 case 2:
00369
00370 orderY=CTileFarBank::order1;
00371 break;
00372 case 1:
00373
00374 orderY=CTileFarBank::order0;
00375 break;
00376 default:
00377
00378 nlassert (0);
00379 }
00380
00381
00382 nlassert (orderX == orderY);
00383 #endif // NL_DEBUG
00384
00385 nlassert (_Bank);
00386
00387
00388 sint nTileInPatch=0;
00389
00390
00391 NL3D_CComputeTileFar TileFar;
00392 TileFar.AsmMMX= false;
00393 #ifdef NL_OS_WINDOWS
00394 TileFar.AsmMMX= NLMISC::CSystemInfo::hasMMX();
00395 #endif
00396
00397
00398
00399
00400 TileFar.DstDeltaX=dstDeltaX;
00401 TileFar.DstDeltaY=dstDeltaY;
00402
00403
00404 NL3D_CExpandLightmap lightMap;
00405
00406
00407 lightMap.MulFactor=tileSize;
00408 lightMap.ColorTile=&patch->TileColors[0];
00409 lightMap.Width=nS+1;
00410 lightMap.Height=nT+1;
00411 lightMap.StaticLightColor=patch->getZone()->getLandscape()->getStaticLight();
00412 lightMap.DstPixels=_LightmapExpanded;
00413
00414 patch->computeCurrentTLILightmap(_TileTLIColors);
00415 lightMap.TLIColor= _TileTLIColors;
00416
00417
00418 patch->unpackShadowMap (_LumelExpanded);
00419 lightMap.LumelTile=_LumelExpanded;
00420
00421
00422 NL3D_expandLightmap (&lightMap);
00423
00424
00425 TileFar.SrcLightingDeltaY=nS*tileSize;
00426
00427
00428 uint nBaseDstTileLine=nBaseOffset;
00429 for (uint t=0; t<nT; t++)
00430 {
00431
00432 uint nBaseDstTilePixels=nBaseDstTileLine;
00433
00434
00435 for (uint s=0; s<nS; s++)
00436 {
00437
00438 TileFar.DstPixels=(CRGBA*)&(getPixels()[0])+nBaseDstTilePixels;
00439
00440
00441 TileFar.SrcLightingPixels=_LightmapExpanded+(s*tileSize)+(t*nS*tileSize*tileSize);
00442
00443
00444 for (sint l=0; l<3; l++)
00445 {
00446
00447 bool bAdditive=false;
00448
00449
00450 TileFar.Size=tileSize;
00451
00452
00453 const CTileElement &tileElm=patch->Tiles[nTileInPatch];
00454
00455
00456 bool is256x256;
00457 uint8 uvOff;
00458 tileElm.getTile256Info(is256x256, uvOff);
00459
00460
00461 sint tile=tileElm.Tile[l];
00462
00463
00464 bool lastLayer = ( (l == 2) || (tileElm.Tile[l+1] == NL_TILE_ELM_LAYER_EMPTY) );
00465
00466
00467 if (tile!=NL_TILE_ELM_LAYER_EMPTY)
00468 {
00469
00470 const CTileFarBank::CTileFar* pTile=_Bank->getTile (tile);
00471
00472
00473 if (pTile==NULL)
00474 nlwarning ("FarBank is not valid!");
00475
00476
00477 if (pTile)
00478 {
00479
00480 if (pTile->isFill (CTileFarBank::diffuse))
00481 {
00482
00483 sint nRot=tileElm.getTileOrient(l);
00484
00485
00486 const CRGBA* pSrcDiffusePixels=pTile->getPixels (CTileFarBank::diffuse, orderX);
00487 const CRGBA* pSrcAdditivePixels=NULL;
00488
00489
00490 if (pTile->isFill (CTileFarBank::additive))
00491 {
00492
00493 bAdditive=true;
00494
00495
00496 pSrcAdditivePixels=pTile->getPixels (CTileFarBank::additive, orderX);
00497 }
00498
00499
00500 sint sourceSize;
00501
00502
00503 uint sourceOffset=0;
00504
00505
00506 if (is256x256)
00507 {
00508
00509 if (uvOff&0x02)
00510 sourceOffset+=tileSize;
00511
00512
00513 if ((uvOff==1)||(uvOff==2))
00514 sourceOffset+=2*tileSize*tileSize;
00515
00516
00517 sourceSize=tileSize<<1;
00518 }
00519 else
00520 {
00521
00522 sourceSize=tileSize;
00523 }
00524
00525
00526 switch (nRot)
00527 {
00528 case 0:
00529
00530 TileFar.SrcDiffusePixels=pSrcDiffusePixels+sourceOffset;
00531 TileFar.SrcAdditivePixels=pSrcAdditivePixels+sourceOffset;
00532
00533
00534 TileFar.SrcDeltaX=1;
00535 TileFar.SrcDeltaY=sourceSize;
00536 break;
00537 case 1:
00538 {
00539
00540 uint newOffset=sourceOffset+(tileSize-1);
00541 TileFar.SrcDiffusePixels=pSrcDiffusePixels+newOffset;
00542 TileFar.SrcAdditivePixels=pSrcAdditivePixels+newOffset;
00543
00544
00545 TileFar.SrcDeltaX=sourceSize;
00546 TileFar.SrcDeltaY=-1;
00547 }
00548 break;
00549 case 2:
00550 {
00551
00552 uint newOffset=sourceOffset+(tileSize-1)*sourceSize+tileSize-1;
00553 TileFar.SrcDiffusePixels=pSrcDiffusePixels+newOffset;
00554 TileFar.SrcAdditivePixels=pSrcAdditivePixels+newOffset;
00555
00556
00557 TileFar.SrcDeltaX=-1;
00558 TileFar.SrcDeltaY=-sourceSize;
00559 }
00560 break;
00561 case 3:
00562 {
00563
00564 uint newOffset=sourceOffset+(tileSize-1)*sourceSize;
00565 TileFar.SrcDiffusePixels=pSrcDiffusePixels+newOffset;
00566 TileFar.SrcAdditivePixels=pSrcAdditivePixels+newOffset;
00567
00568
00569 TileFar.SrcDeltaX=-sourceSize;
00570 TileFar.SrcDeltaY=1;
00571 }
00572 break;
00573 }
00574
00575
00576
00577
00578 if (l>0)
00579 {
00580
00581 if (bAdditive && lastLayer)
00582 NL3D_drawFarTileInFarTextureAdditiveAlpha (&TileFar);
00583 else
00584 NL3D_drawFarTileInFarTextureAlpha (&TileFar);
00585 }
00586 else
00587 {
00588
00589 if (bAdditive && lastLayer)
00590 NL3D_drawFarTileInFarTextureAdditive (&TileFar);
00591 else
00592 NL3D_drawFarTileInFarTexture (&TileFar);
00593 }
00594 }
00595 }
00596 }
00597 else
00598
00599 break;
00600 }
00601
00602
00603 nTileInPatch++;
00604
00605
00606 nBaseDstTilePixels+=dstDeltaX*tileSize;
00607 }
00608
00609
00610 nBaseDstTileLine+=dstDeltaY*tileSize;
00611 }
00612
00613 }
00614
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624 #ifdef NL_OS_WINDOWS
00625
00626
00627
00628 # pragma warning (disable : 4799)
00629
00630
00631
00632 inline void NL3D_asmEndMMX()
00633 {
00634 __asm
00635 {
00636
00637 emms
00638 }
00639 }
00640
00641
00642
00646 inline void NL3D_asmExpandLineColor565(const uint16 *src, CRGBA *dst, uint du, uint len)
00647 {
00648 static uint64 blank = 0;
00649 static uint64 cF800 = 0x0000F8000000F800;
00650 static uint64 cE000 = 0x0000E0000000E000;
00651 static uint64 c07E0 = 0x000007E0000007E0;
00652 static uint64 c0600 = 0x0000060000000600;
00653 static uint64 c001F = 0x0000001F0000001F;
00654 static uint64 c001C = 0x0000001C0000001C;
00655 if(len==0)
00656 return;
00657
00658
00659
00660 __asm
00661 {
00662 movq mm7, blank
00663
00664
00665 mov esi, src
00666 mov edi, dst
00667 add edi, 4
00668 mov ecx, len
00669 mov edx, du
00670
00671
00672 myLoop:
00673
00674
00675
00676
00677
00678 mov ebx, edx
00679 shr ebx, 8
00680
00681
00682 xor eax, eax
00683 mov ax, [esi + ebx*2]
00684 shl eax, 16
00685 mov ax, [esi + ebx*2 +2]
00686
00687
00688 movd mm2, eax
00689 punpcklwd mm2, mm7
00690
00691
00692 movq mm3, mm7
00693
00694
00695
00696 movq mm0, mm2
00697 movq mm1, mm2
00698 pand mm0, cF800
00699 pand mm1, cE000
00700 psrld mm0, 8
00701 psrld mm1, 13
00702 por mm3, mm0
00703 por mm3, mm1
00704
00705 movq mm0, mm2
00706 movq mm1, mm2
00707 pand mm0, c07E0
00708 pand mm1, c0600
00709 pslld mm0, 5
00710 psrld mm1, 1
00711 por mm3, mm0
00712 por mm3, mm1
00713
00714 movq mm0, mm2
00715 movq mm1, mm2
00716 pand mm0, c001F
00717 pand mm1, c001C
00718 pslld mm0, 19
00719 pslld mm1, 14
00720 por mm3, mm0
00721 por mm3, mm1
00722
00723
00724 movq mm0, mm3
00725 movq mm1, mm3
00726 psrlq mm0, 32
00727
00728
00729
00730
00731
00732 mov ebx, edx
00733 mov eax, 256
00734
00735 and ebx, 0xFF
00736 sub eax, ebx
00737
00738 movd mm2, ebx
00739 movd mm3, eax
00740
00741 punpckldq mm2, mm2
00742 punpckldq mm3, mm3
00743 packssdw mm2, mm2
00744 packssdw mm3, mm3
00745
00746
00747 punpcklbw mm0, mm7
00748 punpcklbw mm1, mm7
00749 pmullw mm0, mm3
00750 pmullw mm1, mm2
00751
00752 paddusw mm0, mm1
00753 psrlw mm0, 8
00754 packuswb mm0, mm0
00755
00756
00757 movd [edi], mm0
00758
00759
00760
00761 add edx, du
00762 add edi, 4
00763 dec ecx
00764 jnz myLoop
00765 }
00766 }
00767
00768
00769
00773 inline void NL3D_asmExpandLineColor8888(const CRGBA *src, CRGBA *dst, uint du, uint len)
00774 {
00775 static uint64 blank = 0;
00776 if(len==0)
00777 return;
00778
00779
00780
00781 __asm
00782 {
00783 movq mm7, blank
00784
00785
00786 mov esi, src
00787 mov edi, dst
00788 add edi, 4
00789 mov ecx, len
00790 mov edx, du
00791
00792
00793 myLoop:
00794
00795
00796
00797
00798
00799 mov ebx, edx
00800 shr ebx, 8
00801
00802
00803 movd mm0 , [esi + ebx*4]
00804 movd mm1 , [esi + ebx*4 + 4]
00805
00806
00807
00808
00809
00810 mov ebx, edx
00811 mov eax, 256
00812
00813 and ebx, 0xFF
00814 sub eax, ebx
00815
00816 movd mm2, ebx
00817 movd mm3, eax
00818
00819 punpckldq mm2, mm2
00820 punpckldq mm3, mm3
00821 packssdw mm2, mm2
00822 packssdw mm3, mm3
00823
00824
00825 punpcklbw mm0, mm7
00826 punpcklbw mm1, mm7
00827 pmullw mm0, mm3
00828 pmullw mm1, mm2
00829
00830 paddusw mm0, mm1
00831 psrlw mm0, 8
00832 packuswb mm0, mm0
00833
00834
00835 movd [edi], mm0
00836
00837
00838
00839 add edx, du
00840 add edi, 4
00841 dec ecx
00842 jnz myLoop
00843 }
00844 }
00845
00846
00847
00851 inline void NL3D_asmBlendLines(CRGBA *dst, const CRGBA *src0, const CRGBA *src1, uint index, uint len)
00852 {
00853 static uint64 blank = 0;
00854 if(len==0)
00855 return;
00856
00857
00858
00859 __asm
00860 {
00861 movq mm7, blank
00862
00863
00864 mov ebx, index
00865 mov eax, 256
00866 and ebx, 0xFF
00867 sub eax, ebx
00868 movd mm2, ebx
00869 movd mm3, eax
00870 punpckldq mm2, mm2
00871 punpckldq mm3, mm3
00872 packssdw mm2, mm2
00873 packssdw mm3, mm3
00874
00875
00876 mov esi, src0
00877 mov edx, src1
00878 sub edx, esi
00879 mov edi, dst
00880 mov ecx, len
00881
00882
00883 myLoop:
00884
00885
00886 movd mm0, [esi]
00887 movd mm1, [esi+edx]
00888
00889
00890 punpcklbw mm0, mm7
00891 punpcklbw mm1, mm7
00892 pmullw mm0, mm3
00893 pmullw mm1, mm2
00894
00895 paddusw mm0, mm1
00896 psrlw mm0, 8
00897 packuswb mm0, mm0
00898
00899
00900 movd [edi], mm0
00901
00902
00903
00904 add esi, 4
00905 add edi, 4
00906 dec ecx
00907 jnz myLoop
00908 }
00909 }
00910
00911
00912
00916 static void NL3D_asmAssembleShading1x1(const uint8 *lumels, const CRGBA *colorMap,
00917 const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint lineWidth, uint nbTexel)
00918 {
00919 static uint64 blank = 0;
00920 if(nbTexel==0)
00921 return;
00922
00923
00924 uint offsetTLIs= ((uint)srcTLIs-(uint)dst);
00925 uint offsetUSCs= ((uint)srcUSCs-(uint)dst);
00926
00927
00928 __asm
00929 {
00930 movq mm7, blank
00931
00932
00933 mov esi, lumels
00934 mov edi, dst
00935 mov ecx, nbTexel
00936
00937
00938 myLoop:
00939
00940
00941
00942 mov ebx, colorMap
00943 mov edx, lineWidth
00944
00945
00946 xor eax,eax
00947
00948 mov al, [esi + 0]
00949 add al, [esi + 1]
00950 adc ah, 0
00951 add al, [esi + 2]
00952 adc ah, 0
00953 add al, [esi + 3]
00954 adc ah, 0
00955
00956 add al, [esi + edx + 0]
00957 adc ah, 0
00958 add al, [esi + edx + 1]
00959 adc ah, 0
00960 add al, [esi + edx + 2]
00961 adc ah, 0
00962 add al, [esi + edx + 3]
00963 adc ah, 0
00964
00965 add al, [esi + edx*2 + 0]
00966 adc ah, 0
00967 add al, [esi + edx*2 + 1]
00968 adc ah, 0
00969 add al, [esi + edx*2 + 2]
00970 adc ah, 0
00971 add al, [esi + edx*2 + 3]
00972 adc ah, 0
00973
00974 lea edx, [edx + edx*2]
00975 add al, [esi + edx + 0]
00976 adc ah, 0
00977 add al, [esi + edx + 1]
00978 adc ah, 0
00979 add al, [esi + edx + 2]
00980 adc ah, 0
00981 add al, [esi + edx + 3]
00982 adc ah, 0
00983
00984 shr eax, 4
00985
00986
00987 movd mm0, [ebx + eax*4]
00988
00989
00990
00991 mov edx, offsetTLIs
00992 mov ebx, offsetUSCs
00993
00994
00995 paddusb mm0, [edi + edx]
00996
00997
00998 movd mm1, [edi + ebx]
00999 punpcklbw mm0, mm7
01000 punpcklbw mm1, mm7
01001 pmullw mm0, mm1
01002
01003 psrlw mm0, 8
01004 packuswb mm0, mm0
01005
01006
01007 movd [edi], mm0
01008
01009
01010
01011 add esi, 4
01012 add edi, 4
01013 dec ecx
01014 jnz myLoop
01015 }
01016 }
01017
01018
01019
01023 static void NL3D_asmAssembleShading2x2(const uint8 *lumels, const CRGBA *colorMap,
01024 const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint lineWidth, uint nbTexel)
01025 {
01026 static uint64 blank = 0;
01027 if(nbTexel==0)
01028 return;
01029
01030
01031 uint offsetTLIs= ((uint)srcTLIs-(uint)dst);
01032 uint offsetUSCs= ((uint)srcUSCs-(uint)dst);
01033
01034
01035 __asm
01036 {
01037 movq mm7, blank
01038
01039
01040 mov esi, lumels
01041 mov edi, dst
01042 mov ecx, nbTexel
01043
01044
01045 myLoop:
01046
01047
01048
01049 mov ebx, colorMap
01050 mov edx, lineWidth
01051
01052
01053 xor eax,eax
01054 mov al, [esi]
01055
01056 add al, [esi + 1]
01057 adc ah, 0
01058 add al, [esi + edx]
01059 adc ah, 0
01060 add al, [esi + edx + 1]
01061 adc ah, 0
01062
01063 shr eax, 2
01064
01065
01066 movd mm0, [ebx + eax*4]
01067
01068
01069
01070 mov edx, offsetTLIs
01071 mov ebx, offsetUSCs
01072
01073
01074 paddusb mm0, [edi + edx]
01075
01076
01077 movd mm1, [edi + ebx]
01078 punpcklbw mm0, mm7
01079 punpcklbw mm1, mm7
01080 pmullw mm0, mm1
01081
01082 psrlw mm0, 8
01083 packuswb mm0, mm0
01084
01085
01086 movd [edi], mm0
01087
01088
01089
01090 add esi, 2
01091 add edi, 4
01092 dec ecx
01093 jnz myLoop
01094 }
01095 }
01096
01097
01098
01099 # pragma warning (disable : 4731) // frame pointer register 'ebp' modified by inline assembly code
01100
01103 static void NL3D_asmAssembleShading4x4(const uint8 *lumels, const CRGBA *colorMap,
01104 const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint nbTexel)
01105 {
01106 static uint64 blank = 0;
01107 if(nbTexel==0)
01108 return;
01109
01110
01111 __asm
01112 {
01113
01114 push ebp
01115
01116 movq mm7, blank
01117
01118
01119 mov esi, lumels
01120 mov edi, dst
01121 mov edx, srcTLIs
01122 sub edx, edi
01123 mov ebx, srcUSCs
01124 sub ebx, edi
01125 mov ecx, nbTexel
01126
01127
01128 mov ebp, colorMap
01129
01130
01131 myLoop:
01132
01133
01134 xor eax,eax
01135 mov al,[esi]
01136 movd mm0, [ebp + eax*4]
01137
01138
01139 paddusb mm0, [edi + edx]
01140
01141
01142 movd mm1, [edi + ebx]
01143 punpcklbw mm0, mm7
01144 punpcklbw mm1, mm7
01145 pmullw mm0, mm1
01146
01147 psrlw mm0, 8
01148 packuswb mm0, mm0
01149
01150
01151 movd [edi], mm0
01152
01153
01154
01155 add esi, 1
01156 add edi, 4
01157 dec ecx
01158 jnz myLoop
01159
01160
01161 pop ebp
01162 }
01163
01164 }
01165
01166 # pragma warning (default : 4731) // frame pointer register 'ebp' modified by inline assembly code
01167
01168
01169 #else // NL_OS_WINDOWS
01170
01171
01172 inline void NL3D_asmEndMMX() {}
01173 inline void NL3D_asmExpandLineColor565(const uint16 *src, CRGBA *dst, uint du, uint len) {}
01174 inline void NL3D_asmExpandLineColor8888(const CRGBA *src, CRGBA *dst, uint du, uint len) {}
01175 inline void NL3D_asmBlendLines(CRGBA *dst, const CRGBA *src0, const CRGBA *src1, uint index, uint len) {}
01176 static void NL3D_asmAssembleShading1x1(const uint8 *lumels, const CRGBA *colorMap,
01177 const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint lineWidth, uint nbTexel)
01178 {
01179 }
01180 static void NL3D_asmAssembleShading2x2(const uint8 *lumels, const CRGBA *colorMap,
01181 const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint lineWidth, uint nbTexel)
01182 {
01183 }
01184 static void NL3D_asmAssembleShading4x4(const uint8 *lumels, const CRGBA *colorMap,
01185 const CRGBA *srcTLIs, const CRGBA *srcUSCs, CRGBA *dst, uint nbTexel)
01186 {
01187 }
01188
01189 #endif // NL_OS_WINDOWS
01190
01191
01192
01193 extern "C" void NL3D_expandLightmap (const NL3D_CExpandLightmap* pLightmap)
01194 {
01195 bool asmMMX= false;
01196 #ifdef NL_OS_WINDOWS
01197 asmMMX= CSystemInfo::hasMMX();
01198
01199 nlassert(sizeof(CTileColor)==2);
01200 #endif
01201
01202
01203 uint dstWidth=(pLightmap->Width-1)*pLightmap->MulFactor;
01204 uint dstHeight=(pLightmap->Height-1)*pLightmap->MulFactor;
01205
01206
01207
01208 static CRGBA expandedUserColorLine[ (NL_MAX_TILES_BY_PATCH_EDGE+1)*
01209 (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE ];
01210 static CRGBA expandedTLIColorLine[ (NL_MAX_TILES_BY_PATCH_EDGE+1)*
01211 (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE ];
01212
01213 static CRGBA expandedUserColor[ (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE *
01214 (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE ];
01215 static CRGBA expandedTLIColor[ (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE *
01216 (NL_MAX_TILES_BY_PATCH_EDGE+1)*NL_LUMEL_BY_TILE ];
01217
01218
01219
01220
01221 uint u, v;
01222
01223
01224 uint expandFactor=((pLightmap->Width-1)<<8)/(dstWidth-1);
01225
01226
01227 CRGBA *expandedUserColorLinePtr= expandedUserColorLine;
01228 CRGBA *expandedTLIColorLinePtr= expandedTLIColorLine;
01229
01230
01231 const NL3D::CTileColor *colorTilePtr=pLightmap->ColorTile;
01232 const NLMISC::CRGBA *colorTLIPtr= pLightmap->TLIColor;
01233
01234
01235 for (v=0; v<pLightmap->Height; v++)
01236 {
01237
01238 expandedUserColorLinePtr[0].set565 (colorTilePtr[0].Color565);
01239 expandedTLIColorLinePtr[0]= colorTLIPtr[0];
01240
01241
01242
01243 if(asmMMX)
01244 {
01245 NL3D_asmExpandLineColor565(&colorTilePtr->Color565, expandedUserColorLinePtr, expandFactor, dstWidth-2);
01246 NL3D_asmExpandLineColor8888(colorTLIPtr, expandedTLIColorLinePtr, expandFactor, dstWidth-2);
01247 }
01248
01249
01250 else
01251 {
01252
01253 uint srcIndexPixel=expandFactor;
01254
01255 for (u=1; u<dstWidth-1; u++)
01256 {
01257
01258 nlassert ( (u+v*dstWidth) < (sizeof(expandedUserColorLine)/sizeof(CRGBA)) );
01259
01260
01261 uint srcIndex=srcIndexPixel>>8;
01262 nlassert (srcIndex>=0);
01263 nlassert (srcIndex<pLightmap->Width-1);
01264
01265
01266 CRGBA color0;
01267 CRGBA color1;
01268 color0.set565 (colorTilePtr[srcIndex].Color565);
01269 color1.set565 (colorTilePtr[srcIndex+1].Color565);
01270 expandedUserColorLinePtr[u].blendFromui (color0, color1, srcIndexPixel&0xff);
01271
01272 color0= colorTLIPtr[srcIndex];
01273 color1= colorTLIPtr[srcIndex+1];
01274 expandedTLIColorLinePtr[u].blendFromui (color0, color1, srcIndexPixel&0xff);
01275
01276
01277 srcIndexPixel+=expandFactor;
01278 }
01279 }
01280
01281
01282 expandedUserColorLinePtr[dstWidth-1].set565 (colorTilePtr[pLightmap->Width-1].Color565);
01283 expandedTLIColorLinePtr[dstWidth-1]= colorTLIPtr[pLightmap->Width-1];
01284
01285
01286 expandedUserColorLinePtr+= dstWidth;
01287 expandedTLIColorLinePtr+= dstWidth;
01288 colorTilePtr+=pLightmap->Width;
01289 colorTLIPtr+=pLightmap->Width;
01290 }
01291
01292
01293 if(asmMMX)
01294 NL3D_asmEndMMX();
01295
01296
01297
01298
01299
01300 expandFactor=((pLightmap->Height-1)<<8)/(dstHeight-1);
01301
01302
01303 CRGBA *expandedUserColorPtr= expandedUserColor;
01304 CRGBA *expandedTLIColorPtr= expandedTLIColor;
01305
01306
01307 expandedUserColorLinePtr= expandedUserColorLine;
01308 expandedTLIColorLinePtr= expandedTLIColorLine;
01309
01310
01311 memcpy(expandedUserColorPtr, expandedUserColorLinePtr, dstWidth*sizeof(CRGBA));
01312 memcpy(expandedTLIColorPtr, expandedTLIColorLinePtr, dstWidth*sizeof(CRGBA));
01313
01314
01315 expandedUserColorPtr+=dstWidth;
01316 expandedTLIColorPtr+=dstWidth;
01317
01318
01319 uint indexPixel=expandFactor;
01320
01321
01322 for (v=1; v<dstHeight-1; v++)
01323 {
01324
01325 uint index=indexPixel>>8;
01326
01327
01328 CRGBA *colorTilePtr0= expandedUserColorLine + index*dstWidth;
01329 CRGBA *colorTilePtr1= expandedUserColorLine + (index+1)*dstWidth;
01330 CRGBA *colorTLIPtr0= expandedTLIColorLine + index*dstWidth;
01331 CRGBA *colorTLIPtr1= expandedTLIColorLine + (index+1)*dstWidth;
01332
01333
01334
01335 if(asmMMX)
01336 {
01337 NL3D_asmBlendLines(expandedUserColorPtr, colorTilePtr0, colorTilePtr1, indexPixel, dstWidth);
01338 NL3D_asmBlendLines(expandedTLIColorPtr, colorTLIPtr0, colorTLIPtr1, indexPixel, dstWidth);
01339 }
01340
01341
01342 else
01343 {
01344
01345 for (u=0; u<dstWidth; u++)
01346 {
01347 expandedUserColorPtr[u].blendFromui (colorTilePtr0[u], colorTilePtr1[u], indexPixel&0xff);
01348 expandedTLIColorPtr[u].blendFromui (colorTLIPtr0[u], colorTLIPtr1[u], indexPixel&0xff);
01349 }
01350 }
01351
01352
01353 indexPixel+=expandFactor;
01354
01355
01356 expandedUserColorPtr+=dstWidth;
01357 expandedTLIColorPtr+=dstWidth;
01358 }
01359
01360
01361 if(asmMMX)
01362 NL3D_asmEndMMX();
01363
01364
01365
01366 expandedUserColorPtr= expandedUserColor + dstWidth*(dstHeight-1);
01367 expandedTLIColorPtr= expandedTLIColor + dstWidth*(dstHeight-1);
01368
01369 expandedUserColorLinePtr= expandedUserColorLine + dstWidth*(pLightmap->Height-1);
01370 expandedTLIColorLinePtr= expandedTLIColorLine + dstWidth*(pLightmap->Height-1);
01371
01372
01373 memcpy(expandedUserColorPtr, expandedUserColorLinePtr, dstWidth*sizeof(CRGBA));
01374 memcpy(expandedTLIColorPtr, expandedTLIColorLinePtr, dstWidth*sizeof(CRGBA));
01375
01376
01377
01378
01379
01380 switch (pLightmap->MulFactor)
01381 {
01382 case 1:
01383 {
01384
01385 CRGBA *lineUSCPtr= expandedUserColor;
01386 CRGBA *lineTLIPtr= expandedTLIColor;
01387 CRGBA *lineDestPtr=pLightmap->DstPixels;
01388 const uint8 *lineLumelPtr=pLightmap->LumelTile;
01389 uint lineWidth=dstWidth<<2;
01390 uint lineWidthx2=lineWidth<<1;
01391 uint lineWidthx3=lineWidthx2+lineWidth;
01392 uint lineWidthx4=lineWidth<<2;
01393
01394
01395 for (v=0; v<dstHeight; v++)
01396 {
01397
01398
01399 if(asmMMX)
01400 {
01401 NL3D_asmAssembleShading1x1(lineLumelPtr, pLightmap->StaticLightColor, lineTLIPtr, lineUSCPtr, lineDestPtr,
01402 lineWidth, dstWidth);
01403 }
01404
01405
01406 else
01407 {
01408
01409 for (u=0; u<dstWidth; u++)
01410 {
01411
01412 uint lumelIndex=u<<2;
01413
01414
01415 uint shading=
01416 ((uint)lineLumelPtr[lumelIndex]+(uint)lineLumelPtr[lumelIndex+1]+(uint)lineLumelPtr[lumelIndex+2]+(uint)lineLumelPtr[lumelIndex+3]
01417 +(uint)lineLumelPtr[lumelIndex+lineWidth]+(uint)lineLumelPtr[lumelIndex+1+lineWidth]+(uint)lineLumelPtr[lumelIndex+2+lineWidth]+(uint)lineLumelPtr[lumelIndex+3+lineWidth]
01418 +(uint)lineLumelPtr[lumelIndex+lineWidthx2]+(uint)lineLumelPtr[lumelIndex+1+lineWidthx2]+(uint)lineLumelPtr[lumelIndex+2+lineWidthx2]+(uint)lineLumelPtr[lumelIndex+3+lineWidthx2]
01419 +(uint)lineLumelPtr[lumelIndex+lineWidthx3]+(uint)lineLumelPtr[lumelIndex+1+lineWidthx3]+(uint)lineLumelPtr[lumelIndex+2+lineWidthx3]+(uint)lineLumelPtr[lumelIndex+3+lineWidthx3]
01420 )>>4;
01421
01422
01423 CRGBA col;
01424 col.addRGBOnly(pLightmap->StaticLightColor[shading], lineTLIPtr[u]);
01425
01426
01427 lineDestPtr[u].modulateFromColorRGBOnly(col, lineUSCPtr[u]);
01428 }
01429 }
01430
01431
01432 lineUSCPtr+=dstWidth;
01433 lineTLIPtr+=dstWidth;
01434 lineDestPtr+=dstWidth;
01435 lineLumelPtr+=lineWidthx4;
01436 }
01437 break;
01438 }
01439 case 2:
01440 {
01441
01442 CRGBA *lineUSCPtr= expandedUserColor;
01443 CRGBA *lineTLIPtr= expandedTLIColor;
01444 CRGBA *lineDestPtr=pLightmap->DstPixels;
01445 const uint8 *lineLumelPtr=pLightmap->LumelTile;
01446 uint lineWidth=dstWidth*2;
01447 uint lineWidthx2=lineWidth<<1;
01448
01449
01450 for (v=0; v<dstHeight; v++)
01451 {
01452
01453
01454 if(asmMMX)
01455 {
01456 NL3D_asmAssembleShading2x2(lineLumelPtr, pLightmap->StaticLightColor, lineTLIPtr, lineUSCPtr, lineDestPtr,
01457 lineWidth, dstWidth);
01458 }
01459
01460
01461 else
01462 {
01463
01464 for (u=0; u<dstWidth; u++)
01465 {
01466
01467 uint lumelIndex=u<<1;
01468
01469
01470 uint shading=
01471 ((uint)lineLumelPtr[lumelIndex]+(uint)lineLumelPtr[lumelIndex+1]+(uint)lineLumelPtr[lumelIndex+lineWidth]+(uint)lineLumelPtr[lumelIndex+1+lineWidth])>>2;
01472
01473
01474 CRGBA col;
01475 col.addRGBOnly(pLightmap->StaticLightColor[shading], lineTLIPtr[u]);
01476
01477
01478 lineDestPtr[u].modulateFromColorRGBOnly(col, lineUSCPtr[u]);
01479 }
01480 }
01481
01482
01483 lineUSCPtr+=dstWidth;
01484 lineTLIPtr+=dstWidth;
01485 lineDestPtr+=dstWidth;
01486 lineLumelPtr+=lineWidthx2;
01487 }
01488 break;
01489 }
01490
01491 case 4:
01492
01493 CRGBA *lineUSCPtr= expandedUserColor;
01494 CRGBA *lineTLIPtr= expandedTLIColor;
01495 CRGBA *lineDestPtr=pLightmap->DstPixels;
01496 const uint8 *lineLumelPtr=pLightmap->LumelTile;
01497 uint nbTexel=dstWidth*dstHeight;
01498
01499
01500
01501 if(asmMMX)
01502 {
01503 NL3D_asmAssembleShading4x4(lineLumelPtr, pLightmap->StaticLightColor, lineTLIPtr, lineUSCPtr, lineDestPtr,
01504 nbTexel);
01505 }
01506
01507
01508 else
01509 {
01510
01511 for (u=0; u<nbTexel; u++)
01512 {
01513
01514 uint shading=lineLumelPtr[u];
01515
01516
01517 CRGBA col;
01518 col.addRGBOnly(pLightmap->StaticLightColor[shading], lineTLIPtr[u]);
01519
01520
01521 lineDestPtr[u].modulateFromColorRGBOnly(col, lineUSCPtr[u]);
01522 }
01523 }
01524 break;
01525 }
01526
01527
01528 if(asmMMX)
01529 NL3D_asmEndMMX();
01530
01531 }
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541 #ifdef NL_OS_WINDOWS
01542
01543
01544
01545 inline void NL3D_asmModulateLineColors(CRGBA *dst, const CRGBA *src0, const CRGBA *src1,
01546 uint len, uint src0DeltaX, uint dstDeltaX)
01547 {
01548 static uint64 blank= 0;
01549 if(len==0)
01550 return;
01551
01552 __asm
01553 {
01554 movq mm7, blank
01555
01556 mov esi, src0
01557 mov edx, src1
01558 mov edi, dst
01559 mov ecx, len
01560
01561 mov eax, src0DeltaX
01562 mov ebx, dstDeltaX
01563 sal eax, 2
01564 sal ebx, 2
01565
01566 myLoop:
01567
01568 movd mm0, [esi]
01569 movd mm1, [edx]
01570
01571
01572 punpcklbw mm0, mm7
01573 punpcklbw mm1, mm7
01574 pmullw mm0, mm1
01575 psrlw mm0, 8
01576
01577 packuswb mm0, mm0
01578
01579
01580 movd [edi], mm0
01581
01582
01583 add esi, eax
01584 add edi, ebx
01585 add edx, 4
01586 dec ecx
01587 jnz myLoop
01588 }
01589 }
01590
01591
01592
01593 inline void NL3D_asmModulateAndBlendLineColors(CRGBA *dst, const CRGBA *src0, const CRGBA *src1,
01594 uint len, uint src0DeltaX, uint dstDeltaX)
01595 {
01596 static uint64 blank= 0;
01597 static uint64 one= 0x0100010001000100;
01598 if(len==0)
01599 return;
01600
01601 __asm
01602 {
01603 movq mm7, blank
01604 movq mm6, one
01605
01606 mov esi, src0
01607 mov edx, src1
01608 mov edi, dst
01609 mov ecx, len
01610
01611 mov eax, src0DeltaX
01612 mov ebx, dstDeltaX
01613 sal eax, 2
01614 sal ebx, 2
01615
01616 myLoop:
01617
01618 movd mm0, [esi]
01619 movd mm1, [edx]
01620
01621
01622 movq mm2, mm0
01623 psrld mm2, 24
01624 punpckldq mm2, mm2
01625 packssdw mm2, mm2
01626
01627 movq mm3, mm6
01628 psubusw mm3, mm2
01629
01630
01631 punpcklbw mm0, mm7
01632 punpcklbw mm1, mm7
01633 pmullw mm0, mm1
01634 psrlw mm0, 8
01635
01636
01637 movd mm1, [edi]
01638 punpcklbw mm1, mm7
01639 pmullw mm0, mm2
01640 pmullw mm1, mm3
01641
01642
01643 paddusw mm0, mm1
01644 psrlw mm0, 8
01645 packuswb mm0, mm0
01646
01647
01648 movd [edi], mm0
01649
01650
01651 add esi, eax
01652 add edi, ebx
01653 add edx, 4
01654 dec ecx
01655 jnz myLoop
01656 }
01657 }
01658
01659
01660 #else // NL_OS_WINDOWS
01661
01662
01663 inline void NL3D_asmModulateLineColors(CRGBA *dst, const CRGBA *src0, const CRGBA *src1,
01664 uint len, uint src0DeltaX, uint dstDeltaX)
01665 {
01666 }
01667 inline void NL3D_asmModulateAndBlendLineColors(CRGBA *dst, const CRGBA *src0, const CRGBA *src1,
01668 uint len, uint src0DeltaX, uint dstDeltaX)
01669 {
01670 }
01671
01672 #endif
01673
01674
01675 void NL3D_drawFarTileInFarTexture (const NL3D_CComputeTileFar* pTileFar)
01676 {
01677
01678 const CRGBA* pSrcPixels=pTileFar->SrcDiffusePixels;
01679
01680
01681 const CRGBA* pSrcLightPixels=pTileFar->SrcLightingPixels;
01682
01683
01684 CRGBA* pDstPixels=pTileFar->DstPixels;
01685
01686
01687 int x, y;
01688 for (y=0; y<pTileFar->Size; y++)
01689 {
01690
01691
01692 if(pTileFar->AsmMMX)
01693 {
01694 NL3D_asmModulateLineColors(pDstPixels, pSrcPixels, pSrcLightPixels,
01695 pTileFar->Size, pTileFar->SrcDeltaX, pTileFar->DstDeltaX);
01696 }
01697
01698
01699 else
01700 {
01701
01702 const CRGBA* pSrcLine=pSrcPixels;
01703
01704
01705 const CRGBA* pSrcLightingLine=pSrcLightPixels;
01706
01707
01708 CRGBA* pDstLine=pDstPixels;
01709
01710
01711 for (x=0; x<pTileFar->Size; x++)
01712 {
01713
01714 pDstLine->R=(uint8)(((uint)pSrcLine->R*(uint)pSrcLightingLine->R)>>8);
01715 pDstLine->G=(uint8)(((uint)pSrcLine->G*(uint)pSrcLightingLine->G)>>8);
01716 pDstLine->B=(uint8)(((uint)pSrcLine->B*(uint)pSrcLightingLine->B)>>8);
01717
01718
01719 pSrcLine+=pTileFar->SrcDeltaX;
01720 pSrcLightingLine++;
01721 pDstLine+=pTileFar->DstDeltaX;
01722 }
01723 }
01724
01725
01726 pSrcPixels+=pTileFar->SrcDeltaY;
01727 pSrcLightPixels+=pTileFar->SrcLightingDeltaY;
01728 pDstPixels+=pTileFar->DstDeltaY;
01729 }
01730
01731
01732 if(pTileFar->AsmMMX)
01733 NL3D_asmEndMMX();
01734 }
01735
01736
01737
01738 void NL3D_drawFarTileInFarTextureAlpha (const NL3D_CComputeTileFar* pTileFar)
01739 {
01740
01741 const CRGBA* pSrcPixels=pTileFar->SrcDiffusePixels;
01742
01743
01744 const CRGBA* pSrcLightPixels=pTileFar->SrcLightingPixels;
01745
01746
01747 CRGBA* pDstPixels=pTileFar->DstPixels;
01748
01749
01750 int x, y;
01751 for (y=0; y<pTileFar->Size; y++)
01752 {
01753
01754
01755 if(pTileFar->AsmMMX)
01756 {
01757 NL3D_asmModulateAndBlendLineColors(pDstPixels, pSrcPixels, pSrcLightPixels,
01758 pTileFar->Size, pTileFar->SrcDeltaX, pTileFar->DstDeltaX);
01759 }
01760
01761
01762 else
01763 {
01764
01765 const CRGBA* pSrcLine=pSrcPixels;
01766
01767
01768 const CRGBA* pSrcLightingLine=pSrcLightPixels;
01769
01770
01771 CRGBA* pDstLine=pDstPixels;
01772
01773
01774 for (x=0; x<pTileFar->Size; x++)
01775 {
01776
01777 register uint alpha=pSrcLine->A;
01778 register uint oneLessAlpha=255-pSrcLine->A;
01779 pDstLine->R=(uint8)(((((uint)pSrcLine->R*(uint)pSrcLightingLine->R)>>8)*alpha+(uint)pDstLine->R*oneLessAlpha)>>8);
01780 pDstLine->G=(uint8)(((((uint)pSrcLine->G*(uint)pSrcLightingLine->G)>>8)*alpha+(uint)pDstLine->G*oneLessAlpha)>>8);
01781 pDstLine->B=(uint8)(((((uint)pSrcLine->B*(uint)pSrcLightingLine->B)>>8)*alpha+(uint)pDstLine->B*oneLessAlpha)>>8);
01782
01783
01784 pSrcLine+=pTileFar->SrcDeltaX;
01785 pSrcLightingLine++;
01786 pDstLine+=pTileFar->DstDeltaX;
01787 }
01788 }
01789
01790
01791 pSrcPixels+=pTileFar->SrcDeltaY;
01792 pSrcLightPixels+=pTileFar->SrcLightingDeltaY;
01793 pDstPixels+=pTileFar->DstDeltaY;
01794 }
01795
01796
01797 if(pTileFar->AsmMMX)
01798 NL3D_asmEndMMX();
01799 }
01800
01801
01802
01803
01804
01805 void NL3D_drawFarTileInFarTextureAdditive (const NL3D_CComputeTileFar* pTileFar)
01806 {
01807
01808 const CRGBA* pSrcPixels=pTileFar->SrcDiffusePixels;
01809
01810
01811 const CRGBA* pSrcAddPixels=pTileFar->SrcAdditivePixels;
01812
01813
01814 const CRGBA* pSrcLightPixels=pTileFar->SrcLightingPixels;
01815
01816
01817 CRGBA* pDstPixels=pTileFar->DstPixels;
01818
01819
01820 int x, y;
01821 for (y=0; y<pTileFar->Size; y++)
01822 {
01823
01824 const CRGBA* pSrcLine=pSrcPixels;
01825
01826
01827 const CRGBA* pSrcAddLine=pSrcAddPixels;
01828
01829
01830 const CRGBA* pSrcLightingLine=pSrcLightPixels;
01831
01832
01833 CRGBA* pDstLine=pDstPixels;
01834
01835
01836 for (x=0; x<pTileFar->Size; x++)
01837 {
01838
01839 uint nTmp=(((uint)pSrcLine->R*(uint)pSrcLightingLine->R)>>8)+(uint)pSrcAddLine->R;
01840 if (nTmp>255)
01841 nTmp=255;
01842 pDstLine->R=(uint8)nTmp;
01843 nTmp=(((uint)pSrcLine->G*(uint)pSrcLightingLine->G)>>8)+(uint)pSrcAddLine->G;
01844 if (nTmp>255)
01845 nTmp=255;
01846 pDstLine->G=(uint8)nTmp;
01847 nTmp=(((uint)pSrcLine->B*(uint)pSrcLightingLine->B)>>8)+(uint)pSrcAddLine->B;
01848 if (nTmp>255)
01849 nTmp=255;
01850 pDstLine->B=(uint8)nTmp;
01851
01852
01853 pSrcLine+=pTileFar->SrcDeltaX;
01854 pSrcAddLine+=pTileFar->SrcDeltaX;
01855 pSrcLightingLine++;
01856 pDstLine+=pTileFar->DstDeltaX;
01857 }
01858
01859
01860 pSrcPixels+=pTileFar->SrcDeltaY;
01861 pSrcAddPixels+=pTileFar->SrcDeltaY;
01862 pSrcLightPixels+=pTileFar->SrcLightingDeltaY;
01863 pDstPixels+=pTileFar->DstDeltaY;
01864 }
01865 }
01866
01867
01868
01869
01870
01871
01872 void NL3D_drawFarTileInFarTextureAdditiveAlpha (const NL3D_CComputeTileFar* pTileFar)
01873 {
01874
01875 const CRGBA* pSrcPixels=pTileFar->SrcDiffusePixels;
01876
01877
01878 const CRGBA* pSrcAddPixels=pTileFar->SrcAdditivePixels;
01879
01880
01881 const CRGBA* pSrcLightPixels=pTileFar->SrcLightingPixels;
01882
01883
01884 CRGBA* pDstPixels=pTileFar->DstPixels;
01885
01886
01887 int x, y;
01888 for (y=0; y<pTileFar->Size; y++)
01889 {
01890
01891 const CRGBA* pSrcLine=pSrcPixels;
01892
01893
01894 const CRGBA* pSrcAddLine=pSrcAddPixels;
01895
01896
01897 const CRGBA* pSrcLightingLine=pSrcLightPixels;
01898
01899
01900 CRGBA* pDstLine=pDstPixels;
01901
01902
01903 for (x=0; x<pTileFar->Size; x++)
01904 {
01905
01906 register uint alpha=pSrcLine->A;
01907 register uint oneLessAlpha=255-pSrcLine->A;
01908
01909
01910 uint nTmp=(((uint)pSrcLine->R*(uint)pSrcLightingLine->R)>>8)+(uint)pSrcAddLine->R;
01911 if (nTmp>255)
01912 nTmp=255;
01913 pDstLine->R=(uint8)((nTmp*alpha+pDstLine->R*oneLessAlpha)>>8);
01914 nTmp=(((uint)pSrcLine->G*(uint)pSrcLightingLine->G)>>8)+(uint)pSrcAddLine->G;
01915 if (nTmp>255)
01916 nTmp=255;
01917 pDstLine->G=(uint8)((nTmp*alpha+pDstLine->G*oneLessAlpha)>>8);
01918 nTmp=(((uint)pSrcLine->B*(uint)pSrcLightingLine->B)>>8)+(uint)pSrcAddLine->B;
01919 if (nTmp>255)
01920 nTmp=255;
01921 pDstLine->B=(uint8)((nTmp*alpha+pDstLine->B*oneLessAlpha)>>8);
01922
01923
01924 pSrcLine+=pTileFar->SrcDeltaX;
01925 pSrcAddLine+=pTileFar->SrcDeltaX;
01926 pSrcLightingLine++;
01927 pDstLine+=pTileFar->DstDeltaX;
01928 }
01929
01930
01931 pSrcPixels+=pTileFar->SrcDeltaY;
01932 pSrcAddPixels+=pTileFar->SrcDeltaY;
01933 pSrcLightPixels+=pTileFar->SrcLightingDeltaY;
01934 pDstPixels+=pTileFar->DstDeltaY;
01935 }
01936 }
01937