1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/3d/vertex_buffer.h"
20 #include "nel/misc/vector.h"
21 #include "nel/misc/fast_mem.h"
22 #include "nel/3d/driver.h"
24 using namespace NLMISC
;
33 // --------------------------------------------------
35 const uint
CVertexBuffer::SizeType
[NumType
]=
53 const uint
CVertexBuffer::NumComponentsType
[NumType
] =
71 // --------------------------------------------------
73 const CVertexBuffer::TType
CVertexBuffer::DefaultValueType
[NumValue
]=
85 UChar4
, // Primary color
86 UChar4
, // Secondary color
88 UChar4
, // PaletteSkin
94 // --------------------------------------------------
96 void CVertexBuffer::construct()
98 /* ***********************************************
99 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
100 * It can be loaded/called through CAsyncFileManager for instance
101 * ***********************************************/
107 _VertexColorFormat
= TRGBA
;
109 _LockedBuffer
= NULL
;
110 _PreferredMemory
= RAMPreferred
;
111 _Location
= NotResident
;
113 _KeepLocalMemory
= false;
117 for (i
=0; i
<MaxStage
; i
++)
121 // --------------------------------------------------
123 CVertexBuffer::CVertexBuffer()
128 CVertexBuffer::CVertexBuffer(const char *name
)
135 // --------------------------------------------------
137 CVertexBuffer::CVertexBuffer(const CVertexBuffer
&vb
) : CRefCount()
139 /* ***********************************************
140 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
141 * It can be loaded/called through CAsyncFileManager for instance
142 * ***********************************************/
149 _LockedBuffer
= NULL
;
150 _PreferredMemory
= RAMPreferred
;
151 _Location
= NotResident
;
153 _KeepLocalMemory
= false;
159 for (i
=0; i
<MaxStage
; i
++)
163 // --------------------------------------------------
165 CVertexBuffer::~CVertexBuffer()
167 /* ***********************************************
168 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
169 * It can be loaded/called through CAsyncFileManager for instance
170 * ***********************************************/
173 DrvInfos
->VertexBufferPtr
= NULL
; // Tell the driver info to not restore memory when it will die
175 // Must kill the drv mirror of this VB.
179 // --------------------------------------------------
181 CVertexBuffer
&CVertexBuffer::operator=(const CVertexBuffer
&vb
)
183 nlassertex (!isLocked(), ("The vertex buffer is locked."));
184 nlassertex (!vb
.isLocked(), ("Source buffer is locked."));
187 _VertexSize
= vb
._VertexSize
;
189 _InternalFlags
= vb
._InternalFlags
;
190 _NbVerts
= vb
._NbVerts
;
191 _Capacity
= vb
._Capacity
;
192 _NonResidentVertices
= vb
._NonResidentVertices
;
193 _VertexColorFormat
= vb
._VertexColorFormat
;
194 _PreferredMemory
= vb
._PreferredMemory
;
195 _KeepLocalMemory
= vb
._KeepLocalMemory
;
198 _LockedBuffer
= NULL
;
201 for (uint value
=0; value
<NumValue
; value
++)
203 _Offset
[value
]= vb
._Offset
[value
];
204 _Type
[value
]= vb
._Type
[value
];
208 for (i
=0; i
<MaxStage
; i
++)
209 _UVRouting
[i
] = vb
._UVRouting
[i
];
212 _InternalFlags
|= TouchedAll
;
213 _Location
= NotResident
;
219 // --------------------------------------------------
220 void CVertexBuffer::copyVertices(CVertexBuffer
&dest
) const
222 nlassert(_PreferredMemory
!= RAMVolatile
);
223 nlassert(_PreferredMemory
!= AGPVolatile
);
226 CVertexBufferReadWrite srcDatas
;
227 const_cast<CVertexBuffer
*>(this)->lock(srcDatas
);
228 nlassert(dest
.getLocation() == NotResident
);
229 CVertexBufferReadWrite destDatas
;
230 dest
.lock(destDatas
); // will be in vram
231 NLMISC::CFastMem::memcpy (destDatas
.getVertexCoordPointer(), srcDatas
.getVertexCoordPointer(), getVertexSize() * getNumVertices());
234 // --------------------------------------------------
236 bool CVertexBuffer::setVertexFormat(uint32 flags
)
238 nlassertex (!isLocked(), ("The vertex buffer is locked."));
242 // Clear extended values
246 if (flags
& PositionFlag
)
248 // Add a standard position value
249 addValueEx (Position
, Float3
);
253 if (flags
& NormalFlag
)
255 // Add a standard normal value
256 addValueEx (Normal
, Float3
);
259 // For each uv values
260 for(i
=0 ; i
<MaxStage
; i
++)
263 if (flags
& (TexCoord0Flag
<<i
))
265 // Add a standard uv value
266 addValueEx ((TValue
)(TexCoord0
+i
), Float2
);
273 // Add a standard primary color value
274 addValueEx (Fog
, Float1
);
278 if (flags
& PrimaryColorFlag
)
280 // Add a standard primary color value
281 addValueEx (PrimaryColor
, UChar4
);
285 if (flags
& SecondaryColorFlag
)
287 // Add a standard primary color value
288 addValueEx (SecondaryColor
, UChar4
);
292 if (flags
& WeightFlag
)
294 // Add a standard primary color value
295 addValueEx (Weight
, Float4
);
299 if ((flags
& PaletteSkinFlag
)==CVertexBuffer::PaletteSkinFlag
)
301 // Add a standard primary color value
302 addValueEx (PaletteSkin
, UChar4
);
305 // Compute the vertex buffer
308 // Force non resident
309 restoreNonResidentMemory();
314 // --------------------------------------------------
316 CVertexBuffer::TValue
CVertexBuffer::getValueIdByNumberEx (uint valueNumber
)
318 // See NV_vertex_program spec, or driver_opengl_vertex.cpp:: GLVertexAttribIndex.
319 static TValue lut
[16]= {
338 return lut
[valueNumber
];
341 // --------------------------------------------------
343 void CVertexBuffer::clearValueEx ()
345 nlassertex (!isLocked(), ("The vertex buffer is locked."));
347 // Reset format flags
352 // --------------------------------------------------
354 void CVertexBuffer::dumpFormat() const
356 for(uint k
= 0; k
< NumValue
; ++k
)
358 if (_Flags
& (1 << k
))
360 std::string result
= "Component :";
363 case Position
: result
+= "Position"; break;
364 case Normal
: result
+= "Normal"; break;
365 case TexCoord0
: result
+= "TexCoord0"; break;
366 case TexCoord1
: result
+= "TexCoord1"; break;
367 case TexCoord2
: result
+= "TexCoord2"; break;
368 case TexCoord3
: result
+= "TexCoord3"; break;
369 case TexCoord4
: result
+= "TexCoord4"; break;
370 case TexCoord5
: result
+= "TexCoord5"; break;
371 case TexCoord6
: result
+= "TexCoord6"; break;
372 case TexCoord7
: result
+= "TexCoord7"; break;
373 case PrimaryColor
: result
+= "PrimaryColor"; break;
374 case SecondaryColor
:result
+= "SecondaryColor"; break;
375 case Weight
: result
+= "Weight"; break;
376 case PaletteSkin
: result
+= "PaletteSkin"; break;
377 case Fog
: result
+= "Fog"; break;
378 case Empty
: result
+= "Empty"; break;
379 case NumValue
: result
+= "NumValue"; break;
384 result
+= "; type :";
387 case Double1
: result
+="Double1"; break;
388 case Float1
: result
+="Float1"; break;
389 case Short1
: result
+="Short1"; break;
390 case Double2
: result
+="Double2"; break;
391 case Float2
: result
+="Float2"; break;
392 case Short2
: result
+="Short2"; break;
393 case Double3
: result
+="Double3"; break;
394 case Float3
: result
+="Float3"; break;
395 case Short3
: result
+="Short3"; break;
396 case Double4
: result
+="Double4"; break;
397 case Float4
: result
+="Float4"; break;
398 case Short4
: result
+="Short4"; break;
399 case UChar4
: result
+="UChar4"; break;
404 nlinfo(result
.c_str());
410 // --------------------------------------------------
412 void CVertexBuffer::addValueEx (TValue valueId
, TType type
)
414 nlassertex (!isLocked(), ("The vertex buffer is locked."));
416 // Reset format flags
417 _Flags
|= 1<<valueId
;
420 _Type
[valueId
]=(uint8
)type
;
422 uint numComp
= NumComponentsType
[type
];
423 // unfortunately, some vertex program implementations don't allow any type for any value
426 case Position
: nlassert(numComp
>= 2); break;
427 case Normal
: nlassert(numComp
== 3); break;
428 case PrimaryColor
: nlassert(numComp
== 4); break;
429 case SecondaryColor
: nlassert(numComp
== 4); break;
430 case Weight
: nlassert(numComp
== 4); break;
431 case PaletteSkin
: nlassert(numComp
== 4); break;
432 case Fog
: nlassert(numComp
== 4); break;
437 // --------------------------------------------------
439 bool CVertexBuffer::hasValueEx(TValue valueId
) const
441 return (_Flags
& (1 << valueId
)) != 0;
444 // --------------------------------------------------
446 void CVertexBuffer::initEx ()
448 nlassert (!isLocked());
450 // Calc vertex size and set value's offset
452 for (uint value
=0; value
<NumValue
; value
++)
455 if (_Flags
&(1<<value
))
458 _Offset
[value
]=_VertexSize
;
461 _VertexSize
+=SizeType
[_Type
[value
]];
465 // Reset number of vertices
468 // Compute new capacity
470 _Capacity
= (uint32
)_NonResidentVertices
.size()/_VertexSize
;
474 // Force non resident
475 restoreNonResidentMemory();
478 // --------------------------------------------------
480 void CVertexBuffer::reserve(uint32 n
)
482 nlassert (!isLocked());
486 _NbVerts
=std::min (_NbVerts
,_Capacity
);
488 // Force non resident
489 restoreNonResidentMemory();
493 // --------------------------------------------------
495 void CVertexBuffer::setNumVertices(uint32 n
)
503 _InternalFlags
|= TouchedNumVertices
;
508 // --------------------------------------------------
510 void CVertexBuffer::deleteAllVertices()
514 nlassert (!isLocked());
516 contReset(_NonResidentVertices
);
521 _InternalFlags
|= TouchedNumVertices
;
524 // Force non resident
525 restoreNonResidentMemory();
527 // Delete driver info
528 nlassert (DrvInfos
== NULL
);
532 // --------------------------------------------------
534 uint16
CVertexBuffer::remapV2Flags (uint32 oldFlags
, uint
& weightCount
)
537 const uint32 OLD_IDRV_VF_XYZ
= 0x00000001;
538 const uint32 OLD_IDRV_VF_W0
= 0x00000002;
539 const uint32 OLD_IDRV_VF_W1
= 0x00000004;
540 const uint32 OLD_IDRV_VF_W2
= 0x00000008;
541 const uint32 OLD_IDRV_VF_W3
= 0x00000010;
542 const uint32 OLD_IDRV_VF_NORMAL
= 0x00000020;
543 const uint32 OLD_IDRV_VF_COLOR
= 0x00000040;
544 const uint32 OLD_IDRV_VF_SPECULAR
= 0x00000080;
545 const uint32 OLD_IDRV_VF_UV0
= 0x00000100;
546 const uint32 OLD_IDRV_VF_UV1
= 0x00000200;
547 const uint32 OLD_IDRV_VF_UV2
= 0x00000400;
548 const uint32 OLD_IDRV_VF_UV3
= 0x00000800;
549 const uint32 OLD_IDRV_VF_UV4
= 0x00001000;
550 const uint32 OLD_IDRV_VF_UV5
= 0x00002000;
551 const uint32 OLD_IDRV_VF_UV6
= 0x00004000;
552 const uint32 OLD_IDRV_VF_UV7
= 0x00008000;
553 const uint32 OLD_IDRV_VF_PALETTE_SKIN
= 0x00010000 | OLD_IDRV_VF_W0
| OLD_IDRV_VF_W1
| OLD_IDRV_VF_W2
| OLD_IDRV_VF_W3
;
558 // Number of weight values
562 if (oldFlags
&OLD_IDRV_VF_XYZ
)
563 newFlags
|=PositionFlag
;
564 if (oldFlags
&OLD_IDRV_VF_NORMAL
)
565 newFlags
|=NormalFlag
;
566 if (oldFlags
&OLD_IDRV_VF_COLOR
)
567 newFlags
|=PrimaryColorFlag
;
568 if (oldFlags
&OLD_IDRV_VF_SPECULAR
)
569 newFlags
|=SecondaryColorFlag
;
570 if (oldFlags
&OLD_IDRV_VF_UV0
)
571 newFlags
|=TexCoord0Flag
;
572 if (oldFlags
&OLD_IDRV_VF_UV1
)
573 newFlags
|=TexCoord1Flag
;
574 if (oldFlags
&OLD_IDRV_VF_UV2
)
575 newFlags
|=TexCoord2Flag
;
576 if (oldFlags
&OLD_IDRV_VF_UV3
)
577 newFlags
|=TexCoord3Flag
;
578 if (oldFlags
&OLD_IDRV_VF_UV4
)
579 newFlags
|=TexCoord4Flag
;
580 if (oldFlags
&OLD_IDRV_VF_UV5
)
581 newFlags
|=TexCoord5Flag
;
582 if (oldFlags
&OLD_IDRV_VF_UV6
)
583 newFlags
|=TexCoord6Flag
;
584 if (oldFlags
&OLD_IDRV_VF_UV7
)
585 newFlags
|=TexCoord7Flag
;
586 if (oldFlags
&OLD_IDRV_VF_W0
)
589 newFlags
|=WeightFlag
;
591 if (oldFlags
&OLD_IDRV_VF_W1
)
594 newFlags
|=WeightFlag
;
596 if (oldFlags
&OLD_IDRV_VF_W2
)
599 newFlags
|=WeightFlag
;
601 if (oldFlags
&OLD_IDRV_VF_W3
)
604 newFlags
|=WeightFlag
;
606 if (oldFlags
&(OLD_IDRV_VF_PALETTE_SKIN
))
607 newFlags
|=PaletteSkinFlag
;
609 // Return the new flags
613 // --------------------------------------------------
615 void CVertexBuffer::serialOldV1Minus(NLMISC::IStream
&f
, sint ver
)
617 /* ***********************************************
618 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
619 * It can be loaded/called through CAsyncFileManager for instance
620 * ***********************************************/
624 - PaletteSkin version.
632 // Serial VBuffers format/size.
633 //=============================
638 uint16 newFlags
=remapV2Flags (oldFlags
, weightCount
);
641 nlassert (f
.isReading());
643 // Set default value type
645 for (i
=0; i
<NumValue
; i
++)
646 _Type
[i
]=DefaultValueType
[i
];
648 uint32 nbVert
; // Read only
651 setVertexFormat(newFlags
);
652 setNumVertices(nbVert
);
653 // All other infos (but _NonResidentVertices) are computed by setVertexFormat() and setNumVertices().
659 _Type
[Weight
]=Float1
;
662 _Type
[Weight
]=Float2
;
665 _Type
[Weight
]=Float3
;
668 _Type
[Weight
]=Float4
;
672 // Serial VBuffers components.
673 //============================
674 for(sint id
=0;id
<(sint
)_NbVerts
;id
++)
676 uint8
*pointer
= &(*_NonResidentVertices
.begin());
677 uint stridedId
= id
* _VertexSize
;
679 if(_Flags
& PositionFlag
)
681 CVector
&vert
= *(CVector
*)(pointer
+ stridedId
+ _Offset
[Position
]);
685 if(_Flags
& NormalFlag
)
687 CVector
&norm
= *(CVector
*)(pointer
+ stridedId
+ _Offset
[Normal
]);
691 for(i
=0;i
<MaxStage
;i
++)
693 if(_Flags
& (TexCoord0Flag
<<i
))
695 CUV
&uv
= *(CUV
*)(pointer
+ stridedId
+ _Offset
[TexCoord0
+i
]);
700 if(_Flags
& PrimaryColorFlag
)
702 CRGBA
&col
= *(CRGBA
*)(pointer
+ stridedId
+ _Offset
[PrimaryColor
]);
706 if(_Flags
& SecondaryColorFlag
)
708 CRGBA
&col
= *(CRGBA
*)(pointer
+ stridedId
+ _Offset
[SecondaryColor
]);
712 for(i
=0;i
<weightCount
;i
++)
714 // Weight channel available ?
715 float &w
= *(float*)(pointer
+ stridedId
+ _Offset
[Weight
] + i
*sizeof(float));
718 // CPaletteSkin (version 1+ only).
719 if((ver
>=1) && ((_Flags
& PaletteSkinFlag
) == CVertexBuffer::PaletteSkinFlag
) )
721 CPaletteSkin
&ps
= *(CPaletteSkin
*)(pointer
+ stridedId
+ _Offset
[PaletteSkin
]);
731 // Force non resident
732 restoreNonResidentMemory();
736 // --------------------------------------------------
738 void CVertexBuffer::serial(NLMISC::IStream
&f
)
740 /* ***********************************************
741 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
742 * It can be loaded/called through CAsyncFileManager for instance
743 * ***********************************************/
747 - cut to use serialHeader() serialSubset().
749 - PaletteSkin version.
753 nlassert (!isLocked());
754 sint ver
= f
.serialVersion(2);
759 serialOldV1Minus(f
, ver
);
763 // read write the header of the VBuffer.
766 // read write the entire subset.
767 serialSubset(f
, 0, _NbVerts
);
771 // --------------------------------------------------
773 void CVertexBuffer::serialHeader(NLMISC::IStream
&f
)
775 /* ***********************************************
776 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
777 * It can be loaded/called through CAsyncFileManager for instance
778 * ***********************************************/
784 - Vertex color format management.
786 - Extended vertex format management.
788 - base verison of the header serialisation.
790 sint ver
= f
.serialVersion(3); // Hulud
792 // Serial VBuffers format/size.
793 //=============================
801 nlassert (f
.isReading());
809 flags
=remapV2Flags (oldFlags
, weightCount
);
811 // Set default value type
812 for (uint i
=0; i
<NumValue
; i
++)
813 _Type
[i
]=DefaultValueType
[i
];
819 _Type
[Weight
]=Float1
;
822 _Type
[Weight
]=Float2
;
825 _Type
[Weight
]=Float3
;
828 _Type
[Weight
]=Float4
;
834 // Serial new vertex flags
837 // Serial type of values
838 for (uint i
=0; i
<NumValue
; i
++)
840 if (!(flags
& (1 << i
)))
842 _Type
[i
] = DefaultValueType
[i
];
848 // Serial nb vertices
849 uint32 nbVerts
=_NbVerts
;
856 // Init vertex format setup
859 // Init vertex format
860 for (uint i
=0; i
<NumValue
; i
++)
862 // Setup this value ?
866 addValueEx ((TValue
)i
, (TType
)_Type
[i
]);
870 // Build final vertex format
873 // Set num of vertices
874 setNumVertices(nbVerts
);
876 // All other infos (but _NonResidentVertices) are computed by initEx() and setNumVertices().
879 f
.serial (_VertexColorFormat
);
883 f
.serialEnum(_PreferredMemory
);
888 // Init preferred memory
891 _PreferredMemory
= RAMPreferred
;
898 // --------------------------------------------------
899 uint
CVertexBuffer:: getNumTexCoordUsed() const
901 for (sint k
= (MaxStage
- 1); k
>= 0; --k
)
903 if (_Flags
& (TexCoord0Flag
<< k
)) return (uint
) (k
+ 1);
908 // --------------------------------------------------
910 uint8
CVertexBuffer::getNumWeight () const
913 switch (_Type
[Weight
])
929 // --------------------------------------------------
931 void CVertexBuffer::serialSubset(NLMISC::IStream
&f
, uint vertexStart
, uint vertexEnd
)
933 /* ***********************************************
934 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
935 * It can be loaded/called through CAsyncFileManager for instance
936 * ***********************************************/
942 - weight is 4 float in standard format.
944 - base verison of a vbuffer subset serialisation.
946 sint ver
= f
.serialVersion(2);
949 // Serial VBuffers components.
950 //============================
951 nlassert(vertexStart
<_NbVerts
|| _NbVerts
==0);
952 nlassert(vertexEnd
<=_NbVerts
);
953 for(uint id
=vertexStart
; id
<vertexEnd
; id
++)
956 for (uint value
=0; value
<NumValue
; value
++)
959 if (_Flags
&(1<<value
))
961 // Get the pointer on it
962 void *ptr
=(void*)((&(*_NonResidentVertices
.begin()))+id
*_VertexSize
+getValueOffEx ((TValue
)value
));
963 f
.serialBuffer ((uint8
*)ptr
, SizeType
[_Type
[value
]]);
968 // Serial the UV Routing table
969 //============================
972 f
.serialBuffer (_UVRouting
, sizeof(uint8
)*MaxStage
);
978 for (i
=0; i
<MaxStage
; i
++)
985 // Force non resident
986 restoreNonResidentMemory();
990 // --------------------------------------------------
992 bool CVertexBuffer::setVertexColorFormat (TVertexColorType format
)
998 nlassert (!isLocked());
1000 // Format is not good ?
1001 if ((TVertexColorType
)_VertexColorFormat
!= format
)
1003 // Diffuse or specualr component ?
1004 if (_Flags
& (PrimaryColorFlag
|SecondaryColorFlag
))
1007 uint32
*ptr0
= (_Flags
&PrimaryColorFlag
)?(uint32
*)&(_NonResidentVertices
[_Offset
[PrimaryColor
]]):NULL
;
1008 uint32
*ptr1
= (_Flags
&SecondaryColorFlag
)?(uint32
*)&(_NonResidentVertices
[_Offset
[SecondaryColor
]]):NULL
;
1009 for (i
=0; i
<_NbVerts
; i
++)
1013 const register uint32 value
= *ptr0
;
1014 #ifdef NL_LITTLE_ENDIAN
1015 *ptr0
= (value
&0xff00ff00)|((value
&0xff)<<16)|((value
&0xff0000)>>16);
1016 #else // NL_LITTLE_ENDIAN
1017 *ptr0
= (value
&0x00ff00ff)|((value
&0xff00)<<16)|((value
&0xff000000)>>16);
1018 #endif // NL_LITTLE_ENDIAN
1019 ptr0
= (uint32
*)(((uint8
*)ptr0
)+_VertexSize
);
1023 const register uint32 value
= *ptr1
;
1024 #ifdef NL_LITTLE_ENDIAN
1025 *ptr1
= (value
&0xff00ff00)|((value
&0xff)<<16)|((value
&0xff0000)>>16);
1026 #else // NL_LITTLE_ENDIAN
1027 *ptr1
= (value
&0x00ff00ff)|((value
&0xff00)<<16)|((value
&0xff000000)>>16);
1028 #endif // NL_LITTLE_ENDIAN
1029 ptr1
= (uint32
*)(((uint8
*)ptr1
)+_VertexSize
);
1033 _VertexColorFormat
= (uint8
)format
;
1035 // Force non resident
1036 restoreNonResidentMemory();
1041 // --------------------------------------------------
1043 void CVertexBuffer::setPreferredMemory (TPreferredMemory preferredMemory
, bool keepLocalMemory
)
1045 if ((_PreferredMemory
!= preferredMemory
) || (_KeepLocalMemory
!= keepLocalMemory
))
1047 _PreferredMemory
= preferredMemory
;
1048 _KeepLocalMemory
= keepLocalMemory
;
1050 // Force non resident
1051 restoreNonResidentMemory();
1055 // --------------------------------------------------
1056 void CVertexBuffer::setLocation (TLocation newLocation
)
1059 if (newLocation
!= NotResident
)
1061 // The driver must have setuped the driver info
1062 nlassert (DrvInfos
);
1064 // Current size of the buffer
1065 const uint size
= ((_PreferredMemory
==RAMVolatile
)||(_PreferredMemory
==AGPVolatile
))?_NbVerts
*_VertexSize
:_Capacity
*_VertexSize
;
1067 // The buffer must not be resident
1068 if (_Location
!= NotResident
)
1069 setLocation (NotResident
);
1071 // Copy the buffer containt
1072 uint8
*dest
= DrvInfos
->lock (0, size
, false);
1073 nlassert (size
<=_NonResidentVertices
.size()); // Internal buffer must have the good size
1074 memcpy (dest
, &(_NonResidentVertices
[0]), size
);
1075 DrvInfos
->unlock(0, 0);
1077 // Reset the non resident container if not a static preferred memory and not put in RAM
1078 if ((_PreferredMemory
!= StaticPreferred
) && (_Location
!= RAMResident
) && !_KeepLocalMemory
)
1079 contReset(_NonResidentVertices
);
1081 // Clear touched flags
1084 _Location
= newLocation
;
1085 _ResidentSize
= size
;
1089 // Current size of the buffer
1090 const uint size
= _Capacity
*_VertexSize
;
1092 // Resize the non resident buffer
1093 _NonResidentVertices
.resize (size
);
1095 // If resident in RAM, backup the data in non resident memory
1096 if ((_Location
== RAMResident
) && (_PreferredMemory
!= RAMVolatile
) && (_PreferredMemory
!= AGPVolatile
) && !_KeepLocalMemory
)
1098 // The driver must have setuped the driver info
1099 nlassert (DrvInfos
);
1101 // Copy the old buffer data
1102 const uint8
*src
= DrvInfos
->lock (0, _ResidentSize
, true);
1103 if (!_NonResidentVertices
.empty())
1104 memcpy (&(_NonResidentVertices
[0]), src
, std::min (size
, (uint
)_ResidentSize
));
1105 DrvInfos
->unlock(0, 0);
1108 _Location
= NotResident
;
1112 _InternalFlags
|= TouchedAll
;
1116 // --------------------------------------------------
1117 void CVertexBuffer::restoreNonResidentMemory()
1119 setLocation (NotResident
);
1122 DrvInfos
->VertexBufferPtr
= NULL
; // Tell the driver info to not restore memory when it will die
1124 // Must kill the drv mirror of this VB.
1128 // --------------------------------------------------
1130 void CVertexBuffer::fillBuffer ()
1132 if (DrvInfos
&& _KeepLocalMemory
)
1134 // Copy the local memory in local memory
1135 const uint size
= _NbVerts
*_VertexSize
;
1136 nlassert (size
<=_NonResidentVertices
.size());
1137 uint8
*dest
= DrvInfos
->lock (0, size
, false);
1138 NLMISC::CFastMem::memcpy (dest
, &(_NonResidentVertices
[0]), size
);
1139 DrvInfos
->unlock(0, size
);
1143 // --------------------------------------------------
1145 // CPaletteSkin serial (no version chek).
1146 void CPaletteSkin::serial(NLMISC::IStream
&f
)
1148 f
.serial(MatrixId
[0], MatrixId
[1], MatrixId
[2], MatrixId
[3]);
1151 // --------------------------------------------------
1153 IVBDrvInfos::~IVBDrvInfos()
1155 _Driver
->removeVBDrvInfoPtr(_DriverIterator
);
1158 // --------------------------------------------------
1159 // CVertexBufferReadWrite
1160 // --------------------------------------------------
1162 NLMISC::CVector
* CVertexBufferReadWrite::getVertexCoordPointer(uint idx
)
1164 nlassert (_Parent
->checkLockedBuffer());
1167 ptr
=_Parent
->_LockedBuffer
;
1168 ptr
+=(idx
*_Parent
->_VertexSize
);
1169 return((NLMISC::CVector
*)ptr
);
1172 // --------------------------------------------------
1174 NLMISC::CVector
* CVertexBufferReadWrite::getNormalCoordPointer(uint idx
)
1176 nlassert (_Parent
->checkLockedBuffer());
1179 if ( !(_Parent
->_Flags
& CVertexBuffer::NormalFlag
) )
1183 ptr
=_Parent
->_LockedBuffer
;
1184 ptr
+=_Parent
->_Offset
[CVertexBuffer::Normal
];
1185 ptr
+=idx
*_Parent
->_VertexSize
;
1186 return((NLMISC::CVector
*)ptr
);
1189 // --------------------------------------------------
1191 void* CVertexBufferReadWrite::getColorPointer(uint idx
)
1193 nlassert (_Parent
->checkLockedBuffer());
1196 if ( !(_Parent
->_Flags
& CVertexBuffer::PrimaryColorFlag
) )
1200 ptr
=_Parent
->_LockedBuffer
;
1201 ptr
+=_Parent
->_Offset
[CVertexBuffer::PrimaryColor
];
1202 ptr
+=idx
*_Parent
->_VertexSize
;
1206 // --------------------------------------------------
1208 void* CVertexBufferReadWrite::getSpecularPointer(uint idx
)
1210 nlassert (_Parent
->checkLockedBuffer());
1213 if ( !(_Parent
->_Flags
& CVertexBuffer::SecondaryColorFlag
) )
1217 ptr
=_Parent
->_LockedBuffer
;
1218 ptr
+=_Parent
->_Offset
[CVertexBuffer::SecondaryColor
];
1219 ptr
+=idx
*_Parent
->_VertexSize
;
1223 // --------------------------------------------------
1225 NLMISC::CUV
* CVertexBufferReadWrite::getTexCoordPointer(uint idx
, uint8 stage
)
1227 nlassert (_Parent
->checkLockedBuffer());
1230 if ( !(_Parent
->_Flags
& (CVertexBuffer::TexCoord0Flag
<<stage
)) )
1234 ptr
=_Parent
->_LockedBuffer
;
1235 ptr
+=_Parent
->_Offset
[CVertexBuffer::TexCoord0
+stage
];
1236 ptr
+=idx
*_Parent
->_VertexSize
;
1237 return((NLMISC::CUV
*)ptr
);
1240 // --------------------------------------------------
1242 float* CVertexBufferReadWrite::getWeightPointer(uint idx
, uint8 wgt
)
1244 nlassert (_Parent
->checkLockedBuffer());
1247 nlassert(wgt
<CVertexBuffer::MaxWeight
);
1248 if( !(_Parent
->_Flags
& CVertexBuffer::WeightFlag
))
1251 ptr
=(uint8
*)(&_Parent
->_LockedBuffer
[idx
*_Parent
->_VertexSize
]);
1252 ptr
+=_Parent
->_Offset
[CVertexBuffer::Weight
]+wgt
*sizeof(float);
1257 // --------------------------------------------------
1259 CPaletteSkin
* CVertexBufferReadWrite::getPaletteSkinPointer(uint idx
)
1261 nlassert (_Parent
->checkLockedBuffer());
1264 if ( (_Parent
->_Flags
& CVertexBuffer::PaletteSkinFlag
) != CVertexBuffer::PaletteSkinFlag
)
1268 ptr
=_Parent
->_LockedBuffer
;
1269 ptr
+=_Parent
->_Offset
[CVertexBuffer::PaletteSkin
];
1270 ptr
+=idx
*_Parent
->_VertexSize
;
1271 return((CPaletteSkin
*)ptr
);
1274 // --------------------------------------------------
1276 void CVertexBufferReadWrite::touchVertices (uint first
, uint last
)
1278 nlassert (_Parent
->checkLockedBuffer());
1283 // --------------------------------------------------
1284 // CVertexBufferRead
1285 // --------------------------------------------------
1287 const NLMISC::CVector
* CVertexBufferRead::getVertexCoordPointer(uint idx
) const
1289 nlassert (_Parent
->checkLockedBuffer());
1292 ptr
=_Parent
->_LockedBuffer
;
1293 ptr
+=(idx
*_Parent
->_VertexSize
);
1294 return((const NLMISC::CVector
*)ptr
);
1297 // --------------------------------------------------
1299 const NLMISC::CVector
* CVertexBufferRead::getNormalCoordPointer(uint idx
) const
1301 nlassert (_Parent
->checkLockedBuffer());
1304 if ( !(_Parent
->_Flags
& CVertexBuffer::NormalFlag
) )
1308 ptr
=_Parent
->_LockedBuffer
;
1309 ptr
+=_Parent
->_Offset
[CVertexBuffer::Normal
];
1310 ptr
+=idx
*_Parent
->_VertexSize
;
1311 return((const NLMISC::CVector
*)ptr
);
1314 // --------------------------------------------------
1316 const void* CVertexBufferRead::getColorPointer(uint idx
) const
1318 nlassert (_Parent
->checkLockedBuffer());
1321 if ( !(_Parent
->_Flags
& CVertexBuffer::PrimaryColorFlag
) )
1325 ptr
=_Parent
->_LockedBuffer
;
1326 ptr
+=_Parent
->_Offset
[CVertexBuffer::PrimaryColor
];
1327 ptr
+=idx
*_Parent
->_VertexSize
;
1328 return((const void*)ptr
);
1331 // --------------------------------------------------
1333 const void* CVertexBufferRead::getSpecularPointer(uint idx
) const
1335 nlassert (_Parent
->checkLockedBuffer());
1338 if ( !(_Parent
->_Flags
& CVertexBuffer::SecondaryColorFlag
) )
1342 ptr
=_Parent
->_LockedBuffer
;
1343 ptr
+=_Parent
->_Offset
[CVertexBuffer::SecondaryColor
];
1344 ptr
+=idx
*_Parent
->_VertexSize
;
1345 return((const void*)ptr
);
1348 // --------------------------------------------------
1350 const NLMISC::CUV
* CVertexBufferRead::getTexCoordPointer(uint idx
, uint8 stage
) const
1352 nlassert (_Parent
->checkLockedBuffer());
1355 if ( !(_Parent
->_Flags
& (CVertexBuffer::TexCoord0Flag
<<stage
)) )
1359 ptr
=_Parent
->_LockedBuffer
;
1360 ptr
+=_Parent
->_Offset
[CVertexBuffer::TexCoord0
+stage
];
1361 ptr
+=idx
*_Parent
->_VertexSize
;
1362 return((const NLMISC::CUV
*)ptr
);
1365 // --------------------------------------------------
1367 const float* CVertexBufferRead::getWeightPointer(uint idx
, uint8 wgt
) const
1369 nlassert (_Parent
->checkLockedBuffer());
1372 nlassert(wgt
<CVertexBuffer::MaxWeight
);
1373 if( !(_Parent
->_Flags
& CVertexBuffer::WeightFlag
))
1376 ptr
=(uint8
*)(&_Parent
->_LockedBuffer
[idx
*_Parent
->_VertexSize
]);
1377 ptr
+=_Parent
->_Offset
[CVertexBuffer::Weight
]+wgt
*sizeof(float);
1382 // --------------------------------------------------
1384 const CPaletteSkin
* CVertexBufferRead::getPaletteSkinPointer(uint idx
) const
1386 nlassert (_Parent
->checkLockedBuffer());
1389 if ( (_Parent
->_Flags
& CVertexBuffer::PaletteSkinFlag
) != CVertexBuffer::PaletteSkinFlag
)
1393 ptr
=_Parent
->_LockedBuffer
;
1394 ptr
+=_Parent
->_Offset
[CVertexBuffer::PaletteSkin
];
1395 ptr
+=idx
*_Parent
->_VertexSize
;
1396 return((const CPaletteSkin
*)ptr
);
1399 // --------------------------------------------------