00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef NL_VERTEX_BUFFER_H
00025 #define NL_VERTEX_BUFFER_H
00026
00027 #include "nel/misc/types_nl.h"
00028 #include "nel/misc/smart_ptr.h"
00029 #include "nel/misc/rgba.h"
00030 #include "nel/misc/vector.h"
00031 #include "nel/misc/vectord.h"
00032 #include "nel/misc/debug.h"
00033 #include "nel/misc/uv.h"
00034 #include <vector>
00035 #include <list>
00036
00037 namespace NLMISC
00038 {
00039 class CUV;
00040 }
00041
00042
00043 namespace NL3D
00044 {
00045
00046 using NLMISC::CRefCount;
00047 using NLMISC::CRefPtr;
00048 using NLMISC::CRGBA;
00049 using NLMISC::CBGRA;
00050 using NLMISC::CVector;
00051 using NLMISC::CVectorD;
00052 using NLMISC::CUV;
00053
00054
00055 class IDriver;
00056 class CVertexBufferReadWrite;
00057 class CVertexBufferRead;
00058
00059
00060
00061
00062
00063
00064 class IVBDrvInfos;
00065 class CVertexBuffer;
00066 typedef std::list<IVBDrvInfos*> TVBDrvInfoPtrList;
00067 typedef TVBDrvInfoPtrList::iterator ItVBDrvInfoPtrList;
00068
00069
00073 struct CPaletteSkin
00074 {
00075 uint8 MatrixId[4];
00076
00077 void serial(NLMISC::IStream &f);
00078 };
00079
00080
00081
00093
00094
00095
00096
00097
00098 class CVertexBuffer : public CRefCount
00099 {
00100 public:
00101 friend class CVertexBufferReadWrite;
00102 friend class CVertexBufferRead;
00103
00107 enum TPreferredMemory
00108 {
00109 RAMPreferred = 0,
00110 AGPPreferred,
00111 StaticPreferred,
00112 RAMVolatile,
00113 AGPVolatile,
00114 PreferredCount,
00115 };
00116
00120 enum TLocation
00121 {
00122 RAMResident = 0,
00123 AGPResident,
00124 VRAMResident,
00125 NotResident,
00126 LocationCount,
00127 };
00128
00132 enum TValue
00133 {
00134 Position =0,
00135 Normal =1,
00136 TexCoord0 =2,
00137 TexCoord1 =3,
00138 TexCoord2 =4,
00139 TexCoord3 =5,
00140 TexCoord4 =6,
00141 TexCoord5 =7,
00142 TexCoord6 =8,
00143 TexCoord7 =9,
00144 PrimaryColor =10,
00145 SecondaryColor =11,
00146 Weight =12,
00147 PaletteSkin =13,
00148 Fog =14,
00149 Empty =15,
00150 NumValue =16
00151 };
00152
00156 enum
00157 {
00158 FirstTexCoordValue = TexCoord0,
00159 LastTexCoordValue = TexCoord7,
00160 };
00161
00165 enum
00166 {
00167 PositionFlag = 1<<Position,
00168 NormalFlag = 1<<Normal,
00169 TexCoord0Flag = 1<<TexCoord0,
00170 TexCoord1Flag = 1<<TexCoord1,
00171 TexCoord2Flag = 1<<TexCoord2,
00172 TexCoord3Flag = 1<<TexCoord3,
00173 TexCoord4Flag = 1<<TexCoord4,
00174 TexCoord5Flag = 1<<TexCoord5,
00175 TexCoord6Flag = 1<<TexCoord6,
00176 TexCoord7Flag = 1<<TexCoord7,
00177 PrimaryColorFlag = 1<<PrimaryColor,
00178 SecondaryColorFlag = 1<<SecondaryColor,
00179 WeightFlag = 1<<Weight,
00180 PaletteSkinFlag = (1<<PaletteSkin)|(1<<Weight),
00181 FogFlag = 1<<Fog,
00182 EmptyFlag = 1<<Empty,
00183 };
00184
00185
00186
00190 enum TType
00191 {
00192 Double1=0,
00193 Float1,
00194 Short1,
00195 Double2,
00196 Float2,
00197 Short2,
00198 Double3,
00199 Float3,
00200 Short3,
00201 Double4,
00202 Float4,
00203 Short4,
00204 UChar4,
00205 NumType
00206 };
00207
00211 enum
00212 {
00213
00214 MaxStage = 8,
00215
00216
00217 MaxWeight = 4,
00218 };
00219
00223 enum TVertexColorType
00224 {
00225 TRGBA = 0,
00226 TBGRA = 1
00227 };
00228
00232 static const uint SizeType[NumType];
00233
00237 static const TType DefaultValueType[NumValue];
00238
00242 static const uint NumComponentsType[NumType];
00243
00247 enum
00248 {
00250 TouchedVertexFormat = 1,
00251
00253 TouchedNumVertices = 2,
00254
00256 TouchedReserve = 4,
00257
00259 TouchedAll = 0xFFFF
00260 };
00261
00262 public:
00263
00264
00265
00266 CRefPtr<IVBDrvInfos> DrvInfos;
00267 uint getTouchFlags() const { return _InternalFlags&TouchedAll; }
00268
00276 void setLocation (TLocation newLocation);
00277
00279 void fillBuffer ();
00280
00281
00282 public:
00283
00284
00285
00286
00287
00288
00292 CVertexBuffer(void);
00293
00297 CVertexBuffer(const char *name);
00298
00303 CVertexBuffer(const CVertexBuffer &vb);
00304
00308 ~CVertexBuffer(void);
00309
00317 CVertexBuffer &operator=(const CVertexBuffer &vb);
00318
00327 void copyVertices(CVertexBuffer &dest) const;
00365 void setPreferredMemory (TPreferredMemory preferredMemory, bool keepLocalMemory);
00366
00370 TPreferredMemory getPreferredMemory () const { return _PreferredMemory; }
00371
00375 bool getKeepLocalMemory () const { return _KeepLocalMemory; }
00376
00380 TLocation getLocation () const { return _Location; }
00381
00386 bool isResident () const { return (_Location != NotResident) && DrvInfos; }
00387
00392
00393
00408 bool setVertexFormat (uint32 Flags);
00409
00419 uint16 getVertexFormat (void) const { return(_Flags); };
00420
00421
00423 uint getNumTexCoordUsed() const;
00424
00425
00426
00427 sint getNormalOff() const {nlassert(_Flags & NormalFlag); return _Offset[Normal];}
00428 sint getTexCoordOff(uint8 stage=0) const {nlassert(_Flags & (TexCoord0Flag<<stage)); return _Offset[TexCoord0+stage]; }
00429
00431 sint getColorOff() const {nlassert(_Flags & PrimaryColorFlag); return _Offset[PrimaryColor];}
00433 sint getSpecularOff() const {nlassert(_Flags & SecondaryColorFlag); return _Offset[SecondaryColor];}
00434
00436 sint getWeightOff(sint wgt) const {nlassert(_Flags & WeightFlag); return _Offset[Weight]+(wgt*sizeof(float));}
00437 sint getPaletteSkinOff() const {nlassert(_Flags & PaletteSkin); return _Offset[PaletteSkin];}
00438
00439
00445
00446
00453 static TValue getValueIdByNumberEx (uint valueNumber);
00454
00464 void clearValueEx ();
00465
00477 void addValueEx (TValue valueId, TType type);
00478
00480 bool hasValueEx(TValue valueId) const;
00481
00490 void initEx ();
00491
00495 sint getValueOffEx (TValue valueId) const { nlassert(_Flags & (1<<valueId)); return _Offset[valueId]; };
00496
00497
00498
00504 void setNumVertices(uint32 n);
00505
00509 uint32 getNumVertices(void) const { return(_NbVerts); }
00510
00519 void deleteAllVertices();
00520
00529 void reserve(uint32 nVerts);
00530
00534 uint32 capacity() { return _Capacity; }
00535
00539 uint16 getVertexSize (void) const { return(_VertexSize); }
00540
00544 TType getValueType (uint value) const { nlassert (value<NumValue); return((TType)_Type[value]); }
00545
00549 const uint8 *getValueTypePointer () const { return _Type; }
00550
00554 uint8 getNumWeight () const;
00555
00562 void serial(NLMISC::IStream &f);
00563
00574 inline void lock (CVertexBufferReadWrite &accessor, uint first=0, uint last=0);
00575
00588 inline void lock (CVertexBufferRead &accessor, uint first=0, uint last=0) const;
00589
00590
00591 bool isLocked () const {return _LockCounter!=0;}
00592
00594
00596 void serialHeader(NLMISC::IStream &f);
00600 void serialSubset(NLMISC::IStream &f, uint vertexStart, uint vertexEnd);
00601
00602
00604 const uint8 *getUVRouting () const { return _UVRouting; }
00605 void setUVRouting (uint8 uvChannel, uint newUVRouting) { _UVRouting[uvChannel] = uint8(newUVRouting); }
00606
00617 bool setVertexColorFormat (TVertexColorType format);
00618
00622 TVertexColorType getVertexColorFormat () const
00623 {
00624 return (TVertexColorType)_VertexColorFormat;
00625 }
00626
00627
00628 void dumpFormat() const;
00629 void setName (const std::string &name) { _Name = name; };
00630 const std::string &getName () const { return _Name; };
00631
00632 private:
00633
00634 void construct();
00635
00636
00637 bool checkLockedBuffer () const { return _LockedBuffer || (!isResident() && _NonResidentVertices.empty()); }
00638
00644 inline void unlock (uint first, uint last);
00645
00651 inline void unlock () const;
00652
00654 void serialOldV1Minus(NLMISC::IStream &f, sint ver);
00655
00657 uint16 remapV2Flags (uint32 oldFlags, uint& weightCount);
00658
00659
00660 void resetTouchFlags() {_InternalFlags &= (uint16)(~TouchedAll);}
00661
00662
00663 void restaureNonResidentMemory();
00664
00665 private:
00666
00667
00668 uint8 _Type[NumValue];
00669 uint8 _VertexColorFormat;
00670
00671
00672 uint16 _VertexSize;
00673
00674
00675 uint16 _Flags;
00676
00677
00678 uint16 _InternalFlags;
00679
00680
00681 uint32 _NbVerts;
00682
00683
00684 uint32 _Capacity;
00685
00686
00687 std::vector<uint8> _NonResidentVertices;
00688
00689
00690 mutable uint8* _LockedBuffer;
00691
00692
00693 uint16 _Offset[NumValue];
00694
00695
00696 uint8 _UVRouting[MaxStage];
00697
00698
00699 mutable uint _LockCounter;
00700
00701
00702 TPreferredMemory _PreferredMemory;
00703
00704
00705 TLocation _Location;
00706
00707
00708 uint32 _ResidentSize;
00709
00710
00711 std::string _Name;
00712
00713
00714 bool _KeepLocalMemory;
00715 };
00716
00717
00718
00719
00720 class IVBDrvInfos : public CRefCount
00721 {
00722 protected:
00723 IDriver *_Driver;
00724 private:
00725 ItVBDrvInfoPtrList _DriverIterator;
00726
00727 public:
00728 CRefPtr<CVertexBuffer> VertexBufferPtr;
00729
00730 IVBDrvInfos(IDriver *drv, ItVBDrvInfoPtrList it, CVertexBuffer *vb) {_Driver= drv; _DriverIterator= it; VertexBufferPtr=vb;}
00731
00735 virtual uint8 *lock (uint begin, uint end, bool readOnly) =0;
00736
00739 virtual void unlock (uint begin, uint end) =0;
00740
00741
00742
00743 virtual ~IVBDrvInfos();
00744 };
00745
00749 class CVertexBufferReadWrite
00750 {
00751 public:
00752 friend class CVertexBuffer;
00753
00754 CVertexBufferReadWrite()
00755 {
00756 _Parent = NULL;
00757 }
00758 ~CVertexBufferReadWrite()
00759 {
00760 unlock();
00761 }
00762
00767 void unlock()
00768 {
00769 if (_Parent)
00770 {
00771 _Parent->unlock(_First, _Last);
00772 _Parent = NULL;
00773 }
00774 }
00775
00776
00777 inline void setVertexCoord(uint idx, float x, float y, float z);
00778 inline void setVertexCoord(uint idx, const CVector &v);
00779 inline void setNormalCoord(uint idx, const CVector &v);
00780 inline void setTexCoord(uint idx, uint8 stage, float u, float v);
00781 inline void setTexCoord(uint idx, uint8 stage, const CUV &uv);
00782 inline void setColor(uint idx, CRGBA rgba);
00783 inline void setSpecular(uint idx, CRGBA rgba);
00784 inline void setWeight(uint idx, uint8 wgt, float w);
00785 inline void setPaletteSkin(uint idx, CPaletteSkin ps);
00786 inline void setValueFloat1Ex (CVertexBuffer::TValue valueId, uint idx, float value);
00787 inline void setValueFloat2Ex (CVertexBuffer::TValue valueId, uint idx, float x, float y);
00788 inline void setValueFloat3Ex (CVertexBuffer::TValue valueId, uint idx, float x, float y, float z);
00789 inline void setValueFloat3Ex (CVertexBuffer::TValue valueId, uint idx, const CVector& vector);
00790 inline void setValueFloat4Ex (CVertexBuffer::TValue valueId, uint idx, float x, float y, float z, float w);
00791 inline void setValueUChar4Ex (CVertexBuffer::TValue valueId, uint idx, CRGBA rgba);
00792
00800 NLMISC::CVector* getVertexCoordPointer(uint idx=0);
00801 NLMISC::CVector* getNormalCoordPointer(uint idx=0);
00802 NLMISC::CUV* getTexCoordPointer(uint idx=0, uint8 stage=0);
00803 void* getColorPointer(uint idx=0);
00804 void* getSpecularPointer(uint idx=0);
00805 float* getWeightPointer(uint idx=0, uint8 wgt=0);
00806 CPaletteSkin* getPaletteSkinPointer(uint idx=0);
00807 void* getValueEx (CVertexBuffer::TValue valueId, uint idx=0) { nlassert (_Parent->checkLockedBuffer()); nlassert (_Parent->_Flags & (1<<valueId)); return (void*)(_Parent->_LockedBuffer+idx*_Parent->_VertexSize+_Parent->getValueOffEx (valueId)); }
00808
00813 void touchVertices (uint first, uint last);
00814
00815 const CVertexBuffer *getParent() const { return _Parent; }
00816
00817 private:
00818
00819
00820 void operator=(const CVertexBufferReadWrite& ) {}
00821 CVertexBufferReadWrite(const CVertexBufferReadWrite& ) {}
00822
00823 CVertexBuffer *_Parent;
00824 uint _First, _Last;
00825 };
00826
00830 class CVertexBufferRead
00831 {
00832 public:
00833 friend class CVertexBuffer;
00834
00835 CVertexBufferRead()
00836 {
00837 _Parent = NULL;
00838 }
00839 ~CVertexBufferRead()
00840 {
00841 unlock();
00842 }
00843
00848 void unlock()
00849 {
00850 if (_Parent)
00851 {
00852 _Parent->unlock();
00853 _Parent = NULL;
00854 }
00855 }
00856
00864 const NLMISC::CVector* getVertexCoordPointer(uint idx=0) const;
00865 const NLMISC::CVector* getNormalCoordPointer(uint idx=0) const;
00866 const NLMISC::CUV* getTexCoordPointer(uint idx=0, uint8 stage=0) const;
00867 const void* getColorPointer(uint idx=0) const;
00868 const void* getSpecularPointer(uint idx=0) const;
00869 const float* getWeightPointer(uint idx=0, uint8 wgt=0) const;
00870 const CPaletteSkin* getPaletteSkinPointer(uint idx=0) const;
00871 const void* getValueEx (CVertexBuffer::TValue valueId, uint idx=0) const { nlassert (_Parent->_Flags & (1<<valueId)); return (void*)(_Parent->_LockedBuffer+idx*_Parent->_VertexSize+_Parent->getValueOffEx (valueId)); }
00872
00873 const CVertexBuffer *getParent() const { return _Parent; }
00874
00875 private:
00876
00877
00878 void operator=(const CVertexBufferRead& ) {}
00879 CVertexBufferRead(const CVertexBufferRead& ) {}
00880
00881 const CVertexBuffer *_Parent;
00882 };
00883
00885
00887
00888
00889 inline void CVertexBufferReadWrite::setVertexCoord(uint idx, float x, float y, float z)
00890 {
00891 float* ptr;
00892
00893 nlassert (_Parent->checkLockedBuffer());
00894 nlassert (_Parent->_Flags & CVertexBuffer::PositionFlag);
00895 nlassert (_Parent->_Type[CVertexBuffer::Position]==CVertexBuffer::Float3);
00896
00897 ptr=(float*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
00898 *ptr=x;
00899 ptr++;
00900 *ptr=y;
00901 ptr++;
00902 *ptr=z;
00903 }
00904
00905
00906
00907 inline void CVertexBufferReadWrite::setVertexCoord(uint idx, const CVector &v)
00908 {
00909 uint8* ptr;
00910
00911 nlassert (_Parent->checkLockedBuffer());
00912 nlassert (_Parent->_Flags & CVertexBuffer::PositionFlag);
00913 nlassert (_Parent->_Type[CVertexBuffer::Position]==CVertexBuffer::Float3);
00914
00915 ptr=&_Parent->_LockedBuffer[idx*_Parent->_VertexSize];
00916 memcpy(ptr, &(v.x), 3*sizeof(float));
00917 }
00918
00919
00920
00921 inline void CVertexBufferReadWrite::setNormalCoord(uint idx, const CVector &v)
00922 {
00923 uint8* ptr;
00924
00925 nlassert (_Parent->checkLockedBuffer());
00926 nlassert (_Parent->_Flags & CVertexBuffer::NormalFlag);
00927 nlassert (_Parent->_Type[CVertexBuffer::Normal]==CVertexBuffer::Float3);
00928
00929 ptr=&_Parent->_LockedBuffer[idx*_Parent->_VertexSize];
00930 ptr+=_Parent->_Offset[CVertexBuffer::Normal];
00931 memcpy(ptr, &(v.x), 3*sizeof(float));
00932 }
00933
00934
00935
00936 inline void CVertexBufferReadWrite::setColor(uint idx, CRGBA rgba)
00937 {
00938 uint8* ptr;
00939
00940 nlassert (_Parent->checkLockedBuffer());
00941 nlassert(_Parent->_Flags & CVertexBuffer::PrimaryColorFlag);
00942 nlassert (_Parent->_Type[CVertexBuffer::PrimaryColor]==CVertexBuffer::UChar4);
00943
00944 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
00945 ptr+=_Parent->_Offset[CVertexBuffer::PrimaryColor];
00946 if (_Parent->getVertexColorFormat () == CVertexBuffer::TRGBA)
00947 *(CRGBA*)ptr = rgba;
00948 else
00949 *(CBGRA*)ptr = rgba;
00950 }
00951
00952
00953
00954 inline void CVertexBufferReadWrite::setSpecular(uint idx, CRGBA rgba)
00955 {
00956 uint8* ptr;
00957
00958 nlassert (_Parent->checkLockedBuffer());
00959 nlassert(_Parent->_Flags & CVertexBuffer::SecondaryColorFlag);
00960 nlassert (_Parent->_Type[CVertexBuffer::SecondaryColor]==CVertexBuffer::UChar4);
00961
00962 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
00963 ptr+=_Parent->_Offset[CVertexBuffer::SecondaryColor];
00964 if (_Parent->getVertexColorFormat () == CVertexBuffer::TRGBA)
00965 *(CRGBA*)ptr = rgba;
00966 else
00967 *(CBGRA*)ptr = rgba;
00968 }
00969
00970
00971
00972 inline void CVertexBufferReadWrite::setTexCoord(uint idx, uint8 stage, float u, float v)
00973 {
00974 uint8* ptr;
00975 float* ptrf;
00976
00977 nlassert (_Parent->checkLockedBuffer());
00978 nlassert(stage<CVertexBuffer::MaxStage);
00979 nlassert(_Parent->_Flags & (CVertexBuffer::TexCoord0Flag<<stage));
00980 nlassert (_Parent->_Type[CVertexBuffer::TexCoord0+stage]==CVertexBuffer::Float2);
00981
00982 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
00983 ptr+=_Parent->_Offset[CVertexBuffer::TexCoord0+stage];
00984 ptrf=(float*)ptr;
00985 *ptrf=u;
00986 ptrf++;
00987 *ptrf=v;
00988 }
00989
00990
00991
00992 inline void CVertexBufferReadWrite::setTexCoord(uint idx, uint8 stage, const CUV &uv)
00993 {
00994 uint8* ptr;
00995 CUV* ptruv;
00996
00997 nlassert (_Parent->checkLockedBuffer());
00998 nlassert(stage<CVertexBuffer::MaxStage);
00999 nlassert(_Parent->_Flags & (CVertexBuffer::TexCoord0Flag<<stage));
01000 nlassert (_Parent->_Type[CVertexBuffer::TexCoord0+stage]==CVertexBuffer::Float2);
01001
01002 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
01003 ptr+=_Parent->_Offset[CVertexBuffer::TexCoord0+stage];
01004 ptruv=(CUV*)ptr;
01005 *ptruv=uv;
01006 }
01007
01008
01009
01010
01011 inline void CVertexBufferReadWrite::setWeight(uint idx, uint8 wgt, float w)
01012 {
01013 uint8* ptr;
01014 float* ptrf;
01015
01016 nlassert (_Parent->checkLockedBuffer());
01017 nlassert(wgt<CVertexBuffer::MaxWeight);
01018 nlassert(_Parent->_Flags & (CVertexBuffer::WeightFlag));
01019
01020 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
01021 ptr+=_Parent->_Offset[CVertexBuffer::Weight]+sizeof(float)*wgt;
01022 ptrf=(float*)ptr;
01023 *ptrf=w;
01024 }
01025
01026
01027
01028 inline void CVertexBufferReadWrite::setPaletteSkin(uint idx, CPaletteSkin ps)
01029 {
01030 uint8* ptr;
01031 CPaletteSkin *pPalSkin;
01032
01033 nlassert (_Parent->checkLockedBuffer());
01034 nlassert ( (_Parent->_Flags & CVertexBuffer::PaletteSkinFlag) == CVertexBuffer::PaletteSkinFlag);
01035 nlassert (_Parent->_Type[CVertexBuffer::PaletteSkin]==CVertexBuffer::UChar4);
01036
01037 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
01038 ptr+=_Parent->_Offset[CVertexBuffer::PaletteSkin];
01039 pPalSkin= (CPaletteSkin*)ptr;
01040 *pPalSkin= ps;
01041 }
01042
01043
01044
01045 inline void CVertexBufferReadWrite::setValueFloat1Ex (CVertexBuffer::TValue valueId, uint idx, float value)
01046 {
01047 uint8* ptr;
01048 float* ptrf;
01049
01050 nlassert (_Parent->checkLockedBuffer());
01051 nlassert(valueId<CVertexBuffer::NumValue);
01052 nlassert(_Parent->_Flags & (1<<(uint)valueId));
01053 nlassert((_Parent->_Type[valueId]==CVertexBuffer::Float4)||(_Parent->_Type[valueId]==CVertexBuffer::Float3)||(_Parent->_Type[valueId]==CVertexBuffer::Float2)||(_Parent->_Type[valueId]==CVertexBuffer::Float1));
01054
01055 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
01056 ptr+=_Parent->_Offset[valueId];
01057 ptrf=(float*)ptr;
01058 *ptrf=value;
01059 }
01060
01061
01062
01063 inline void CVertexBufferReadWrite::setValueFloat2Ex (CVertexBuffer::TValue valueId, uint idx, float x, float y)
01064 {
01065 uint8* ptr;
01066 float* ptrf;
01067
01068 nlassert (_Parent->checkLockedBuffer());
01069 nlassert(valueId<CVertexBuffer::NumValue);
01070 nlassert(_Parent->_Flags & (1<<(uint)valueId));
01071 nlassert((_Parent->_Type[valueId]==CVertexBuffer::Float4)||(_Parent->_Type[valueId]==CVertexBuffer::Float3)||(_Parent->_Type[valueId]==CVertexBuffer::Float2));
01072
01073 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
01074 ptr+=_Parent->_Offset[valueId];
01075 ptrf=(float*)ptr;
01076 ptrf[0]=x;
01077 ptrf[1]=y;
01078 }
01079
01080
01081
01082 inline void CVertexBufferReadWrite::setValueFloat3Ex (CVertexBuffer::TValue valueId, uint idx, float x, float y, float z)
01083 {
01084 uint8* ptr;
01085 float* ptrf;
01086
01087 nlassert (_Parent->checkLockedBuffer());
01088 nlassert(valueId<CVertexBuffer::NumValue);
01089 nlassert(_Parent->_Flags & (1<<(uint)valueId));
01090 nlassert((_Parent->_Type[valueId]==CVertexBuffer::Float4)||(_Parent->_Type[valueId]==CVertexBuffer::Float3));
01091
01092 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
01093 ptr+=_Parent->_Offset[valueId];
01094 ptrf=(float*)ptr;
01095 ptrf[0]=x;
01096 ptrf[1]=y;
01097 ptrf[2]=z;
01098 }
01099
01100
01101
01102 inline void CVertexBufferReadWrite::setValueFloat3Ex (CVertexBuffer::TValue valueId, uint idx, const NLMISC::CVector& theVector)
01103 {
01104 uint8* ptr;
01105 float* ptrf;
01106
01107 nlassert (_Parent->checkLockedBuffer());
01108 nlassert(valueId<CVertexBuffer::NumValue);
01109 nlassert(_Parent->_Flags & (1<<(uint)valueId));
01110 nlassert((_Parent->_Type[valueId]==CVertexBuffer::Float4)||(_Parent->_Type[valueId]==CVertexBuffer::Float3));
01111
01112 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
01113 ptr+=_Parent->_Offset[valueId];
01114 ptrf=(float*)ptr;
01115 memcpy (ptrf, &theVector, sizeof(float)*3);
01116 }
01117
01118
01119
01120 inline void CVertexBufferReadWrite::setValueFloat4Ex (CVertexBuffer::TValue valueId, uint idx, float x, float y, float z, float w)
01121 {
01122 uint8* ptr;
01123 float* ptrf;
01124
01125 nlassert (_Parent->checkLockedBuffer());
01126 nlassert(valueId<CVertexBuffer::NumValue);
01127 nlassert(_Parent->_Flags & (1<<(uint)valueId));
01128 nlassert(_Parent->_Type[valueId]==CVertexBuffer::Float4);
01129
01130 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
01131 ptr+=_Parent->_Offset[valueId];
01132 ptrf=(float*)ptr;
01133 ptrf[0]=x;
01134 ptrf[1]=y;
01135 ptrf[2]=z;
01136 ptrf[3]=w;
01137 }
01138
01139
01140
01141 inline void CVertexBufferReadWrite::setValueUChar4Ex (CVertexBuffer::TValue valueId, uint idx, CRGBA rgba)
01142 {
01143 uint8* ptr;
01144 CRGBA* ptrr;
01145
01146 nlassert (_Parent->checkLockedBuffer());
01147 nlassert(valueId<CVertexBuffer::NumValue);
01148 nlassert(_Parent->_Flags & (1<<(uint)valueId));
01149 nlassert(_Parent->_Type[valueId]==CVertexBuffer::UChar4);
01150
01151 ptr=(uint8*)(&_Parent->_LockedBuffer[idx*_Parent->_VertexSize]);
01152 ptr+=_Parent->_Offset[valueId];
01153 ptrr=(CRGBA*)ptr;
01154 *ptrr=rgba;
01155 }
01156
01157
01158
01159 inline void CVertexBuffer::lock (CVertexBufferReadWrite &accessor, uint first, uint last)
01160 {
01161 accessor.unlock();
01162 accessor._Parent = this;
01163 accessor._First = 0;
01164 accessor._Last = 0;
01165
01166
01167 if (_LockCounter == 0)
01168 {
01169 nlassert (_LockedBuffer == NULL);
01170
01171
01172 if (isResident() && !_KeepLocalMemory)
01173 {
01174 if (last == 0)
01175 last = _NbVerts;
01176 _LockedBuffer = DrvInfos->lock (first*_VertexSize, last*_VertexSize, false);
01177 }
01178 else
01179 {
01180 if (_NonResidentVertices.empty())
01181 _LockedBuffer = NULL;
01182 else
01183 _LockedBuffer = &(_NonResidentVertices[0]);
01184 }
01185 }
01186 else
01187 nlassert ((first==0)&&(last==0));
01188
01189 _LockCounter++;
01190 }
01191
01192
01193
01194 inline void CVertexBuffer::lock (CVertexBufferRead &accessor, uint first, uint last) const
01195 {
01196 accessor.unlock();
01197 accessor._Parent = this;
01198
01199
01200 if (_LockCounter == 0)
01201 {
01202 nlassert (_LockedBuffer == NULL);
01203
01204
01205 if (isResident() && !_KeepLocalMemory)
01206 {
01207 if (last == 0)
01208 last = _NbVerts;
01209
01210 nlassertex (_Location==RAMResident, ("Try to read a write only vertex buffer"));
01211 _LockedBuffer = DrvInfos->lock (first*_VertexSize, last*_VertexSize, true);
01212 }
01213 else
01214 {
01215 if (_NonResidentVertices.empty())
01216 _LockedBuffer = NULL;
01217 else
01218 _LockedBuffer = const_cast<uint8*>(&(_NonResidentVertices[0]));
01219 }
01220 }
01221 else
01222 nlassert ((first==0)&&(last==0));
01223
01224 _LockCounter++;
01225 }
01226
01227
01228
01229 inline void CVertexBuffer::unlock (uint first, uint end)
01230 {
01231 nlassertex (_LockCounter!=0, ("Vertex buffer not locked"));
01232 nlassert (_LockedBuffer || (!isResident() && _NonResidentVertices.empty()));
01233
01234 if (_LockCounter)
01235 _LockCounter--;
01236
01237 if (_LockCounter == 0)
01238 {
01239 if (isResident() && !_KeepLocalMemory)
01240 DrvInfos->unlock (0, 0);
01241
01242 _LockedBuffer = NULL;
01243 }
01244 }
01245
01246
01247
01248 inline void CVertexBuffer::unlock () const
01249 {
01250 nlassertex (_LockCounter!=0, ("Vertex buffer not locked"));
01251 nlassert (_LockedBuffer || (!isResident() && _NonResidentVertices.empty()));
01252
01253 if (_LockCounter)
01254 _LockCounter--;
01255
01256 if (_LockCounter == 0)
01257 {
01258 if (isResident() && !_KeepLocalMemory)
01259 DrvInfos->unlock (0, 0);
01260
01261 _LockedBuffer = NULL;
01262 }
01263 }
01264
01265
01266
01267 }
01268
01269
01270 #endif // NL_VERTEX_BUFFER_H
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293