00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "std3d.h"
00025
00026 #include "nel/3d/vertex_buffer.h"
00027 #include "nel/misc/vector.h"
00028 #include "nel/misc/fast_mem.h"
00029 #include "nel/3d/driver.h"
00030 using namespace NLMISC;
00031
00032
00033 namespace NL3D
00034 {
00035
00036
00037
00038 const uint CVertexBuffer::SizeType[NumType]=
00039 {
00040 1*sizeof(double),
00041 1*sizeof(float),
00042 1*sizeof(short),
00043 2*sizeof(double),
00044 2*sizeof(float),
00045 2*sizeof(short),
00046 3*sizeof(double),
00047 3*sizeof(float),
00048 3*sizeof(short),
00049 4*sizeof(double),
00050 4*sizeof(float),
00051 4*sizeof(short),
00052 4*sizeof(char),
00053 };
00054
00055
00056 const uint CVertexBuffer::NumComponentsType[NumType] =
00057 {
00058 1,
00059 1,
00060 1,
00061 2,
00062 2,
00063 2,
00064 3,
00065 3,
00066 3,
00067 4,
00068 4,
00069 4,
00070 4
00071 };
00072
00073
00074
00075
00076 const CVertexBuffer::TType CVertexBuffer::DefaultValueType[NumValue]=
00077 {
00078 Float3,
00079 Float3,
00080 Float2,
00081 Float2,
00082 Float2,
00083 Float2,
00084 Float2,
00085 Float2,
00086 Float2,
00087 Float2,
00088 UChar4,
00089 UChar4,
00090 Float4,
00091 UChar4,
00092 Float1,
00093 Float1,
00094 };
00095
00096
00097
00098
00099 void CVertexBuffer::construct()
00100 {
00101
00102
00103
00104
00105 _Flags = 0;
00106 _Capacity = 0;
00107 _NbVerts = 0;
00108 _InternalFlags = 0;
00109 _VertexSize = 0;
00110 _VertexColorFormat = TRGBA;
00111 _LockCounter = 0;
00112 _LockedBuffer = NULL;
00113 _PreferredMemory = RAMPreferred;
00114 _Location = NotResident;
00115 _ResidentSize = 0;
00116 _KeepLocalMemory = false;
00117
00118
00119 uint i;
00120 for (i=0; i<MaxStage; i++)
00121 _UVRouting[i] = i;
00122 }
00123
00124
00125
00126 CVertexBuffer::CVertexBuffer()
00127 {
00128 construct();
00129 }
00130
00131 CVertexBuffer::CVertexBuffer(const char *name)
00132 {
00133 construct();
00134 _Name = name;
00135 }
00136
00137
00138
00139
00140 CVertexBuffer::CVertexBuffer(const CVertexBuffer &vb) : CRefCount()
00141 {
00142
00143
00144
00145
00146
00147 _Flags = 0;
00148 _Capacity = 0;
00149 _NbVerts = 0;
00150 _VertexSize = 0;
00151 _LockCounter = 0;
00152 _LockedBuffer = NULL;
00153 _PreferredMemory = RAMPreferred;
00154 _Location = NotResident;
00155 _ResidentSize = 0;
00156 _KeepLocalMemory = false;
00157
00158 operator=(vb);
00159
00160
00161 uint i;
00162 for (i=0; i<MaxStage; i++)
00163 _UVRouting[i] = i;
00164 }
00165
00166
00167
00168 CVertexBuffer::~CVertexBuffer()
00169 {
00170
00171
00172
00173
00174
00175 if (DrvInfos)
00176 DrvInfos->VertexBufferPtr = NULL;
00177
00178
00179 DrvInfos.kill();
00180 }
00181
00182
00183
00184 CVertexBuffer &CVertexBuffer::operator=(const CVertexBuffer &vb)
00185 {
00186 nlassertex (!isLocked(), ("The vertex buffer is locked."));
00187 nlassertex (!vb.isLocked(), ("Source buffer is locked."));
00188
00189
00190 _VertexSize = vb._VertexSize;
00191 _Flags = vb._Flags;
00192 _InternalFlags = vb._InternalFlags;
00193 _NbVerts = vb._NbVerts;
00194 _Capacity = vb._Capacity;
00195 _NonResidentVertices = vb._NonResidentVertices;
00196 _VertexColorFormat = vb._VertexColorFormat;
00197 _PreferredMemory = vb._PreferredMemory;
00198 _KeepLocalMemory = vb._KeepLocalMemory;
00199 uint i;
00200 _LockCounter = 0;
00201 _LockedBuffer = NULL;
00202
00203
00204 for (uint value=0; value<NumValue; value++)
00205 {
00206 _Offset[value]= vb._Offset[value];
00207 _Type[value]= vb._Type[value];
00208 }
00209
00210
00211 for (i=0; i<MaxStage; i++)
00212 _UVRouting[i] = vb._UVRouting[i];
00213
00214
00215 _InternalFlags |= TouchedAll;
00216 _Location = NotResident;
00217 _ResidentSize = 0;
00218
00219 return *this;
00220 }
00221
00222
00223 void CVertexBuffer::copyVertices(CVertexBuffer &dest) const
00224 {
00225 nlassert(_PreferredMemory != RAMVolatile);
00226 nlassert(_PreferredMemory != AGPVolatile);
00227
00228 dest = *this;
00229 CVertexBufferReadWrite srcDatas;
00230 const_cast<CVertexBuffer *>(this)->lock(srcDatas);
00231 nlassert(dest.getLocation() == NotResident);
00232 CVertexBufferReadWrite destDatas;
00233 dest.lock(destDatas);
00234 NLMISC::CFastMem::memcpy (destDatas.getVertexCoordPointer(), srcDatas.getVertexCoordPointer(), getVertexSize() * getNumVertices());
00235 }
00236
00237
00238
00239 bool CVertexBuffer::setVertexFormat(uint32 flags)
00240 {
00241 nlassertex (!isLocked(), ("The vertex buffer is locked."));
00242
00243 uint i;
00244
00245
00246 clearValueEx ();
00247
00248
00249 if (flags & PositionFlag)
00250 {
00251
00252 addValueEx (Position, Float3);
00253 }
00254
00255
00256 if (flags & NormalFlag)
00257 {
00258
00259 addValueEx (Normal, Float3);
00260 }
00261
00262
00263 for(i=0 ; i<MaxStage ; i++)
00264 {
00265
00266 if (flags & (TexCoord0Flag<<i))
00267 {
00268
00269 addValueEx ((TValue)(TexCoord0+i), Float2);
00270 }
00271 }
00272
00273
00274 if (flags & FogFlag)
00275 {
00276
00277 addValueEx (Fog, Float1);
00278 }
00279
00280
00281 if (flags & PrimaryColorFlag)
00282 {
00283
00284 addValueEx (PrimaryColor, UChar4);
00285 }
00286
00287
00288 if (flags & SecondaryColorFlag)
00289 {
00290
00291 addValueEx (SecondaryColor, UChar4);
00292 }
00293
00294
00295 if (flags & WeightFlag)
00296 {
00297
00298 addValueEx (Weight, Float4);
00299 }
00300
00301
00302 if ((flags & PaletteSkinFlag)==CVertexBuffer::PaletteSkinFlag)
00303 {
00304
00305 addValueEx (PaletteSkin, UChar4);
00306 }
00307
00308
00309 initEx ();
00310
00311
00312 restaureNonResidentMemory();
00313
00314 return (true);
00315 }
00316
00317
00318
00319 CVertexBuffer::TValue CVertexBuffer::getValueIdByNumberEx (uint valueNumber)
00320 {
00321
00322 static TValue lut[16]= {
00323 Position,
00324 Weight,
00325 Normal,
00326 PrimaryColor,
00327 SecondaryColor,
00328 Fog,
00329 PaletteSkin,
00330 Empty,
00331 TexCoord0,
00332 TexCoord1,
00333 TexCoord2,
00334 TexCoord3,
00335 TexCoord4,
00336 TexCoord5,
00337 TexCoord6,
00338 TexCoord7,
00339 };
00340
00341 return lut[valueNumber];
00342 }
00343
00344
00345
00346 void CVertexBuffer::clearValueEx ()
00347 {
00348 nlassertex (!isLocked(), ("The vertex buffer is locked."));
00349
00350
00351 _Flags=0;
00352 }
00353
00354
00355
00356
00357 void CVertexBuffer::dumpFormat() const
00358 {
00359 for(uint k = 0; k < NumValue; ++k)
00360 {
00361 if (_Flags & (1 << k))
00362 {
00363 std::string result = "Component :";
00364 switch(k)
00365 {
00366 case Position: result += "Position"; break;
00367 case Normal: result += "Normal"; break;
00368 case TexCoord0: result += "TexCoord0"; break;
00369 case TexCoord1: result += "TexCoord1"; break;
00370 case TexCoord2: result += "TexCoord2"; break;
00371 case TexCoord3: result += "TexCoord3"; break;
00372 case TexCoord4: result += "TexCoord4"; break;
00373 case TexCoord5: result += "TexCoord5"; break;
00374 case TexCoord6: result += "TexCoord6"; break;
00375 case TexCoord7: result += "TexCoord7"; break;
00376 case PrimaryColor: result += "PrimaryColor"; break;
00377 case SecondaryColor:result += "SecondaryColor"; break;
00378 case Weight: result += "Weight"; break;
00379 case PaletteSkin: result += "PaletteSkin"; break;
00380 case Fog: result += "Fog"; break;
00381 case Empty: result += "Empty"; break;
00382 case NumValue: result += "NumValue"; break;
00383 default:
00384 result += "???";
00385 break;
00386 }
00387 result += "; type :";
00388 switch(_Type[k])
00389 {
00390 case Double1: result +="Double1"; break;
00391 case Float1: result +="Float1"; break;
00392 case Short1: result +="Short1"; break;
00393 case Double2: result +="Double2"; break;
00394 case Float2: result +="Float2"; break;
00395 case Short2: result +="Short2"; break;
00396 case Double3: result +="Double3"; break;
00397 case Float3: result +="Float3"; break;
00398 case Short3: result +="Short3"; break;
00399 case Double4: result +="Double4"; break;
00400 case Float4: result +="Float4"; break;
00401 case Short4: result +="Short4"; break;
00402 case UChar4: result +="UChar4"; break;
00403 default:
00404 result += "???";
00405 break;
00406 }
00407 nlinfo(result.c_str());
00408 }
00409 }
00410 }
00411
00412
00413
00414
00415 void CVertexBuffer::addValueEx (TValue valueId, TType type)
00416 {
00417 nlassertex (!isLocked(), ("The vertex buffer is locked."));
00418
00419
00420 _Flags |= 1<<valueId;
00421
00422
00423 _Type[valueId]=(uint8)type;
00424
00425 uint numComp = NumComponentsType[type];
00426
00427 switch (valueId)
00428 {
00429 case Position: nlassert(numComp >= 2); break;
00430 case Normal: nlassert(numComp == 3); break;
00431 case PrimaryColor: nlassert(numComp == 4); break;
00432 case SecondaryColor: nlassert(numComp == 4); break;
00433 case Weight: nlassert(numComp == 4); break;
00434 case PaletteSkin: nlassert(numComp == 4); break;
00435 case Fog: nlassert(numComp == 4); break;
00436 default: break;
00437 }
00438 }
00439
00440
00441
00442 bool CVertexBuffer::hasValueEx(TValue valueId) const
00443 {
00444 return (_Flags & (1 << valueId)) != 0;
00445 }
00446
00447
00448
00449 void CVertexBuffer::initEx ()
00450 {
00451 nlassert (!isLocked());
00452
00453
00454 _VertexSize=0;
00455 for (uint value=0; value<NumValue; value++)
00456 {
00457
00458 if (_Flags&(1<<value))
00459 {
00460
00461 _Offset[value]=_VertexSize;
00462
00463
00464 _VertexSize+=SizeType[_Type[value]];
00465 }
00466 }
00467
00468
00469 _NbVerts=0;
00470
00471
00472 if (_VertexSize)
00473 _Capacity = _NonResidentVertices.size()/_VertexSize;
00474 else
00475 _Capacity = 0;
00476
00477
00478 restaureNonResidentMemory();
00479 }
00480
00481
00482
00483 void CVertexBuffer::reserve(uint32 n)
00484 {
00485 nlassert (!isLocked());
00486 if (_Capacity != n)
00487 {
00488 _Capacity= n;
00489 _NbVerts=std::min (_NbVerts,_Capacity);
00490
00491
00492 restaureNonResidentMemory();
00493 }
00494 }
00495
00496
00497
00498 void CVertexBuffer::setNumVertices(uint32 n)
00499 {
00500 if(_Capacity<n)
00501 {
00502 reserve(n);
00503 }
00504 if(_NbVerts != n)
00505 {
00506 _InternalFlags |= TouchedNumVertices;
00507 _NbVerts=n;
00508 }
00509 }
00510
00511
00512
00513 void CVertexBuffer::deleteAllVertices()
00514 {
00515 if (_Capacity)
00516 {
00517 nlassert (!isLocked());
00518
00519 contReset(_NonResidentVertices);
00520 _Capacity= 0;
00521 if(_NbVerts!=0)
00522 {
00523 _NbVerts=0;
00524 _InternalFlags |= TouchedNumVertices;
00525 }
00526
00527
00528 restaureNonResidentMemory();
00529
00530
00531 nlassert (DrvInfos == NULL);
00532 }
00533 }
00534
00535
00536
00537 uint16 CVertexBuffer::remapV2Flags (uint32 oldFlags, uint& weightCount)
00538 {
00539
00540 const uint32 OLD_IDRV_VF_XYZ = 0x00000001;
00541 const uint32 OLD_IDRV_VF_W0 = 0x00000002;
00542 const uint32 OLD_IDRV_VF_W1 = 0x00000004;
00543 const uint32 OLD_IDRV_VF_W2 = 0x00000008;
00544 const uint32 OLD_IDRV_VF_W3 = 0x00000010;
00545 const uint32 OLD_IDRV_VF_NORMAL = 0x00000020;
00546 const uint32 OLD_IDRV_VF_COLOR = 0x00000040;
00547 const uint32 OLD_IDRV_VF_SPECULAR = 0x00000080;
00548 const uint32 OLD_IDRV_VF_UV0 = 0x00000100;
00549 const uint32 OLD_IDRV_VF_UV1 = 0x00000200;
00550 const uint32 OLD_IDRV_VF_UV2 = 0x00000400;
00551 const uint32 OLD_IDRV_VF_UV3 = 0x00000800;
00552 const uint32 OLD_IDRV_VF_UV4 = 0x00001000;
00553 const uint32 OLD_IDRV_VF_UV5 = 0x00002000;
00554 const uint32 OLD_IDRV_VF_UV6 = 0x00004000;
00555 const uint32 OLD_IDRV_VF_UV7 = 0x00008000;
00556 const uint32 OLD_IDRV_VF_PALETTE_SKIN = 0x00010000 | OLD_IDRV_VF_W0 | OLD_IDRV_VF_W1 | OLD_IDRV_VF_W2 | OLD_IDRV_VF_W3;
00557
00558
00559 uint16 newFlags=0;
00560
00561
00562 weightCount=0;
00563
00564
00565 if (oldFlags&OLD_IDRV_VF_XYZ)
00566 newFlags|=PositionFlag;
00567 if (oldFlags&OLD_IDRV_VF_NORMAL)
00568 newFlags|=NormalFlag;
00569 if (oldFlags&OLD_IDRV_VF_COLOR)
00570 newFlags|=PrimaryColorFlag;
00571 if (oldFlags&OLD_IDRV_VF_SPECULAR)
00572 newFlags|=SecondaryColorFlag;
00573 if (oldFlags&OLD_IDRV_VF_UV0)
00574 newFlags|=TexCoord0Flag;
00575 if (oldFlags&OLD_IDRV_VF_UV1)
00576 newFlags|=TexCoord1Flag;
00577 if (oldFlags&OLD_IDRV_VF_UV2)
00578 newFlags|=TexCoord2Flag;
00579 if (oldFlags&OLD_IDRV_VF_UV3)
00580 newFlags|=TexCoord3Flag;
00581 if (oldFlags&OLD_IDRV_VF_UV4)
00582 newFlags|=TexCoord4Flag;
00583 if (oldFlags&OLD_IDRV_VF_UV5)
00584 newFlags|=TexCoord5Flag;
00585 if (oldFlags&OLD_IDRV_VF_UV6)
00586 newFlags|=TexCoord6Flag;
00587 if (oldFlags&OLD_IDRV_VF_UV7)
00588 newFlags|=TexCoord7Flag;
00589 if (oldFlags&OLD_IDRV_VF_W0)
00590 {
00591 weightCount=1;
00592 newFlags|=WeightFlag;
00593 }
00594 if (oldFlags&OLD_IDRV_VF_W1)
00595 {
00596 weightCount=2;
00597 newFlags|=WeightFlag;
00598 }
00599 if (oldFlags&OLD_IDRV_VF_W2)
00600 {
00601 weightCount=3;
00602 newFlags|=WeightFlag;
00603 }
00604 if (oldFlags&OLD_IDRV_VF_W3)
00605 {
00606 weightCount=4;
00607 newFlags|=WeightFlag;
00608 }
00609 if (oldFlags&(OLD_IDRV_VF_PALETTE_SKIN))
00610 newFlags|=PaletteSkinFlag;
00611
00612
00613 return newFlags;
00614 }
00615
00616
00617
00618 void CVertexBuffer::serialOldV1Minus(NLMISC::IStream &f, sint ver)
00619 {
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 uint32 oldFlags;
00634
00635
00636
00637 f.serial(oldFlags);
00638
00639
00640 uint weightCount;
00641 uint16 newFlags=remapV2Flags (oldFlags, weightCount);
00642
00643
00644 nlassert (f.isReading());
00645
00646
00647 uint i;
00648 for (i=0; i<NumValue; i++)
00649 _Type[i]=DefaultValueType[i];
00650
00651 uint32 nbVert;
00652 f.serial(nbVert);
00653 reserve(0);
00654 setVertexFormat(newFlags);
00655 setNumVertices(nbVert);
00656
00657
00658
00659 switch (weightCount)
00660 {
00661 case 1:
00662 _Type[Weight]=Float1;
00663 break;
00664 case 2:
00665 _Type[Weight]=Float2;
00666 break;
00667 case 3:
00668 _Type[Weight]=Float3;
00669 break;
00670 case 4:
00671 _Type[Weight]=Float4;
00672 break;
00673 }
00674
00675
00676
00677 for(sint id=0;id<(sint)_NbVerts;id++)
00678 {
00679 uint8 *pointer = &(*_NonResidentVertices.begin());
00680 uint stridedId = id * _VertexSize;
00681
00682 if(_Flags & PositionFlag)
00683 {
00684 CVector &vert= *(CVector*)(pointer + stridedId + _Offset[Position]);
00685 f.serial(vert);
00686 }
00687
00688 if(_Flags & NormalFlag)
00689 {
00690 CVector &norm= *(CVector*)(pointer + stridedId + _Offset[Normal]);
00691 f.serial(norm);
00692 }
00693
00694 for(i=0;i<MaxStage;i++)
00695 {
00696 if(_Flags & (TexCoord0Flag<<i))
00697 {
00698 CUV &uv= *(CUV*)(pointer + stridedId + _Offset[TexCoord0+i]);
00699 f.serial(uv);
00700 }
00701 }
00702
00703 if(_Flags & PrimaryColorFlag)
00704 {
00705 CRGBA &col= *(CRGBA*)(pointer + stridedId + _Offset[PrimaryColor]);
00706 f.serial(col);
00707 }
00708
00709 if(_Flags & SecondaryColorFlag)
00710 {
00711 CRGBA &col= *(CRGBA*)(pointer + stridedId + _Offset[SecondaryColor]);
00712 f.serial(col);
00713 }
00714
00715 for(i=0;i<weightCount;i++)
00716 {
00717
00718 float &w= *(float*)(pointer + stridedId + _Offset[Weight] + i*sizeof(float));
00719 f.serial(w);
00720 }
00721
00722 if((ver>=1) && ((_Flags & PaletteSkinFlag) == CVertexBuffer::PaletteSkinFlag) )
00723 {
00724 CPaletteSkin &ps= *(CPaletteSkin*)(pointer + stridedId + _Offset[PaletteSkin]);
00725 f.serial(ps);
00726 }
00727
00728 }
00729
00730
00731 _InternalFlags = 0;
00732 if(f.isReading())
00733 {
00734
00735 restaureNonResidentMemory();
00736 }
00737 }
00738
00739
00740
00741 void CVertexBuffer::serial(NLMISC::IStream &f)
00742 {
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 nlassert (!isLocked());
00757 sint ver= f.serialVersion(2);
00758
00759 if (ver<2)
00760 {
00761
00762 serialOldV1Minus(f, ver);
00763 }
00764 else
00765 {
00766
00767 serialHeader(f);
00768
00769
00770 serialSubset(f, 0, _NbVerts);
00771 }
00772 }
00773
00774
00775
00776 void CVertexBuffer::serialHeader(NLMISC::IStream &f)
00777 {
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 sint ver= f.serialVersion(3);
00794
00795
00796
00797
00798
00799 uint16 flags=_Flags;
00800
00801 if (ver<1)
00802 {
00803
00804 nlassert (f.isReading());
00805
00806
00807 uint32 oldFlags;
00808 f.serial(oldFlags);
00809
00810
00811 uint weightCount;
00812 flags=remapV2Flags (oldFlags, weightCount);
00813
00814
00815 for (uint i=0; i<NumValue; i++)
00816 _Type[i]=DefaultValueType[i];
00817
00818
00819 switch (weightCount)
00820 {
00821 case 1:
00822 _Type[Weight]=Float1;
00823 break;
00824 case 2:
00825 _Type[Weight]=Float2;
00826 break;
00827 case 3:
00828 _Type[Weight]=Float3;
00829 break;
00830 case 4:
00831 _Type[Weight]=Float4;
00832 break;
00833 }
00834 }
00835 else
00836 {
00837
00838 f.serial(flags);
00839
00840
00841 for (uint i=0; i<NumValue; i++)
00842 {
00843 if (!(flags & (1 << i)))
00844 {
00845 _Type[i] = DefaultValueType[i];
00846 }
00847 f.serial (_Type[i]);
00848 }
00849 }
00850
00851
00852 uint32 nbVerts=_NbVerts;
00853 f.serial(nbVerts);
00854
00855 if(f.isReading())
00856 {
00857 reserve(0);
00858
00859
00860 clearValueEx ();
00861
00862
00863 for (uint i=0; i<NumValue; i++)
00864 {
00865
00866 if (flags&(1<<i))
00867 {
00868
00869 addValueEx ((TValue)i, (TType)_Type[i]);
00870 }
00871 }
00872
00873
00874 initEx ();
00875
00876
00877 setNumVertices(nbVerts);
00878 }
00879
00880
00881 if (ver>=2)
00882 f.serial (_VertexColorFormat);
00883
00884 if (ver>=3)
00885 {
00886 f.serialEnum(_PreferredMemory);
00887 f.serial(_Name);
00888 }
00889 else
00890 {
00891
00892 if(f.isReading())
00893 {
00894 _PreferredMemory = RAMPreferred;
00895 _Name = "";
00896 }
00897 }
00898 }
00899
00900
00901
00902 uint CVertexBuffer:: getNumTexCoordUsed() const
00903 {
00904 for (sint k = (MaxStage - 1); k >= 0; --k)
00905 {
00906 if (_Flags & (TexCoord0Flag << k)) return (uint) (k + 1);
00907 }
00908 return 0;
00909 }
00910
00911
00912
00913 uint8 CVertexBuffer::getNumWeight () const
00914 {
00915
00916 switch (_Type[Weight])
00917 {
00918 case Float1:
00919 return 1;
00920 case Float2:
00921 return 2;
00922 case Float3:
00923 return 3;
00924 case Float4:
00925 return 4;
00926 }
00927
00928
00929 return 0;
00930 }
00931
00932
00933
00934 void CVertexBuffer::serialSubset(NLMISC::IStream &f, uint vertexStart, uint vertexEnd)
00935 {
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 sint ver = f.serialVersion(2);
00950
00951
00952
00953
00954 nlassert(vertexStart<_NbVerts || _NbVerts==0);
00955 nlassert(vertexEnd<=_NbVerts);
00956 for(uint id=vertexStart; id<vertexEnd; id++)
00957 {
00958
00959 for (uint value=0; value<NumValue; value++)
00960 {
00961
00962 if (_Flags&(1<<value))
00963 {
00964
00965 void *ptr=(void*)((&(*_NonResidentVertices.begin()))+id*_VertexSize+getValueOffEx ((TValue)value));
00966 f.serialBuffer ((uint8*)ptr, SizeType[_Type[value]]);
00967 }
00968 }
00969 }
00970
00971
00972
00973 if (ver>=2)
00974 {
00975 f.serialBuffer (_UVRouting, sizeof(uint8)*MaxStage);
00976 }
00977 else
00978 {
00979
00980 uint i;
00981 for (i=0; i<MaxStage; i++)
00982 _UVRouting[i] = i;
00983 }
00984
00985
00986 if(f.isReading())
00987 {
00988
00989 restaureNonResidentMemory();
00990 }
00991 }
00992
00993
00994
00995 bool CVertexBuffer::setVertexColorFormat (TVertexColorType format)
00996 {
00997
00998 if (isResident())
00999 return false;
01000
01001 nlassert (!isLocked());
01002
01003
01004 if ((TVertexColorType)_VertexColorFormat != format)
01005 {
01006
01007 if (_Flags & (PrimaryColorFlag|SecondaryColorFlag))
01008 {
01009 uint i;
01010 uint32 *ptr0 = (_Flags&PrimaryColorFlag)?(uint32*)&(_NonResidentVertices[_Offset[PrimaryColor]]):NULL;
01011 uint32 *ptr1 = (_Flags&SecondaryColorFlag)?(uint32*)&(_NonResidentVertices[_Offset[SecondaryColor]]):NULL;
01012 for (i=0; i<_NbVerts; i++)
01013 {
01014 if (ptr0)
01015 {
01016 const register uint32 value = *ptr0;
01017 #ifdef NL_LITTLE_ENDIAN
01018 *ptr0 = (value&0xff00ff00)|((value&0xff)<<16)|((value&0xff0000)>>16);
01019 #else // NL_LITTLE_ENDIAN
01020 *ptr0 = (value&0x00ff00ff)|((value&0xff00)<<16)|((value&0xff000000)>>16);
01021 #endif // NL_LITTLE_ENDIAN
01022 ptr0 = (uint32*)(((uint8*)ptr0)+_VertexSize);
01023 }
01024 if (ptr1)
01025 {
01026 const register uint32 value = *ptr1;
01027 #ifdef NL_LITTLE_ENDIAN
01028 *ptr1 = (value&0xff00ff00)|((value&0xff)<<16)|((value&0xff0000)>>16);
01029 #else // NL_LITTLE_ENDIAN
01030 *ptr1 = (value&0x00ff00ff)|((value&0xff00)<<16)|((value&0xff000000)>>16);
01031 #endif // NL_LITTLE_ENDIAN
01032 ptr1 = (uint32*)(((uint8*)ptr1)+_VertexSize);
01033 }
01034 }
01035 }
01036 _VertexColorFormat = (uint8)format;
01037
01038
01039 restaureNonResidentMemory();
01040 }
01041 return true;
01042 }
01043
01044
01045
01046 void CVertexBuffer::setPreferredMemory (TPreferredMemory preferredMemory, bool keepLocalMemory)
01047 {
01048 if ((_PreferredMemory != preferredMemory) || (_KeepLocalMemory != keepLocalMemory))
01049 {
01050 _PreferredMemory = preferredMemory;
01051 _KeepLocalMemory = keepLocalMemory;
01052
01053
01054 restaureNonResidentMemory();
01055 }
01056 }
01057
01058
01059 void CVertexBuffer::setLocation (TLocation newLocation)
01060 {
01061
01062 if (newLocation != NotResident)
01063 {
01064
01065 nlassert (DrvInfos);
01066
01067
01068 const uint size = ((_PreferredMemory==RAMVolatile)||(_PreferredMemory==AGPVolatile))?_NbVerts*_VertexSize:_Capacity*_VertexSize;
01069
01070
01071 if (_Location != NotResident)
01072 setLocation (NotResident);
01073
01074
01075 uint8 *dest = DrvInfos->lock (0, size, false);
01076 nlassert (size<=_NonResidentVertices.size());
01077 memcpy (dest, &(_NonResidentVertices[0]), size);
01078 DrvInfos->unlock(0, 0);
01079
01080
01081 if ((_PreferredMemory != StaticPreferred) && (_Location != RAMResident) && !_KeepLocalMemory)
01082 contReset(_NonResidentVertices);
01083
01084
01085 resetTouchFlags ();
01086
01087 _Location = newLocation;
01088 _ResidentSize = size;
01089 }
01090 else
01091 {
01092
01093 const uint size = _Capacity*_VertexSize;
01094
01095
01096 _NonResidentVertices.resize (size);
01097
01098
01099 if ((_Location == RAMResident) && (_PreferredMemory != RAMVolatile) && (_PreferredMemory != AGPVolatile) && !_KeepLocalMemory)
01100 {
01101
01102 nlassert (DrvInfos);
01103
01104
01105 const uint8 *src = DrvInfos->lock (0, _ResidentSize, true);
01106 if (!_NonResidentVertices.empty())
01107 memcpy (&(_NonResidentVertices[0]), src, std::min (size, (uint)_ResidentSize));
01108 DrvInfos->unlock(0, 0);
01109 }
01110
01111 _Location = NotResident;
01112 _ResidentSize = 0;
01113
01114
01115 _InternalFlags |= TouchedAll;
01116 }
01117 }
01118
01119
01120 void CVertexBuffer::restaureNonResidentMemory()
01121 {
01122 setLocation (NotResident);
01123
01124 if (DrvInfos)
01125 DrvInfos->VertexBufferPtr = NULL;
01126
01127
01128 DrvInfos.kill();
01129 }
01130
01131
01132
01133 void CVertexBuffer::fillBuffer ()
01134 {
01135 if (DrvInfos && _KeepLocalMemory)
01136 {
01137
01138 const uint size = _NbVerts*_VertexSize;
01139 nlassert (size<=_NonResidentVertices.size());
01140 uint8 *dest = DrvInfos->lock (0, size, false);
01141 NLMISC::CFastMem::memcpy (dest, &(_NonResidentVertices[0]), size);
01142 DrvInfos->unlock(0, size);
01143 }
01144 }
01145
01146
01147
01148
01149 void CPaletteSkin::serial(NLMISC::IStream &f)
01150 {
01151 f.serial(MatrixId[0], MatrixId[1], MatrixId[2], MatrixId[3]);
01152 }
01153
01154
01155
01156 IVBDrvInfos::~IVBDrvInfos()
01157 {
01158 _Driver->removeVBDrvInfoPtr(_DriverIterator);
01159 }
01160
01161
01162
01163
01164
01165 NLMISC::CVector* CVertexBufferReadWrite::getVertexCoordPointer(uint idx)
01166 {
01167 nlassert (_Parent->checkLockedBuffer());
01168 uint8* ptr;
01169
01170 ptr=_Parent->_LockedBuffer;
01171 ptr+=(idx*_Parent->_VertexSize);
01172 return((NLMISC::CVector*)ptr);
01173 }
01174
01175
01176
01177 NLMISC::CVector* CVertexBufferReadWrite::getNormalCoordPointer(uint idx)
01178 {
01179 nlassert (_Parent->checkLockedBuffer());
01180 uint8* ptr;
01181
01182 if ( !(_Parent->_Flags & CVertexBuffer::NormalFlag) )
01183 {
01184 return(NULL);
01185 }
01186 ptr=_Parent->_LockedBuffer;
01187 ptr+=_Parent->_Offset[CVertexBuffer::Normal];
01188 ptr+=idx*_Parent->_VertexSize;
01189 return((NLMISC::CVector*)ptr);
01190 }
01191
01192
01193
01194 void* CVertexBufferReadWrite::getColorPointer(uint idx)
01195 {
01196 nlassert (_Parent->checkLockedBuffer());
01197 uint8* ptr;
01198
01199 if ( !(_Parent->_Flags & CVertexBuffer::PrimaryColorFlag) )
01200 {
01201 return(NULL);
01202 }
01203 ptr=_Parent->_LockedBuffer;
01204 ptr+=_Parent->_Offset[CVertexBuffer::PrimaryColor];
01205 ptr+=idx*_Parent->_VertexSize;
01206 return((void*)ptr);
01207 }
01208
01209
01210
01211 void* CVertexBufferReadWrite::getSpecularPointer(uint idx)
01212 {
01213 nlassert (_Parent->checkLockedBuffer());
01214 uint8* ptr;
01215
01216 if ( !(_Parent->_Flags & CVertexBuffer::SecondaryColorFlag) )
01217 {
01218 return(NULL);
01219 }
01220 ptr=_Parent->_LockedBuffer;
01221 ptr+=_Parent->_Offset[CVertexBuffer::SecondaryColor];
01222 ptr+=idx*_Parent->_VertexSize;
01223 return((void*)ptr);
01224 }
01225
01226
01227
01228 NLMISC::CUV* CVertexBufferReadWrite::getTexCoordPointer(uint idx, uint8 stage)
01229 {
01230 nlassert (_Parent->checkLockedBuffer());
01231 uint8* ptr;
01232
01233 if ( !(_Parent->_Flags & (CVertexBuffer::TexCoord0Flag<<stage)) )
01234 {
01235 return(NULL);
01236 }
01237 ptr=_Parent->_LockedBuffer;
01238 ptr+=_Parent->_Offset[CVertexBuffer::TexCoord0+stage];
01239 ptr+=idx*_Parent->_VertexSize;
01240 return((NLMISC::CUV*)ptr);
01241 }
01242
01243
01244
01245 float* CVertexBufferReadWrite::getWeightPointer(uint idx, uint8 wgt)
01246 {
01247 nlassert (_Parent->checkLockedBuffer());
01248 uint8* ptr;
01249
01250 nlassert(wgt<CVertexBuffer::MaxWeight);
01251 if( !(_Parent->_Flags & CVertexBuffer::WeightFlag))
01252 return NULL;
01253
01254 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
01255 ptr+=_Parent->_Offset[CVertexBuffer::Weight]+wgt*sizeof(float);
01256
01257 return (float*)ptr;
01258 }
01259
01260
01261
01262 CPaletteSkin* CVertexBufferReadWrite::getPaletteSkinPointer(uint idx)
01263 {
01264 nlassert (_Parent->checkLockedBuffer());
01265 uint8* ptr;
01266
01267 if ( (_Parent->_Flags & CVertexBuffer::PaletteSkinFlag) != CVertexBuffer::PaletteSkinFlag )
01268 {
01269 return(NULL);
01270 }
01271 ptr=_Parent->_LockedBuffer;
01272 ptr+=_Parent->_Offset[CVertexBuffer::PaletteSkin];
01273 ptr+=idx*_Parent->_VertexSize;
01274 return((CPaletteSkin*)ptr);
01275 }
01276
01277
01278
01279 void CVertexBufferReadWrite::touchVertices (uint first, uint last)
01280 {
01281 nlassert (_Parent->checkLockedBuffer());
01282 _First = first;
01283 _Last = last;
01284 }
01285
01286
01287
01288
01289
01290 const NLMISC::CVector* CVertexBufferRead::getVertexCoordPointer(uint idx) const
01291 {
01292 nlassert (_Parent->checkLockedBuffer());
01293 const uint8* ptr;
01294
01295 ptr=_Parent->_LockedBuffer;
01296 ptr+=(idx*_Parent->_VertexSize);
01297 return((const NLMISC::CVector*)ptr);
01298 }
01299
01300
01301
01302 const NLMISC::CVector* CVertexBufferRead::getNormalCoordPointer(uint idx) const
01303 {
01304 nlassert (_Parent->checkLockedBuffer());
01305 const uint8* ptr;
01306
01307 if ( !(_Parent->_Flags & CVertexBuffer::NormalFlag) )
01308 {
01309 return(NULL);
01310 }
01311 ptr=_Parent->_LockedBuffer;
01312 ptr+=_Parent->_Offset[CVertexBuffer::Normal];
01313 ptr+=idx*_Parent->_VertexSize;
01314 return((const NLMISC::CVector*)ptr);
01315 }
01316
01317
01318
01319 const void* CVertexBufferRead::getColorPointer(uint idx) const
01320 {
01321 nlassert (_Parent->checkLockedBuffer());
01322 const uint8* ptr;
01323
01324 if ( !(_Parent->_Flags & CVertexBuffer::PrimaryColorFlag) )
01325 {
01326 return(NULL);
01327 }
01328 ptr=_Parent->_LockedBuffer;
01329 ptr+=_Parent->_Offset[CVertexBuffer::PrimaryColor];
01330 ptr+=idx*_Parent->_VertexSize;
01331 return((const void*)ptr);
01332 }
01333
01334
01335
01336 const void* CVertexBufferRead::getSpecularPointer(uint idx) const
01337 {
01338 nlassert (_Parent->checkLockedBuffer());
01339 const uint8* ptr;
01340
01341 if ( !(_Parent->_Flags & CVertexBuffer::SecondaryColorFlag) )
01342 {
01343 return(NULL);
01344 }
01345 ptr=_Parent->_LockedBuffer;
01346 ptr+=_Parent->_Offset[CVertexBuffer::SecondaryColor];
01347 ptr+=idx*_Parent->_VertexSize;
01348 return((const void*)ptr);
01349 }
01350
01351
01352
01353 const NLMISC::CUV* CVertexBufferRead::getTexCoordPointer(uint idx, uint8 stage) const
01354 {
01355 nlassert (_Parent->checkLockedBuffer());
01356 const uint8* ptr;
01357
01358 if ( !(_Parent->_Flags & (CVertexBuffer::TexCoord0Flag<<stage)) )
01359 {
01360 return(NULL);
01361 }
01362 ptr=_Parent->_LockedBuffer;
01363 ptr+=_Parent->_Offset[CVertexBuffer::TexCoord0+stage];
01364 ptr+=idx*_Parent->_VertexSize;
01365 return((const NLMISC::CUV*)ptr);
01366 }
01367
01368
01369
01370 const float* CVertexBufferRead::getWeightPointer(uint idx, uint8 wgt) const
01371 {
01372 nlassert (_Parent->checkLockedBuffer());
01373 const uint8* ptr;
01374
01375 nlassert(wgt<CVertexBuffer::MaxWeight);
01376 if( !(_Parent->_Flags & CVertexBuffer::WeightFlag))
01377 return NULL;
01378
01379 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
01380 ptr+=_Parent->_Offset[CVertexBuffer::Weight]+wgt*sizeof(float);
01381
01382 return (float*)ptr;
01383 }
01384
01385
01386
01387 const CPaletteSkin* CVertexBufferRead::getPaletteSkinPointer(uint idx) const
01388 {
01389 nlassert (_Parent->checkLockedBuffer());
01390 const uint8* ptr;
01391
01392 if ( (_Parent->_Flags & CVertexBuffer::PaletteSkinFlag) != CVertexBuffer::PaletteSkinFlag )
01393 {
01394 return(NULL);
01395 }
01396 ptr=_Parent->_LockedBuffer;
01397 ptr+=_Parent->_Offset[CVertexBuffer::PaletteSkin];
01398 ptr+=idx*_Parent->_VertexSize;
01399 return((const CPaletteSkin*)ptr);
01400 }
01401
01402
01403
01404 }
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425