# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

vertex_buffer.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "std3d.h"
00027 
00028 #include "3d/vertex_buffer.h"
00029 #include "nel/misc/vector.h"
00030 #include "3d/driver.h"
00031 using namespace NLMISC;
00032 
00033 
00034 namespace NL3D
00035 {
00036 
00037 // --------------------------------------------------
00038 
00039 const uint CVertexBuffer::SizeType[NumType]=
00040 {
00041         1*sizeof(double),
00042         1*sizeof(float),
00043         1*sizeof(short),
00044         2*sizeof(double),
00045         2*sizeof(float),
00046         2*sizeof(short),
00047         3*sizeof(double),
00048         3*sizeof(float),
00049         3*sizeof(short),
00050         4*sizeof(double),
00051         4*sizeof(float),
00052         4*sizeof(short),
00053         4*sizeof(char),
00054 };
00055 
00056 // --------------------------------------------------
00057 
00058 const CVertexBuffer::TType CVertexBuffer::DefaultValueType[NumValue]=
00059 {
00060         Float3,         // Position
00061         Float3,         // Normal
00062         Float2,         // TexCoord0
00063         Float2,         // TexCoord1
00064         Float2,         // TexCoord2
00065         Float2,         // TexCoord3
00066         Float2,         // TexCoord4
00067         Float2,         // TexCoord5
00068         Float2,         // TexCoord6
00069         Float2,         // TexCoord7
00070         UChar4,         // Primary color
00071         UChar4,         // Secondary color
00072         Float4,         // 4 Weights
00073         UChar4,         // PaletteSkin
00074         Float1,         // Fog
00075         Float1,         // Empty
00076 };
00077 
00078 // --------------------------------------------------
00079 
00080 CVertexBuffer::CVertexBuffer()
00081 {
00082         _Flags = 0;
00083         _Capacity = 0;
00084         _NbVerts = 0;
00085         _InternalFlags = 0;
00086         _VertexSize = 0;
00087 }
00088 
00089 // --------------------------------------------------
00090 
00091 CVertexBuffer::CVertexBuffer(const CVertexBuffer &vb)
00092 {
00093         _Flags = 0;
00094         _Capacity = 0;
00095         _NbVerts = 0;
00096         _VertexSize = 0;
00097         operator=(vb);
00098 }
00099 
00100 // --------------------------------------------------
00101 
00102 CVertexBuffer::~CVertexBuffer()
00103 {
00104         // Must kill the drv mirror of this VB.
00105         DrvInfos.kill();
00106 }
00107 
00108 // --------------------------------------------------
00109 
00110 CVertexBuffer   &CVertexBuffer::operator=(const CVertexBuffer &vb)
00111 {
00112         // Single value
00113         _VertexSize = vb._VertexSize;
00114         _Flags = vb._Flags;
00115         _InternalFlags = vb._InternalFlags;
00116         _NbVerts = vb._NbVerts;
00117         _Capacity = vb._Capacity;
00118         _Verts = vb._Verts;
00119 
00120         // Arraies
00121         for (uint value=0; value<NumValue; value++)
00122         {
00123                 _Offset[value]= vb._Offset[value];
00124                 _Type[value]= vb._Type[value];
00125         }
00126 
00127         // Set touch flags
00128         _InternalFlags |= TouchedAll;
00129 
00130         return *this;
00131 }
00132 
00133 // --------------------------------------------------
00134 
00135 bool CVertexBuffer::setVertexFormat(uint32 flags)
00136 {
00137         uint    i;
00138 
00139         // Clear extended values 
00140         clearValueEx ();
00141 
00142         // Position ?
00143         if (flags & PositionFlag)
00144         {
00145                 // Add a standard position value
00146                 addValueEx (Position, Float3);
00147         }
00148 
00149         // Normal ?
00150         if (flags & NormalFlag)
00151         {
00152                 // Add a standard normal value
00153                 addValueEx (Normal, Float3);
00154         }
00155 
00156         // For each uv values
00157         for(i=0 ; i<MaxStage ; i++)
00158         {
00159                 // UV ?
00160                 if (flags & (TexCoord0Flag<<i))
00161                 {
00162                         // Add a standard uv value
00163                         addValueEx ((TValue)(TexCoord0+i), Float2);
00164                 }
00165         }
00166 
00167         // Fog ?
00168         if (flags & FogFlag)
00169         {
00170                 // Add a standard primary color value
00171                 addValueEx (Fog, Float1);
00172         }
00173 
00174         // Primary color ?
00175         if (flags & PrimaryColorFlag)
00176         {
00177                 // Add a standard primary color value
00178                 addValueEx (PrimaryColor, UChar4);
00179         }
00180 
00181         // Secondary color ?
00182         if (flags & SecondaryColorFlag)
00183         {
00184                 // Add a standard primary color value
00185                 addValueEx (SecondaryColor, UChar4);
00186         }
00187 
00188         // Weight ?
00189         if (flags & WeightFlag)
00190         {
00191                 // Add a standard primary color value
00192                 addValueEx (Weight, Float4);
00193         }
00194 
00195         // Palette skin ?
00196         if ((flags & PaletteSkinFlag)==CVertexBuffer::PaletteSkinFlag)
00197         {
00198                 // Add a standard primary color value
00199                 addValueEx (PaletteSkin, UChar4);
00200         }
00201 
00202         // Compute the vertex buffer
00203         initEx ();
00204 
00205         return (true);
00206 }
00207 
00208 // --------------------------------------------------
00209 
00210 CVertexBuffer::TValue CVertexBuffer::getValueIdByNumberEx (uint valueNumber)
00211 {
00212         // See NV_vertex_program spec, or driver_opengl_vertex.cpp:: GLVertexAttribIndex.
00213         static  TValue  lut[16]= {
00214                 Position,
00215                 Weight,
00216                 Normal,
00217                 PrimaryColor,
00218                 SecondaryColor,
00219                 Fog,
00220                 PaletteSkin,
00221                 Empty,
00222                 TexCoord0,
00223                 TexCoord1,
00224                 TexCoord2,
00225                 TexCoord3,
00226                 TexCoord4,
00227                 TexCoord5,
00228                 TexCoord6,
00229                 TexCoord7,
00230         };
00231 
00232         return lut[valueNumber];
00233 }
00234 
00235 // --------------------------------------------------
00236 
00237 void CVertexBuffer::clearValueEx ()
00238 {
00239         // Reset format flags
00240         _Flags=0;
00241 }
00242 
00243 // --------------------------------------------------
00244 
00245 void CVertexBuffer::addValueEx (TValue valueId, TType type)
00246 {
00247         // Reset format flags
00248         _Flags |= 1<<valueId;
00249 
00250         // Set the type
00251         _Type[valueId]=(uint8)type;
00252 }
00253 
00254 // --------------------------------------------------
00255 
00256 bool CVertexBuffer::hasValueEx(TValue valueId) const
00257 {
00258         return (_Flags & (1 << valueId)) != 0;
00259 }
00260 
00261 // --------------------------------------------------
00262 
00263 void CVertexBuffer::initEx ()
00264 {
00265         // Reset internal flag
00266         _InternalFlags=TouchedAll;
00267 
00268         // Calc vertex size and set value's offset
00269         _VertexSize=0;
00270         for (uint value=0; value<NumValue; value++)
00271         {
00272                 // Value used ?
00273                 if (_Flags&(1<<value))
00274                 {
00275                         // Set offset
00276                         _Offset[value]=_VertexSize;
00277 
00278                         // New size
00279                         _VertexSize+=SizeType[_Type[value]];
00280                 }
00281         }
00282 
00283         // Reset number of vertices
00284         _NbVerts=0;
00285 
00286         // Compute new capacity
00287         if (_VertexSize)
00288                 _Capacity = _Verts.size()/_VertexSize;
00289         else
00290                 _Capacity = 0;
00291 }
00292 
00293 // --------------------------------------------------
00294 
00295 void CVertexBuffer::reserve(uint32 n)
00296 {
00297         _Verts.resize(n*_VertexSize);
00298         _Capacity= n;
00299 }
00300 
00301 // --------------------------------------------------
00302 
00303 void CVertexBuffer::setNumVertices(uint32 n)
00304 {
00305         if(_Capacity<n)
00306         {
00307                 reserve(n);
00308         }
00309         if(_NbVerts != n)
00310         {
00311                 _InternalFlags |= TouchedNumVertices;
00312                 _NbVerts=n;
00313         }
00314 }
00315 
00316 // --------------------------------------------------
00317 
00318 void    CVertexBuffer::deleteAllVertices()
00319 {
00320         // free memory.
00321         contReset(_Verts);
00322         _Capacity= 0;
00323         if(_NbVerts!=0)
00324         {
00325                 _NbVerts=0;
00326                 _InternalFlags |= TouchedNumVertices;
00327         }
00328 }
00329 
00330 // --------------------------------------------------
00331 
00332 void* CVertexBuffer::getVertexCoordPointer(uint idx)
00333 {
00334         uint8*  ptr;
00335 
00336         ptr=&(*_Verts.begin());
00337         ptr+=(idx*_VertexSize);
00338         return((void*)ptr);
00339 }
00340 
00341 // --------------------------------------------------
00342 
00343 void* CVertexBuffer::getNormalCoordPointer(uint idx)
00344 {
00345         uint8*  ptr;
00346 
00347         if ( !(_Flags & NormalFlag) )
00348         {
00349                 return(NULL);
00350         }
00351         ptr=&(*_Verts.begin());
00352         ptr+=_Offset[Normal];
00353         ptr+=idx*_VertexSize;
00354         return((void*)ptr);
00355 }
00356 
00357 // --------------------------------------------------
00358 
00359 void* CVertexBuffer::getColorPointer(uint idx)
00360 {
00361         uint8*  ptr;
00362 
00363         if ( !(_Flags & PrimaryColorFlag) )
00364         {
00365                 return(NULL);
00366         }
00367         ptr=&(*_Verts.begin());
00368         ptr+=_Offset[PrimaryColor];
00369         ptr+=idx*_VertexSize;
00370         return((void*)ptr);
00371 }
00372 
00373 // --------------------------------------------------
00374 
00375 void* CVertexBuffer::getSpecularPointer(uint idx)
00376 {
00377         uint8*  ptr;
00378 
00379         if ( !(_Flags & SecondaryColorFlag) )
00380         {
00381                 return(NULL);
00382         }
00383         ptr=&(*_Verts.begin());
00384         ptr+=_Offset[SecondaryColor];
00385         ptr+=idx*_VertexSize;
00386         return((void*)ptr);
00387 }
00388 
00389 // --------------------------------------------------
00390 
00391 void* CVertexBuffer::getTexCoordPointer(uint idx, uint8 stage)
00392 {
00393         uint8*  ptr;
00394 
00395         if ( !(_Flags & (TexCoord0Flag<<stage)) )
00396         {
00397                 return(NULL);
00398         }
00399         ptr=&(*_Verts.begin());
00400         ptr+=_Offset[TexCoord0+stage];
00401         ptr+=idx*_VertexSize;
00402         return((void*)ptr);
00403 }
00404 
00405 // --------------------------------------------------
00406 
00407 void* CVertexBuffer::getWeightPointer(uint idx, uint8 wgt)
00408 {
00409         uint8*  ptr;
00410 
00411         nlassert(wgt<MaxWeight);
00412         if( !(_Flags & WeightFlag))
00413                 return NULL;
00414 
00415         ptr=(uint8*)(&_Verts[idx*_VertexSize]);
00416         ptr+=_Offset[Weight]+wgt*sizeof(float);
00417 
00418         return ptr;
00419 }
00420 
00421 // --------------------------------------------------
00422 
00423 void* CVertexBuffer::getPaletteSkinPointer(uint idx)
00424 {
00425         uint8*  ptr;
00426 
00427         if ( (_Flags & PaletteSkinFlag) != CVertexBuffer::PaletteSkinFlag )
00428         {
00429                 return(NULL);
00430         }
00431         ptr=&(*_Verts.begin());
00432         ptr+=_Offset[PaletteSkin];
00433         ptr+=idx*_VertexSize;
00434         return((void*)ptr);
00435 }
00436 
00437 // --------------------------------------------------
00438 
00439 
00441 // const versions //
00443 
00444 
00445 // --------------------------------------------------
00446 
00447 const void* CVertexBuffer::getVertexCoordPointer(uint idx) const 
00448 {
00449         const uint8*    ptr;
00450 
00451         ptr=&(*_Verts.begin());
00452         ptr+=(idx*_VertexSize);
00453         return((void*)ptr);
00454 }
00455 
00456 // --------------------------------------------------
00457 
00458 const void* CVertexBuffer::getNormalCoordPointer(uint idx) const
00459 {
00460         const uint8*    ptr;
00461 
00462         if ( !(_Flags & NormalFlag) )
00463         {
00464                 return(NULL);
00465         }
00466         ptr=&(*_Verts.begin());
00467         ptr+=_Offset[Normal];
00468         ptr+=idx*_VertexSize;
00469         return((void*)ptr);
00470 }
00471 
00472 // --------------------------------------------------
00473 
00474 const void* CVertexBuffer::getColorPointer(uint idx) const
00475 {
00476         const uint8*    ptr;
00477 
00478         if ( !(_Flags & PrimaryColorFlag) )
00479         {
00480                 return(NULL);
00481         }
00482         ptr=&(*_Verts.begin());
00483         ptr+=_Offset[PrimaryColor];
00484         ptr+=idx*_VertexSize;
00485         return((void*)ptr);
00486 }
00487 
00488 // --------------------------------------------------
00489 
00490 const void* CVertexBuffer::getSpecularPointer(uint idx) const
00491 {
00492         const uint8*    ptr;
00493 
00494         if ( !(_Flags & SecondaryColorFlag) )
00495         {
00496                 return(NULL);
00497         }
00498         ptr=&(*_Verts.begin());
00499         ptr+=_Offset[SecondaryColor];
00500         ptr+=idx*_VertexSize;
00501         return((void*)ptr);
00502 }
00503 
00504 // --------------------------------------------------
00505 
00506 const void* CVertexBuffer::getTexCoordPointer(uint idx, uint8 stage) const
00507 {
00508         const uint8*    ptr;
00509 
00510         if ( !(_Flags & (TexCoord0Flag<<stage)) )
00511         {
00512                 return(NULL);
00513         }
00514         ptr=&(*_Verts.begin());
00515         ptr+=_Offset[TexCoord0+stage];
00516         ptr+=idx*_VertexSize;
00517         return((void*)ptr);
00518 }
00519 
00520 // --------------------------------------------------
00521 
00522 const void* CVertexBuffer::getWeightPointer(uint idx, uint8 wgt) const
00523 {
00524         const uint8*    ptr;
00525 
00526         nlassert(wgt<MaxWeight);
00527         if( !(_Flags & WeightFlag))
00528                 return NULL;
00529 
00530         ptr=(uint8*)(&_Verts[idx*_VertexSize]);
00531         ptr+=_Offset[Weight]+wgt*sizeof(float);
00532 
00533         return ptr;
00534 }
00535 
00536 // --------------------------------------------------
00537 
00538 const void* CVertexBuffer::getPaletteSkinPointer(uint idx) const
00539 {
00540         const uint8*    ptr;
00541 
00542         if ( (_Flags & PaletteSkinFlag) != CVertexBuffer::PaletteSkinFlag )
00543         {
00544                 return(NULL);
00545         }
00546         ptr=&(*_Verts.begin());
00547         ptr+=_Offset[PaletteSkin];
00548         ptr+=idx*_VertexSize;
00549         return((void*)ptr);
00550 }
00551 
00552 // --------------------------------------------------
00553 
00554 uint16          CVertexBuffer::remapV2Flags (uint32 oldFlags, uint& weightCount)
00555 {
00556         // Old flags
00557         const uint32 OLD_IDRV_VF_XYZ = 0x00000001;
00558         const uint32 OLD_IDRV_VF_W0 = 0x00000002;
00559         const uint32 OLD_IDRV_VF_W1 = 0x00000004;
00560         const uint32 OLD_IDRV_VF_W2 = 0x00000008;
00561         const uint32 OLD_IDRV_VF_W3 = 0x00000010;
00562         const uint32 OLD_IDRV_VF_NORMAL = 0x00000020;
00563         const uint32 OLD_IDRV_VF_COLOR = 0x00000040;
00564         const uint32 OLD_IDRV_VF_SPECULAR = 0x00000080;
00565         const uint32 OLD_IDRV_VF_UV0 = 0x00000100;
00566         const uint32 OLD_IDRV_VF_UV1 = 0x00000200;
00567         const uint32 OLD_IDRV_VF_UV2 = 0x00000400;
00568         const uint32 OLD_IDRV_VF_UV3 = 0x00000800;
00569         const uint32 OLD_IDRV_VF_UV4 = 0x00001000;
00570         const uint32 OLD_IDRV_VF_UV5 = 0x00002000;
00571         const uint32 OLD_IDRV_VF_UV6 = 0x00004000;
00572         const uint32 OLD_IDRV_VF_UV7 = 0x00008000;
00573         const uint32 OLD_IDRV_VF_PALETTE_SKIN = 0x00010000 | OLD_IDRV_VF_W0 | OLD_IDRV_VF_W1 | OLD_IDRV_VF_W2 | OLD_IDRV_VF_W3;
00574 
00575         // Old Flags
00576         uint16 newFlags=0;
00577 
00578         // Number of weight values
00579         weightCount=0;
00580 
00581         // Remap the flags
00582         if (oldFlags&OLD_IDRV_VF_XYZ)
00583                 newFlags|=PositionFlag;
00584         if (oldFlags&OLD_IDRV_VF_NORMAL)
00585                 newFlags|=NormalFlag;
00586         if (oldFlags&OLD_IDRV_VF_COLOR)
00587                 newFlags|=PrimaryColorFlag;
00588         if (oldFlags&OLD_IDRV_VF_SPECULAR)
00589                 newFlags|=SecondaryColorFlag;
00590         if (oldFlags&OLD_IDRV_VF_UV0)
00591                 newFlags|=TexCoord0Flag;
00592         if (oldFlags&OLD_IDRV_VF_UV1)
00593                 newFlags|=TexCoord1Flag;
00594         if (oldFlags&OLD_IDRV_VF_UV2)
00595                 newFlags|=TexCoord2Flag;
00596         if (oldFlags&OLD_IDRV_VF_UV3)
00597                 newFlags|=TexCoord3Flag;
00598         if (oldFlags&OLD_IDRV_VF_UV4)
00599                 newFlags|=TexCoord4Flag;
00600         if (oldFlags&OLD_IDRV_VF_UV5)
00601                 newFlags|=TexCoord5Flag;
00602         if (oldFlags&OLD_IDRV_VF_UV6)
00603                 newFlags|=TexCoord6Flag;
00604         if (oldFlags&OLD_IDRV_VF_UV7)
00605                 newFlags|=TexCoord7Flag;
00606         if (oldFlags&OLD_IDRV_VF_W0)
00607         {
00608                 weightCount=1;
00609                 newFlags|=WeightFlag;
00610         }
00611         if (oldFlags&OLD_IDRV_VF_W1)
00612         {
00613                 weightCount=2;
00614                 newFlags|=WeightFlag;
00615         }
00616         if (oldFlags&OLD_IDRV_VF_W2)
00617         {
00618                 weightCount=3;
00619                 newFlags|=WeightFlag;
00620         }
00621         if (oldFlags&OLD_IDRV_VF_W3)
00622         {
00623                 weightCount=4;
00624                 newFlags|=WeightFlag;
00625         }
00626         if (oldFlags&(OLD_IDRV_VF_PALETTE_SKIN))
00627                 newFlags|=PaletteSkinFlag;
00628 
00629         // Return the new flags
00630         return newFlags;
00631 }
00632 
00633 // --------------------------------------------------
00634 
00635 void            CVertexBuffer::serialOldV1Minus(NLMISC::IStream &f, sint ver)
00636 {
00637         /*
00638         Version 1:
00639                 - PaletteSkin version.
00640         Version 0:
00641                 - base verison.
00642         */
00643 
00644         // old Flags
00645         uint32 oldFlags;
00646 
00647         // Serial VBuffers format/size.
00648         //=============================
00649         f.serial(oldFlags);
00650 
00651         // Remap the flags
00652         uint weightCount;
00653         uint16 newFlags=remapV2Flags (oldFlags, weightCount);
00654 
00655         // Must be reading
00656         nlassert (f.isReading());
00657 
00658         // Set default value type
00659         uint i;
00660         for (i=0; i<NumValue; i++)
00661                 _Type[i]=DefaultValueType[i];
00662 
00663         uint32 nbVert;  // Read only
00664         f.serial(nbVert);
00665         reserve(0);
00666         setVertexFormat(newFlags);
00667         setNumVertices(nbVert);
00668         // All other infos (but _Verts) are computed by setVertexFormat() and setNumVertices().
00669 
00670         // Weight count ?
00671         switch (weightCount)
00672         {
00673         case 1:
00674                 _Type[Weight]=Float1;
00675                 break;
00676         case 2:
00677                 _Type[Weight]=Float2;
00678                 break;
00679         case 3:
00680                 _Type[Weight]=Float3;
00681                 break;
00682         case 4:
00683                 _Type[Weight]=Float4;
00684                 break;
00685         }
00686 
00687         // Serial VBuffers components.
00688         //============================
00689         for(sint id=0;id<(sint)_NbVerts;id++)
00690         {
00691                 // XYZ.
00692                 if(_Flags & PositionFlag)
00693                 {
00694                         CVector         &vert= *(CVector*)getVertexCoordPointer(id);
00695                         f.serial(vert);
00696                 }
00697                 // Normal
00698                 if(_Flags & NormalFlag)
00699                 {
00700                         CVector         &norm= *(CVector*)getNormalCoordPointer(id);
00701                         f.serial(norm);
00702                 }
00703                 // Uvs.
00704                 for(i=0;i<MaxStage;i++)
00705                 {
00706                         if(_Flags & (TexCoord0Flag<<i))
00707                         {
00708                                 CUV             &uv= *(CUV*)getTexCoordPointer(id, i);
00709                                 f.serial(uv);
00710                         }
00711                 }
00712                 // Color.
00713                 if(_Flags & PrimaryColorFlag)
00714                 {
00715                         CRGBA           &col= *(CRGBA*)getColorPointer(id);
00716                         f.serial(col);
00717                 }
00718                 // Specular.
00719                 if(_Flags & SecondaryColorFlag)
00720                 {
00721                         CRGBA           &col= *(CRGBA*)getSpecularPointer(id);
00722                         f.serial(col);
00723                 }
00724                 // Weights
00725                 for(i=0;i<weightCount;i++)
00726                 {
00727                         // Weight channel available ?
00728                         float   &w= *(float*)getWeightPointer(id, i);
00729                         f.serial(w);
00730                 }
00731                 // CPaletteSkin (version 1+ only).
00732                 if((ver>=1) && ((_Flags & PaletteSkinFlag) == CVertexBuffer::PaletteSkinFlag) )
00733                 {
00734                         CPaletteSkin    &ps= *(CPaletteSkin*)getPaletteSkinPointer(id);
00735                         f.serial(ps);
00736                 }
00737 
00738         }
00739 
00740         // Set touch flags
00741         _InternalFlags = 0;
00742         if(f.isReading())
00743                 _InternalFlags |= TouchedAll;
00744 }
00745 
00746 // --------------------------------------------------
00747 
00748 void            CVertexBuffer::serial(NLMISC::IStream &f)
00749 {
00750         /*
00751         Version 2:
00752                 - cut to use serialHeader() serialSubset().
00753         Version 1:
00754                 - PaletteSkin version.
00755         Version 0:
00756                 - base verison.
00757         */
00758         sint    ver= f.serialVersion(2);
00759 
00760         if (ver<2)
00761         {
00762                 // old serial method
00763                 serialOldV1Minus(f, ver);
00764         }
00765         else
00766         {
00767                 // read write the header of the VBuffer.
00768                 serialHeader(f);
00769 
00770                 // read write the entire subset.
00771                 serialSubset(f, 0, _NbVerts);
00772         }
00773 }
00774 
00775 // --------------------------------------------------
00776 
00777 void            CVertexBuffer::serialHeader(NLMISC::IStream &f)
00778 {
00779         /*
00780         Version 1:
00781                 - Extended vertex format management.
00782         Version 0:
00783                 - base verison of the header serialisation.
00784         */
00785         sint    ver= f.serialVersion(1);
00786 
00787         // Serial VBuffers format/size.
00788         //=============================
00789 
00790         // Flags
00791         uint16 flags=_Flags;
00792 
00793         if (ver<1)
00794         {
00795                 // Must be reading
00796                 nlassert (f.isReading());
00797 
00798                 // Serial old flags
00799                 uint32 oldFlags;
00800                 f.serial(oldFlags);
00801 
00802                 // Remap flags
00803                 uint weightCount;
00804                 flags=remapV2Flags (oldFlags, weightCount);
00805 
00806                 // Set default value type
00807                 for (uint i=0; i<NumValue; i++)
00808                         _Type[i]=DefaultValueType[i];
00809 
00810                 // weight count ?
00811                 switch (weightCount)
00812                 {
00813                 case 1:
00814                         _Type[Weight]=Float1;
00815                         break;
00816                 case 2:
00817                         _Type[Weight]=Float2;
00818                         break;
00819                 case 3:
00820                         _Type[Weight]=Float3;
00821                         break;
00822                 case 4:
00823                         _Type[Weight]=Float4;
00824                         break;
00825                 }
00826         }
00827         else
00828         {
00829                 // Serial new vertex flags
00830                 f.serial(flags);
00831 
00832                 // Serial type of values
00833                 for (uint i=0; i<NumValue; i++)
00834                         f.serial (_Type[i]);
00835         }
00836 
00837         // Serial nb vertices
00838         uint32 nbVerts=_NbVerts;
00839         f.serial(nbVerts);
00840 
00841         if(f.isReading())
00842         {
00843                 reserve(0);
00844 
00845                 // Init vertex format setup
00846                 clearValueEx ();
00847 
00848                 // Init vertex format
00849                 for (uint i=0; i<NumValue; i++)
00850                 {
00851                         // Setup this value ?
00852                         if (flags&(1<<i))
00853                         {
00854                                 // Add a value
00855                                 addValueEx ((TValue)i, (TType)_Type[i]);
00856                         }
00857                 }
00858 
00859                 // Build final vertex format
00860                 initEx ();
00861 
00862                 // Set num of vertices
00863                 setNumVertices(nbVerts);
00864         }
00865         // All other infos (but _Verts) are computed by initEx() and setNumVertices().
00866 }
00867 
00868 
00869 // --------------------------------------------------
00870 uint    CVertexBuffer:: getNumTexCoordUsed() const
00871 {       
00872         for (sint k = (MaxStage - 1); k >= 0; --k)
00873         {
00874                 if (_Flags & (TexCoord0Flag << k))  return (uint) (k + 1);
00875         }
00876         return 0;
00877 }
00878 
00879 // --------------------------------------------------
00880 
00881 uint8           CVertexBuffer::getNumWeight () const
00882 {
00883         // Num weight
00884         switch (_Type[Weight])
00885         {
00886         case Float1:
00887                 return 1;
00888         case Float2:
00889                 return 2;
00890         case Float3:
00891                 return 3;
00892         case Float4:
00893                 return 4;
00894         }
00895 
00896         // No weight
00897         return 0;
00898 }
00899 
00900 // --------------------------------------------------
00901 
00902 void            CVertexBuffer::serialSubset(NLMISC::IStream &f, uint vertexStart, uint vertexEnd)
00903 {
00904         /*
00905         Version 1:
00906                 - weight is 4 float in standard format.
00907         Version 0:
00908                 - base verison of a vbuffer subset serialisation.
00909         */
00910         sint    ver= f.serialVersion(1);
00911 
00912 
00913         // Serial VBuffers components.
00914         //============================
00915         nlassert(vertexStart<_NbVerts || _NbVerts==0);
00916         nlassert(vertexEnd<=_NbVerts);
00917         for(uint id=vertexStart; id<vertexEnd; id++)
00918         {
00919                 // For each value
00920                 for (uint value=0; value<NumValue; value++)
00921                 {
00922                         // Value used ?
00923                         if (_Flags&(1<<value))
00924                         {
00925                                 // Get the pointer on it
00926                                 void *ptr=getValueEx ((TValue)value, id);
00927                                 f.serialBuffer ((uint8*)ptr, SizeType[_Type[value]]);
00928                         }
00929                 }
00930         }
00931 
00932         // Set touch flags
00933         if(f.isReading())
00934                 _InternalFlags |= TouchedAll;
00935 }
00936 
00937 // --------------------------------------------------
00938 
00939 // CPaletteSkin serial (no version chek).
00940 void    CPaletteSkin::serial(NLMISC::IStream &f)
00941 {
00942         f.serial(MatrixId[0], MatrixId[1], MatrixId[2], MatrixId[3]);
00943 }
00944 
00945 // --------------------------------------------------
00946 
00947 IVBDrvInfos::~IVBDrvInfos()
00948 {
00949         _Driver->removeVBDrvInfoPtr(_DriverIterator);
00950 }
00951 
00952 // --------------------------------------------------
00953 
00954 }