vertex_buffer.h

Go to the documentation of this file.
00001 
00005 /* Copyright, 2000 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
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 // List typedef.
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 /* *** IMPORTANT ********************
00094  * *** IF YOU MODIFY THE STRUCTURE OF THIS CLASS, PLEASE INCREMENT IDriver::InterfaceVersion TO INVALIDATE OLD DRIVER DLL
00095  * **********************************
00096  */
00097 // All these flags are similar to DX8
00098 class CVertexBuffer : public CRefCount
00099 {
00100 public:
00101     friend class CVertexBufferReadWrite;
00102     friend class CVertexBufferRead;
00103 
00107     enum TPreferredMemory
00108     {
00109         RAMPreferred = 0,   // A block of driver RAM memory is allocated for this buffer. The buffer is read/write.
00110         AGPPreferred,       // A block of driver AGP memory is allocated for this buffer. The buffer is writeonly.
00111         StaticPreferred,    // The buffer will not be modified. A block of driver AGP or VRAM memory is allocated for this buffer. The buffer is writeonly.
00112         RAMVolatile,        // A block of temporary driver RAM memory will be returned by lock(). The buffer must be entirely filled after each swapBuffers(). The buffer is writeonly.
00113         AGPVolatile,        // A block of temporary driver AGP memory will be returned by lock(). The buffer must be entirely filled after each swapBuffers(). The buffer is writeonly.
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,  // Deprecated
00193         Float1,
00194         Short1,     // Deprecated
00195         Double2,    // Deprecated
00196         Float2,
00197         Short2,     // Deprecated
00198         Double3,    // Deprecated
00199         Float3,
00200         Short3,     // Deprecated
00201         Double4,    // Deprecated
00202         Float4,
00203         Short4,     // Deprecated
00204         UChar4,
00205         NumType
00206     };
00207 
00211     enum
00212     {
00213         // Max count of texture coordinates
00214         MaxStage = 8,
00215 
00216         // Max count of skinning weight
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     // \name Private. For Driver only.
00265     // @{
00266     CRefPtr<IVBDrvInfos>    DrvInfos;
00267     uint                    getTouchFlags() const { return _InternalFlags&TouchedAll; }
00268 
00276     void                    setLocation (TLocation newLocation);    // The driver implementation must set the location after activeVertexBuffer.
00277 
00279     void                    fillBuffer ();
00280     // @}
00281 
00282 public:
00283 
00284     /* ***********************************************
00285      *  WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
00286      *  It can be loaded/called through CAsyncFileManager for instance
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         // It is an error (assert) to query a vertex offset of a vertex component not setuped in setVertexFormat().
00426         // NB: The Vertex offset is always 0.
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     // Return true if the vetx buffer is locked
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     // for debug : dump format of vertex buffer
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     // Check locked buffers
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     // Reset the touch flags
00660     void        resetTouchFlags() {_InternalFlags &= (uint16)(~TouchedAll);}
00661 
00662     // Force non resident memory
00663     void        restaureNonResidentMemory();
00664 
00665 private:
00666 
00667     // Type of data stored in each value
00668     uint8                   _Type[NumValue];    // Offset 0 : aligned
00669     uint8                   _VertexColorFormat; // Offset 13 : aligned
00670 
00671     // Size of the vertex (sum of the size of each value
00672     uint16                  _VertexSize;        // Offset 14 : aligned
00673 
00674     // Flags: bit #n is 1 if the value #n is used
00675     uint16                  _Flags;             // Offset 16 : aligned
00676 
00677     // Internal flags
00678     uint16                  _InternalFlags;     // Offset 18 : aligned
00679 
00680     // Vertex count in the buffer
00681     uint32                  _NbVerts;           // Offset 20 : aligned
00682 
00683     // Capacity of the buffer
00684     uint32                  _Capacity;
00685 
00686     // Vertex array
00687     std::vector<uint8>      _NonResidentVertices;
00688 
00689     // The locked vertex buffer
00690     mutable uint8*          _LockedBuffer;
00691 
00692     // Offset of each value
00693     uint16                  _Offset[NumValue];
00694 
00695     // The UV routing table
00696     uint8                   _UVRouting[MaxStage];
00697 
00698     // The vertex buffer is locked n times
00699     mutable uint            _LockCounter;
00700 
00701     // Prefered memory
00702     TPreferredMemory        _PreferredMemory;
00703 
00704     // Location of the buffer
00705     TLocation               _Location;
00706 
00707     // Resident buffer size
00708     uint32                  _ResidentSize;
00709 
00710     // Debug string
00711     std::string             _Name;
00712 
00713     // Keep in local memory
00714     bool                    _KeepLocalMemory;
00715 };
00716 
00717 // *** IMPORTANT ********************
00718 // *** IF YOU MODIFY THE STRUCTURE OF THIS CLASS, PLEASE INCREMENT IDriver::InterfaceVersion TO INVALIDATE OLD DRIVER DLL
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     /* The virtual dtor is important.
00742      * The driver implementation must call setLocation (NotResident) if VertexBufferPtr!=NULL.*/
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     /* Set a value into the vertex buffer. */
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     // No copy operators available
00820     void        operator=(const CVertexBufferReadWrite& /* other */) {}
00821     CVertexBufferReadWrite(const CVertexBufferReadWrite& /* other */) {}
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     // No copy operators available
00878     void        operator=(const CVertexBufferRead& /* other */) {}
00879     CVertexBufferRead(const CVertexBufferRead& /* other */) {}
00880 
00881     const CVertexBuffer     *_Parent;
00882 };
00883 
00885 // implementation of inline methods //
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     // Already locked ?
01167     if (_LockCounter == 0)
01168     {
01169         nlassert (_LockedBuffer == NULL);
01170 
01171         // No
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     // Already locked ?
01200     if (_LockCounter == 0)
01201     {
01202         nlassert (_LockedBuffer == NULL);
01203 
01204         // No
01205         if (isResident() && !_KeepLocalMemory)
01206         {
01207             if (last == 0)
01208                 last = _NbVerts;
01209             // Can read it ?
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 } // NL3D
01268 
01269 
01270 #endif // NL_VERTEX_BUFFER_H
01271 
01272 /* End of vertex_buffer.h */
01273 
01274 
01275 
01276 
01277 
01278 
01279 
01280 
01281 
01282 
01283 
01284 
01285 
01286 
01287 
01288 
01289 
01290 
01291 
01292 
01293 

Generated on Thu Jan 7 08:26:21 2010 for NeL by  doxygen 1.6.1