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 "nel/misc/common.h"
00029 #include "3d/lod_character_manager.h"
00030 #include "3d/lod_character_shape.h"
00031 #include "3d/lod_character_shape_bank.h"
00032 #include "3d/lod_character_instance.h"
00033 #include "nel/misc/hierarchical_timer.h"
00034 #include "3d/fast_floor.h"
00035 #include "3d/lod_character_texture.h"
00036 #include "nel/misc/file.h"
00037
00038
00039 using namespace std;
00040 using namespace NLMISC;
00041
00042 namespace NL3D
00043 {
00044
00045
00046 H_AUTO_DECL ( NL3D_CharacterLod_Render )
00047
00048
00049
00050
00051 #define NL3D_CLOD_VERTEX_FORMAT (CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::PrimaryColorFlag)
00052 #define NL3D_CLOD_VERTEX_SIZE 24
00053 #define NL3D_CLOD_UV_OFF 12
00054 #define NL3D_CLOD_COLOR_OFF 20
00055
00056
00057 #define NL3D_CLOD_TEXT_NLOD_WIDTH 16
00058 #define NL3D_CLOD_TEXT_NLOD_HEIGHT 16
00059 #define NL3D_CLOD_TEXT_NUM_IDS NL3D_CLOD_TEXT_NLOD_WIDTH*NL3D_CLOD_TEXT_NLOD_HEIGHT
00060 #define NL3D_CLOD_BIGTEXT_WIDTH NL3D_CLOD_TEXT_NLOD_WIDTH*NL3D_CLOD_TEXT_WIDTH
00061 #define NL3D_CLOD_BIGTEXT_HEIGHT NL3D_CLOD_TEXT_NLOD_HEIGHT*NL3D_CLOD_TEXT_HEIGHT
00062
00063
00064 #define NL3D_CLOD_DEFAULT_TEXCOLOR CRGBA(255,255,255,255)
00065
00066
00067
00068 CLodCharacterManager::CLodCharacterManager()
00069 {
00070 _Driver= NULL;
00071 _MaxNumVertices= 3000;
00072 _Rendering= false;
00073
00074
00075 _VBuffer.setVertexFormat(NL3D_CLOD_VERTEX_FORMAT);
00076
00077
00078 nlassert( NL3D_CLOD_UV_OFF == _VBuffer.getTexCoordOff());
00079 nlassert( NL3D_CLOD_COLOR_OFF == _VBuffer.getColorOff());
00080
00081
00082 _BigTexture= new CTextureBlank;
00083
00084
00085 _BigTexture->setReleasable(false);
00086
00087 _BigTexture->resize(NL3D_CLOD_BIGTEXT_WIDTH, NL3D_CLOD_BIGTEXT_HEIGHT, CBitmap::RGBA);
00088
00089 _BigTexture->setUploadFormat(ITexture::RGB565);
00090 _BigTexture->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff);
00091 _BigTexture->setWrapS(ITexture::Clamp);
00092 _BigTexture->setWrapT(ITexture::Clamp);
00093
00094
00095 _FreeIds.resize(NL3D_CLOD_TEXT_NUM_IDS);
00096 for(uint i=0;i<_FreeIds.size();i++)
00097 {
00098 _FreeIds[i]= i;
00099 }
00100
00101
00102 _Material.initUnlit();
00103 _Material.setAlphaTest(true);
00104 _Material.setDoubleSided(true);
00105 _Material.setTexture(0, _BigTexture);
00106
00107
00108 _LightCorrectionMatrix.rotateZ((float)Pi/2);
00109 _LightCorrectionMatrix.invert();
00110 }
00111
00112
00113
00114 CLodCharacterManager::~CLodCharacterManager()
00115 {
00116 reset();
00117 }
00118
00119
00120 void CLodCharacterManager::reset()
00121 {
00122
00123 for(uint i=0;i<_ShapeBankArray.size();i++)
00124 {
00125 if(_ShapeBankArray[i])
00126 delete _ShapeBankArray[i];
00127 }
00128
00129
00130 contReset(_ShapeBankArray);
00131 contReset(_ShapeMap);
00132
00133
00134 deleteVertexBuffer();
00135 _Driver= NULL;
00136 }
00137
00138
00139 uint32 CLodCharacterManager::createShapeBank()
00140 {
00141
00142 for(uint i=0;i<_ShapeBankArray.size();i++)
00143 {
00144
00145 if(_ShapeBankArray[i]==NULL)
00146 {
00147 _ShapeBankArray[i]= new CLodCharacterShapeBank;
00148 return i;
00149 }
00150 }
00151
00152
00153 _ShapeBankArray.push_back(new CLodCharacterShapeBank);
00154 return _ShapeBankArray.size()-1;
00155 }
00156
00157
00158 const CLodCharacterShapeBank *CLodCharacterManager::getShapeBank(uint32 bankId) const
00159 {
00160 if(bankId>=_ShapeBankArray.size())
00161 return NULL;
00162 else
00163 return _ShapeBankArray[bankId];
00164 }
00165
00166
00167 CLodCharacterShapeBank *CLodCharacterManager::getShapeBank(uint32 bankId)
00168 {
00169 if(bankId>=_ShapeBankArray.size())
00170 return NULL;
00171 else
00172 return _ShapeBankArray[bankId];
00173 }
00174
00175
00176 void CLodCharacterManager::deleteShapeBank(uint32 bankId)
00177 {
00178 if(bankId>=_ShapeBankArray.size())
00179 {
00180 if(_ShapeBankArray[bankId])
00181 {
00182 delete _ShapeBankArray[bankId];
00183 _ShapeBankArray[bankId]= NULL;
00184 }
00185 }
00186 }
00187
00188
00189 sint32 CLodCharacterManager::getShapeIdByName(const std::string &name) const
00190 {
00191 CstItStrIdMap it= _ShapeMap.find(name);
00192 if(it==_ShapeMap.end())
00193 return -1;
00194 else
00195 return it->second;
00196 }
00197
00198
00199 const CLodCharacterShape *CLodCharacterManager::getShape(uint32 shapeId) const
00200 {
00201
00202 uint bankId= shapeId >> 16;
00203 uint shapeInBankId= shapeId &0xFFFF;
00204
00205
00206 const CLodCharacterShapeBank *shapeBank= getShapeBank(bankId);
00207 if(shapeBank)
00208 {
00209
00210 return shapeBank->getShape(shapeInBankId);
00211 }
00212 else
00213 return NULL;
00214 }
00215
00216
00217 bool CLodCharacterManager::compile()
00218 {
00219 bool error= false;
00220
00221
00222 contReset(_ShapeMap);
00223
00224
00225 for(uint i=0; i<_ShapeBankArray.size(); i++)
00226 {
00227 if(_ShapeBankArray[i])
00228 {
00229
00230 for(uint j=0; j<_ShapeBankArray[i]->getNumShapes(); j++)
00231 {
00232
00233 uint shapeId= (i<<16) + j;
00234
00235
00236 const CLodCharacterShape *shape= _ShapeBankArray[i]->getShape(j);
00237 if(shape)
00238 {
00239 const string &name= shape->getName();
00240 ItStrIdMap it= _ShapeMap.find(name);
00241 if(it == _ShapeMap.end())
00242
00243 _ShapeMap.insert(make_pair(name, shapeId));
00244 else
00245 {
00246 error= true;
00247 nlwarning("Found a Character Lod with same name in the manager: %s", name.c_str());
00248 }
00249 }
00250 }
00251 }
00252 }
00253
00254 return error;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 void CLodCharacterManager::setMaxVertex(uint32 maxVertex)
00266 {
00267
00268 nlassert(!isRendering());
00269 _MaxNumVertices= maxVertex;
00270 }
00271
00272
00273 void CLodCharacterManager::deleteVertexBuffer()
00274 {
00275
00276 if(_VBHard!=NULL)
00277 {
00278
00279 nlassert(_Driver!=NULL);
00280
00281
00282 _VBHard->unlock(0,0);
00283
00284
00285 _Driver->deleteVertexBufferHard(_VBHard);
00286 _VBHard= NULL;
00287 }
00288
00289
00290 _VBuffer.deleteAllVertices();
00291 }
00292
00293
00294
00295 void CLodCharacterManager::beginRender(IDriver *driver, const CVector &managerPos)
00296 {
00297 H_AUTO_USE ( NL3D_CharacterLod_Render )
00298
00299
00300 nlassert(!isRendering());
00301
00302
00303
00304 _CurrentVertexId=0;
00305 _CurrentTriId= 0;
00306
00307
00308
00309 nlassert(driver);
00310
00311
00312 nlassert(driver);
00313 if( _Driver==NULL || driver!=_Driver )
00314 {
00315
00316 deleteVertexBuffer();
00317 _Driver= driver;
00318 _VBHardOk= _Driver->supportVertexBufferHard();
00319 }
00320
00321
00322 if(_VBHard && _VBHard->getNumVertices()!=_MaxNumVertices)
00323 deleteVertexBuffer();
00324
00325
00326 if(_VBHardOk && _VBHard==NULL)
00327 {
00328 _VBHard= driver->createVertexBufferHard(_VBuffer.getVertexFormat(), _VBuffer.getValueTypePointer(),
00329 _MaxNumVertices, IDriver::VBHardAGP);
00330 }
00331
00332
00333 if(_VBHard==NULL)
00334 {
00335
00336 _VBuffer.setNumVertices(_MaxNumVertices);
00337 }
00338
00339
00340
00341
00342
00343 if(_VBHard)
00344 {
00345 _VertexData= (uint8*)_VBHard->lock();
00346 _VertexSize= _VBHard->getVertexSize();
00347 }
00348 else
00349 {
00350 _VertexData= (uint8*)_VBuffer.getVertexCoordPointer();
00351 _VertexSize= _VBuffer.getVertexSize();
00352 }
00353
00354 nlassert( _VertexSize == NL3D_CLOD_VERTEX_SIZE );
00355
00356
00357
00358 if(_Triangles.size()<_MaxNumVertices * 2)
00359 _Triangles.resize(_MaxNumVertices * 2);
00360
00361
00362 _ManagerMatrixPos= managerPos;
00363
00364
00365 _Rendering= true;
00366 }
00367
00368
00369
00370 static inline CRGBA computeLodLighting(const CVector &lightObjectSpace, const CVector &normalPtr, CRGBA ambient, CRGBA diffuse)
00371 {
00372
00373 float f= lightObjectSpace * normalPtr;
00374 f= max(0.f,f);
00375 sint f8= OptFastFloor(f*255);
00376 CRGBA lightRes;
00377 lightRes.modulateFromuiRGBOnly(diffuse, f8);
00378 lightRes.addRGBOnly(lightRes, ambient);
00379 return lightRes;
00380 }
00381
00382
00383
00384 bool CLodCharacterManager::addRenderCharacterKey(CLodCharacterInstance &instance, const CMatrix &worldMatrix,
00385 CRGBA ambient, CRGBA diffuse, const CVector &lightDir)
00386 {
00387 H_AUTO_USE ( NL3D_CharacterLod_Render )
00388
00389 nlassert(_Driver);
00390
00391 nlassert(isRendering());
00392
00393 CVector unPackScaleFactor;
00394 uint numVertices;
00395
00396
00397
00398
00399
00400 const CLodCharacterShape *clod= getShape(instance.ShapeId);
00401
00402 if(!clod)
00403 return true;
00404
00405
00406 const CVector *normalPtr= clod->getNormals();
00407
00408 const CUV *uvPtr= instance.getUVs();
00409
00410 nlassert(normalPtr && uvPtr);
00411
00412
00413 const CLodCharacterShape::CVector3s *vertPtr;
00414 vertPtr= clod->getAnimKey(instance.AnimId, instance.AnimTime, instance.WrapMode, unPackScaleFactor);
00415
00416 if(!vertPtr)
00417 return true;
00418
00419 numVertices= clod->getNumVertices();
00420
00421
00422 if(numVertices==0)
00423 return true;
00424
00425
00426 if(_CurrentVertexId+numVertices > _MaxNumVertices)
00427 return false;
00428
00429
00430 bool vertexColor= instance.VertexColors.size() == numVertices;
00431
00432
00433
00434
00435
00436
00437
00438 CVector matPos= worldMatrix.getPos();
00439
00440 matPos -= _ManagerMatrixPos;
00441
00442 float a00= worldMatrix.get()[0]; float a01= worldMatrix.get()[4]; float a02= worldMatrix.get()[8];
00443 float a10= worldMatrix.get()[1]; float a11= worldMatrix.get()[5]; float a12= worldMatrix.get()[9];
00444 float a20= worldMatrix.get()[2]; float a21= worldMatrix.get()[6]; float a22= worldMatrix.get()[10];
00445
00446
00447 CVector lightObjectSpace;
00448
00449 lightObjectSpace.x= a00 * lightDir.x + a10 * lightDir.y + a20 * lightDir.z;
00450 lightObjectSpace.y= a01 * lightDir.x + a11 * lightDir.y + a21 * lightDir.z;
00451 lightObjectSpace.z= a02 * lightDir.x + a12 * lightDir.y + a22 * lightDir.z;
00452
00453 lightObjectSpace= _LightCorrectionMatrix.mulVector(lightObjectSpace);
00454
00455 lightObjectSpace.normalize();
00456 lightObjectSpace= -lightObjectSpace;
00457
00458
00459 a00*= unPackScaleFactor.x; a01*= unPackScaleFactor.y; a02*= unPackScaleFactor.z;
00460 a10*= unPackScaleFactor.x; a11*= unPackScaleFactor.y; a12*= unPackScaleFactor.z;
00461 a20*= unPackScaleFactor.x; a21*= unPackScaleFactor.y; a22*= unPackScaleFactor.z;
00462
00463
00464
00465 uint8 *dstPtr;
00466 dstPtr= _VertexData + _CurrentVertexId * _VertexSize;
00467
00468
00469 if(vertexColor)
00470 {
00471
00472 const CRGBA *colorPtr= &instance.VertexColors[0];
00473 for(;numVertices>0;numVertices--)
00474 {
00475
00476
00477 CVector *dstVector= (CVector*)dstPtr;
00478 dstVector->x= a00 * vertPtr->x + a01 * vertPtr->y + a02 * vertPtr->z + matPos.x;
00479 dstVector->y= a10 * vertPtr->x + a11 * vertPtr->y + a12 * vertPtr->z + matPos.y;
00480 dstVector->z= a20 * vertPtr->x + a21 * vertPtr->y + a22 * vertPtr->z + matPos.z;
00481
00482 *(CUV*)(dstPtr + NL3D_CLOD_UV_OFF)= *uvPtr;
00483
00484
00485 CRGBA lightRes= computeLodLighting(lightObjectSpace, *normalPtr, ambient, diffuse);
00486
00487 ((CRGBA*)(dstPtr + NL3D_CLOD_COLOR_OFF))->modulateFromColorRGBOnly(*colorPtr, lightRes);
00488
00489 ((CRGBA*)(dstPtr + NL3D_CLOD_COLOR_OFF))->A= colorPtr->A;
00490
00491
00492 vertPtr++;
00493 uvPtr++;
00494 normalPtr++;
00495 colorPtr++;
00496 dstPtr+= NL3D_CLOD_VERTEX_SIZE;
00497 }
00498 }
00499 else
00500 {
00501 for(;numVertices>0;numVertices--)
00502 {
00503
00504
00505 CVector *dstVector= (CVector*)dstPtr;
00506 dstVector->x= a00 * vertPtr->x + a01 * vertPtr->y + a02 * vertPtr->z + matPos.x;
00507 dstVector->y= a10 * vertPtr->x + a11 * vertPtr->y + a12 * vertPtr->z + matPos.y;
00508 dstVector->z= a20 * vertPtr->x + a21 * vertPtr->y + a22 * vertPtr->z + matPos.z;
00509
00510 *(CUV*)(dstPtr + NL3D_CLOD_UV_OFF)= *uvPtr;
00511
00512
00513 CRGBA lightRes= computeLodLighting(lightObjectSpace, *normalPtr, ambient, diffuse);
00514 lightRes.A= 255;
00515
00516 *(CRGBA*)(dstPtr + NL3D_CLOD_COLOR_OFF)= lightRes;
00517
00518
00519 vertPtr++;
00520 uvPtr++;
00521 normalPtr++;
00522 dstPtr+= NL3D_CLOD_VERTEX_SIZE;
00523 }
00524 }
00525
00526
00527
00528
00529
00530
00531 uint numTriIdxs= clod->getNumTriangles() * 3;
00532
00533
00534 if(_CurrentTriId+numTriIdxs > _Triangles.size())
00535 {
00536 _Triangles.resize(_CurrentTriId+numTriIdxs);
00537 }
00538
00539
00540 const uint32 *srcIdx= clod->getTriangleArray();
00541 uint32 *dstIdx= &_Triangles[_CurrentTriId];
00542 for(;numTriIdxs>0;numTriIdxs--, srcIdx++, dstIdx++)
00543 {
00544 *dstIdx= *srcIdx + _CurrentVertexId;
00545 }
00546
00547
00548
00549
00550
00551
00552 _CurrentVertexId+= clod->getNumVertices();
00553
00554 _CurrentTriId+= clod->getNumTriangles() * 3;
00555
00556
00557
00558 return true;
00559 }
00560
00561
00562 void CLodCharacterManager::endRender()
00563 {
00564 H_AUTO_USE ( NL3D_CharacterLod_Render )
00565
00566 nlassert(_Driver);
00567
00568 nlassert(isRendering());
00569
00570
00571 if(_VBHard)
00572 {
00573
00574 _VBHard->unlock(0, _CurrentVertexId);
00575 }
00576
00577
00578 if(_CurrentTriId>0)
00579 {
00580
00581 CMatrix managerMatrix;
00582 managerMatrix.setPos(_ManagerMatrixPos);
00583 _Driver->setupModelMatrix(managerMatrix);
00584
00585
00586 if(_VBHard)
00587 _Driver->activeVertexBufferHard(_VBHard);
00588 else
00589 _Driver->activeVertexBuffer(_VBuffer);
00590
00591
00592 _Driver->renderTriangles(_Material, &_Triangles[0], _CurrentTriId/3);
00593 }
00594
00595
00596 _Rendering= false;
00597 }
00598
00599
00600 void CLodCharacterManager::setupNormalCorrectionMatrix(const CMatrix &normalMatrix)
00601 {
00602 _LightCorrectionMatrix= normalMatrix;
00603 _LightCorrectionMatrix.setPos(CVector::Null);
00604 _LightCorrectionMatrix.invert();
00605 }
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 CLodCharacterTmpBitmap::CLodCharacterTmpBitmap()
00617 {
00618 reset();
00619 }
00620
00621
00622 void CLodCharacterTmpBitmap::reset()
00623 {
00624
00625 _Bitmap.resize(1);
00626 _Bitmap[0]= CRGBA::Black;
00627 _WidthPower=0;
00628 _UShift= 8;
00629 _VShift= 8;
00630 }
00631
00632
00633 void CLodCharacterTmpBitmap::build(const NLMISC::CBitmap &bmpIn)
00634 {
00635 uint width= bmpIn.getWidth();
00636 uint height= bmpIn.getHeight();
00637 nlassert(width>0 && width<=256);
00638 nlassert(height>0 && height<=256);
00639
00640
00641 _Bitmap.resize(width*height);
00642 _WidthPower= getPowerOf2(width);
00643
00644 _UShift= 8-getPowerOf2(width);
00645 _VShift= 8-getPowerOf2(height);
00646
00647
00648 CBitmap bmp= bmpIn;
00649 bmp.convertToType(CBitmap::RGBA);
00650 CRGBA *src= (CRGBA*)&bmp.getPixels()[0];
00651 CRGBA *dst= _Bitmap.getPtr();
00652 for(sint nPix= width*height;nPix>0;nPix--, src++, dst++)
00653 {
00654 *dst= *src;
00655 }
00656 }
00657
00658
00659 void CLodCharacterTmpBitmap::build(CRGBA col)
00660 {
00661
00662 reset();
00663 _Bitmap[0]= col;
00664 }
00665
00666
00667
00668 void CLodCharacterManager::initInstance(CLodCharacterInstance &instance)
00669 {
00670
00671 if(instance._Owner)
00672 instance._Owner->releaseInstance(instance);
00673
00674
00675 const CLodCharacterShape *clod= getShape(instance.ShapeId);
00676
00677 if(!clod)
00678 return;
00679
00680 const CUV *uvSrc= clod->getUVs();
00681 nlassert(uvSrc);
00682
00683
00684
00685 instance._Owner= this;
00686 instance._UVs.resize(clod->getNumVertices());
00687
00688
00689 if(_FreeIds.empty())
00690 {
00691
00692 instance._TextureId= NL3D_CLOD_TEXT_NUM_IDS;
00693 CUV uv(0,0);
00694 fill(instance._UVs.begin(), instance._UVs.end(), uv);
00695 }
00696
00697 else
00698 {
00699
00700 instance._TextureId= _FreeIds.back();
00701 _FreeIds.pop_back();
00702
00703 uint xId= instance._TextureId % NL3D_CLOD_TEXT_NLOD_WIDTH;
00704 uint yId= instance._TextureId / NL3D_CLOD_TEXT_NLOD_WIDTH;
00705
00706 float scaleU= 1.0f / NL3D_CLOD_TEXT_NLOD_WIDTH;
00707 float scaleV= 1.0f / NL3D_CLOD_TEXT_NLOD_HEIGHT;
00708 float biasU= (float)xId / NL3D_CLOD_TEXT_NLOD_WIDTH;
00709 float biasV= (float)yId / NL3D_CLOD_TEXT_NLOD_HEIGHT;
00710
00711 CUV *uvDst= &instance._UVs[0];
00712 for(uint i=0; i<instance._UVs.size();i++)
00713 {
00714 uvDst[i].U= biasU + uvSrc[i].U*scaleU;
00715 uvDst[i].V= biasV + uvSrc[i].V*scaleV;
00716 }
00717 }
00718 }
00719
00720
00721 void CLodCharacterManager::releaseInstance(CLodCharacterInstance &instance)
00722 {
00723 if(instance._Owner==NULL)
00724 return;
00725 nlassert(this==instance._Owner);
00726
00727
00728 if(instance._TextureId>=0 && instance._TextureId<NL3D_CLOD_TEXT_NUM_IDS)
00729 _FreeIds.push_back(instance._TextureId);
00730
00731
00732 instance._Owner= NULL;
00733 instance._TextureId= -1;
00734 contReset(instance._UVs);
00735 }
00736
00737
00738
00739 CRGBA *CLodCharacterManager::getTextureInstance(CLodCharacterInstance &instance)
00740 {
00741 nlassert(instance._Owner==this);
00742 nlassert(instance._TextureId!=-1);
00743
00744 if(instance._TextureId==NL3D_CLOD_TEXT_NUM_IDS)
00745 return NULL;
00746
00747
00748 uint xId= instance._TextureId % NL3D_CLOD_TEXT_NLOD_WIDTH;
00749 uint yId= instance._TextureId / NL3D_CLOD_TEXT_NLOD_WIDTH;
00750
00751
00752 CRGBA *pix= (CRGBA*)&_BigTexture->getPixels(0)[0];
00753 return pix + yId*NL3D_CLOD_TEXT_HEIGHT*NL3D_CLOD_BIGTEXT_WIDTH + xId*NL3D_CLOD_TEXT_WIDTH;
00754 }
00755
00756
00757
00758 bool CLodCharacterManager::startTextureCompute(CLodCharacterInstance &instance)
00759 {
00760 CRGBA *dst= getTextureInstance(instance);
00761 if(!dst)
00762 return false;
00763
00764
00765 CRGBA col= NL3D_CLOD_DEFAULT_TEXCOLOR;
00766 for(uint y=0;y<NL3D_CLOD_TEXT_HEIGHT;y++)
00767 {
00768
00769 for(uint x=0;x<NL3D_CLOD_TEXT_WIDTH;x++)
00770 dst[x]= col;
00771
00772 dst+= NL3D_CLOD_BIGTEXT_WIDTH;
00773 }
00774
00775 return true;
00776 }
00777
00778
00779 void CLodCharacterManager::addTextureCompute(CLodCharacterInstance &instance, const CLodCharacterTexture &lodTexture)
00780 {
00781 CRGBA *dst= getTextureInstance(instance);
00782 if(!dst)
00783 return;
00784
00785
00786 nlassert(lodTexture.Texture.size()==NL3D_CLOD_TEXT_SIZE);
00787 const CLodCharacterTexture::CTUVQ *lookUpPtr= &lodTexture.Texture[0];
00788
00789
00790 for(uint y=0;y<NL3D_CLOD_TEXT_HEIGHT;y++)
00791 {
00792
00793 for(uint x=0;x<NL3D_CLOD_TEXT_WIDTH;x++)
00794 {
00795 CLodCharacterTexture::CTUVQ lut= *lookUpPtr;
00796
00797 if(lut.Q<dst[x].A)
00798 {
00799
00800 CRGBA col= _TmpBitmaps[lut.T].getPixel(lut.U, lut.V);
00801
00802 col.A= lut.Q;
00803
00804 dst[x]= col;
00805 }
00806
00807
00808 lookUpPtr++;
00809 }
00810
00811 dst+= NL3D_CLOD_BIGTEXT_WIDTH;
00812 }
00813 }
00814
00815
00816 void CLodCharacterManager::endTextureCompute(CLodCharacterInstance &instance, uint numBmpToReset)
00817 {
00818 CRGBA *dst= getTextureInstance(instance);
00819 if(!dst)
00820 return;
00821
00822
00823 for(uint y=0;y<NL3D_CLOD_TEXT_HEIGHT;y++)
00824 {
00825
00826 for(uint x=0;x<NL3D_CLOD_TEXT_WIDTH;x++)
00827 {
00828 dst[x].A= 255;
00829 }
00830
00831 dst+= NL3D_CLOD_BIGTEXT_WIDTH;
00832 }
00833
00834
00835 if(instance._TextureId==0)
00836 *(CRGBA*)&_BigTexture->getPixels(0)[0]= NL3D_CLOD_DEFAULT_TEXCOLOR;
00837
00838
00839 uint xId= instance._TextureId % NL3D_CLOD_TEXT_NLOD_WIDTH;
00840 uint yId= instance._TextureId / NL3D_CLOD_TEXT_NLOD_WIDTH;
00841
00842 _BigTexture->touchRect(
00843 CRect(xId*NL3D_CLOD_TEXT_WIDTH, yId*NL3D_CLOD_TEXT_HEIGHT, NL3D_CLOD_TEXT_WIDTH, NL3D_CLOD_TEXT_HEIGHT) );
00844
00845
00846 for(uint i=0; i<numBmpToReset; i++)
00847 {
00848 _TmpBitmaps[i].reset();
00849 }
00850
00851
00852
00853
00854 }
00855
00856
00857 }