1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4     (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2013 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #include "OgreStableHeaders.h"
29 #include "OgreHardwareVertexBuffer.h"
30 #include "OgreColourValue.h"
31 #include "OgreException.h"
32 #include "OgreStringConverter.h"
33 #include "OgreHardwareBufferManager.h"
34 #include "OgreDefaultHardwareBufferManager.h"
35 #include "OgreRoot.h"
36 #include "OgreRenderSystem.h"
37 
38 namespace Ogre {
39 
40     //-----------------------------------------------------------------------------
HardwareVertexBuffer(HardwareBufferManagerBase * mgr,size_t vertexSize,size_t numVertices,HardwareBuffer::Usage usage,bool useSystemMemory,bool useShadowBuffer)41     HardwareVertexBuffer::HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize,
42         size_t numVertices, HardwareBuffer::Usage usage,
43         bool useSystemMemory, bool useShadowBuffer)
44         : HardwareBuffer(usage, useSystemMemory, useShadowBuffer),
45 		  mMgr(mgr),
46           mNumVertices(numVertices),
47           mVertexSize(vertexSize),
48           mIsInstanceData(false),
49 		  mInstanceDataStepRate(1)
50     {
51         // Calculate the size of the vertices
52         mSizeInBytes = mVertexSize * numVertices;
53 
54         // Create a shadow buffer if required
55         if (mUseShadowBuffer)
56         {
57             mShadowBuffer = OGRE_NEW DefaultHardwareVertexBuffer(mMgr, mVertexSize,
58                     mNumVertices, HardwareBuffer::HBU_DYNAMIC);
59         }
60 
61     }
62     //-----------------------------------------------------------------------------
~HardwareVertexBuffer()63     HardwareVertexBuffer::~HardwareVertexBuffer()
64     {
65 		if (mMgr)
66 		{
67 			mMgr->_notifyVertexBufferDestroyed(this);
68 		}
69         if (mShadowBuffer)
70         {
71             OGRE_DELETE mShadowBuffer;
72         }
73     }
74     //-----------------------------------------------------------------------------
checkIfVertexInstanceDataIsSupported()75     bool HardwareVertexBuffer::checkIfVertexInstanceDataIsSupported()
76     {
77     	// Use the current render system
78     	RenderSystem* rs = Root::getSingleton().getRenderSystem();
79 
80     	// Check if the supported
81     	return rs->getCapabilities()->hasCapability(RSC_VERTEX_BUFFER_INSTANCE_DATA);
82     }
83     //-----------------------------------------------------------------------------
setIsInstanceData(const bool val)84     void HardwareVertexBuffer::setIsInstanceData( const bool val )
85     {
86         if (val && !checkIfVertexInstanceDataIsSupported())
87         {
88             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
89                 "vertex instance data is not supported by the render system.",
90                 "HardwareVertexBuffer::checkIfInstanceDataSupported");
91         }
92         else
93         {
94         	mIsInstanceData = val;
95         }
96     }
97 	//-----------------------------------------------------------------------------
getInstanceDataStepRate() const98 	size_t HardwareVertexBuffer::getInstanceDataStepRate() const
99 	{
100 		return mInstanceDataStepRate;
101 	}
102 	//-----------------------------------------------------------------------------
setInstanceDataStepRate(const size_t val)103 	void HardwareVertexBuffer::setInstanceDataStepRate( const size_t val )
104 	{
105         if (val > 0)
106         {
107 			mInstanceDataStepRate = val;
108         }
109 		else
110 		{
111             OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
112                 "Instance data step rate must be bigger then 0.",
113                 "HardwareVertexBuffer::setInstanceDataStepRate");
114 		}
115 	}
116 	//-----------------------------------------------------------------------------
117 	// VertexElement
118 	//-----------------------------------------------------------------------------
VertexElement(unsigned short source,size_t offset,VertexElementType theType,VertexElementSemantic semantic,unsigned short index)119     VertexElement::VertexElement(unsigned short source, size_t offset,
120         VertexElementType theType, VertexElementSemantic semantic, unsigned short index)
121         : mSource(source), mOffset(offset), mType(theType),
122         mSemantic(semantic), mIndex(index)
123     {
124     }
125     //-----------------------------------------------------------------------------
getSize(void) const126 	size_t VertexElement::getSize(void) const
127 	{
128 		return getTypeSize(mType);
129 	}
130 	//-----------------------------------------------------------------------------
getTypeSize(VertexElementType etype)131 	size_t VertexElement::getTypeSize(VertexElementType etype)
132 	{
133 		switch(etype)
134 		{
135 		case VET_COLOUR:
136 		case VET_COLOUR_ABGR:
137 		case VET_COLOUR_ARGB:
138 			return sizeof(RGBA);
139 		case VET_FLOAT1:
140 			return sizeof(float);
141 		case VET_FLOAT2:
142 			return sizeof(float)*2;
143 		case VET_FLOAT3:
144 			return sizeof(float)*3;
145 		case VET_FLOAT4:
146 			return sizeof(float)*4;
147         case VET_DOUBLE1:
148             return sizeof(double);
149         case VET_DOUBLE2:
150             return sizeof(double)*2;
151         case VET_DOUBLE3:
152             return sizeof(double)*3;
153         case VET_DOUBLE4:
154             return sizeof(double)*4;
155 		case VET_SHORT1:
156 			return sizeof(short);
157 		case VET_SHORT2:
158 			return sizeof(short)*2;
159 		case VET_SHORT3:
160 			return sizeof(short)*3;
161 		case VET_SHORT4:
162 			return sizeof(short)*4;
163         case VET_USHORT1:
164             return sizeof(unsigned short);
165         case VET_USHORT2:
166             return sizeof(unsigned short)*2;
167         case VET_USHORT3:
168             return sizeof(unsigned short)*3;
169         case VET_USHORT4:
170             return sizeof(unsigned short)*4;
171         case VET_INT1:
172             return sizeof(int);
173         case VET_INT2:
174             return sizeof(int)*2;
175         case VET_INT3:
176             return sizeof(int)*3;
177         case VET_INT4:
178             return sizeof(int)*4;
179         case VET_UINT1:
180             return sizeof(unsigned int);
181         case VET_UINT2:
182             return sizeof(unsigned int)*2;
183         case VET_UINT3:
184             return sizeof(unsigned int)*3;
185         case VET_UINT4:
186             return sizeof(unsigned int)*4;
187         case VET_UBYTE4:
188             return sizeof(unsigned char)*4;
189 		}
190 		return 0;
191 	}
192 	//-----------------------------------------------------------------------------
getTypeCount(VertexElementType etype)193 	unsigned short VertexElement::getTypeCount(VertexElementType etype)
194 	{
195 		switch (etype)
196 		{
197 		case VET_COLOUR:
198 		case VET_COLOUR_ABGR:
199 		case VET_COLOUR_ARGB:
200         case VET_FLOAT1:
201         case VET_SHORT1:
202         case VET_USHORT1:
203         case VET_UINT1:
204         case VET_INT1:
205         case VET_DOUBLE1:
206 			return 1;
207         case VET_FLOAT2:
208         case VET_SHORT2:
209         case VET_USHORT2:
210         case VET_UINT2:
211         case VET_INT2:
212         case VET_DOUBLE2:
213 			return 2;
214         case VET_FLOAT3:
215         case VET_SHORT3:
216         case VET_USHORT3:
217         case VET_UINT3:
218         case VET_INT3:
219         case VET_DOUBLE3:
220 			return 3;
221         case VET_FLOAT4:
222         case VET_SHORT4:
223         case VET_USHORT4:
224         case VET_UINT4:
225         case VET_INT4:
226         case VET_DOUBLE4:
227         case VET_UBYTE4:
228             return 4;
229 		}
230 		OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid type",
231 			"VertexElement::getTypeCount");
232 	}
233 	//-----------------------------------------------------------------------------
multiplyTypeCount(VertexElementType baseType,unsigned short count)234 	VertexElementType VertexElement::multiplyTypeCount(VertexElementType baseType,
235 		unsigned short count)
236 	{
237 		switch (baseType)
238 		{
239 		case VET_FLOAT1:
240 			switch(count)
241 			{
242 			case 1:
243 				return VET_FLOAT1;
244 			case 2:
245 				return VET_FLOAT2;
246 			case 3:
247 				return VET_FLOAT3;
248 			case 4:
249 				return VET_FLOAT4;
250             default:
251                 break;
252 			}
253 			break;
254 		case VET_SHORT1:
255 			switch(count)
256 			{
257 			case 1:
258 				return VET_SHORT1;
259 			case 2:
260 				return VET_SHORT2;
261 			case 3:
262 				return VET_SHORT3;
263 			case 4:
264 				return VET_SHORT4;
265             default:
266                 break;
267 			}
268 			break;
269         default:
270             break;
271 		}
272 		OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid base type",
273 			"VertexElement::multiplyTypeCount");
274 	}
275 	//--------------------------------------------------------------------------
getBestColourVertexElementType(void)276 	VertexElementType VertexElement::getBestColourVertexElementType(void)
277 	{
278 		// Use the current render system to determine if possible
279 		if (Root::getSingletonPtr() && Root::getSingletonPtr()->getRenderSystem())
280 		{
281 			return Root::getSingleton().getRenderSystem()->getColourVertexElementType();
282 		}
283 		else
284 		{
285 			// We can't know the specific type right now, so pick a type
286 			// based on platform
287 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT
288 			return VET_COLOUR_ARGB; // prefer D3D format on windows
289 #else
290 			return VET_COLOUR_ABGR; // prefer GL format on everything else
291 #endif
292 
293 		}
294 	}
295 	//--------------------------------------------------------------------------
convertColourValue(VertexElementType srcType,VertexElementType dstType,uint32 * ptr)296 	void VertexElement::convertColourValue(VertexElementType srcType,
297 		VertexElementType dstType, uint32* ptr)
298 	{
299 		if (srcType == dstType)
300 			return;
301 
302 		// Conversion between ARGB and ABGR is always a case of flipping R/B
303 		*ptr =
304 		   ((*ptr&0x00FF0000)>>16)|((*ptr&0x000000FF)<<16)|(*ptr&0xFF00FF00);
305 	}
306 	//--------------------------------------------------------------------------
convertColourValue(const ColourValue & src,VertexElementType dst)307 	uint32 VertexElement::convertColourValue(const ColourValue& src,
308 		VertexElementType dst)
309 	{
310 		switch(dst)
311 		{
312 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT
313         default:
314 #endif
315 		case VET_COLOUR_ARGB:
316 			return src.getAsARGB();
317 #if OGRE_PLATFORM != OGRE_PLATFORM_WIN32 && OGRE_PLATFORM != OGRE_PLATFORM_WINRT
318         default:
319 #endif
320 		case VET_COLOUR_ABGR:
321 			return src.getAsABGR();
322 		};
323 
324 	}
325 	//-----------------------------------------------------------------------------
getBaseType(VertexElementType multiType)326 	VertexElementType VertexElement::getBaseType(VertexElementType multiType)
327 	{
328 		switch (multiType)
329 		{
330 			case VET_FLOAT1:
331 			case VET_FLOAT2:
332 			case VET_FLOAT3:
333 			case VET_FLOAT4:
334 				return VET_FLOAT1;
335 			case VET_DOUBLE1:
336 			case VET_DOUBLE2:
337 			case VET_DOUBLE3:
338 			case VET_DOUBLE4:
339 				return VET_DOUBLE1;
340             case VET_INT1:
341 			case VET_INT2:
342 			case VET_INT3:
343 			case VET_INT4:
344 				return VET_INT1;
345             case VET_UINT1:
346 			case VET_UINT2:
347 			case VET_UINT3:
348 			case VET_UINT4:
349 				return VET_UINT1;
350 			case VET_COLOUR:
351 				return VET_COLOUR;
352 			case VET_COLOUR_ABGR:
353 				return VET_COLOUR_ABGR;
354 			case VET_COLOUR_ARGB:
355 				return VET_COLOUR_ARGB;
356 			case VET_SHORT1:
357 			case VET_SHORT2:
358 			case VET_SHORT3:
359 			case VET_SHORT4:
360 				return VET_SHORT1;
361 			case VET_USHORT1:
362 			case VET_USHORT2:
363 			case VET_USHORT3:
364 			case VET_USHORT4:
365 				return VET_USHORT1;
366 			case VET_UBYTE4:
367 				return VET_UBYTE4;
368 		};
369         // To keep compiler happy
370         return VET_FLOAT1;
371 	}
372 	//-----------------------------------------------------------------------------
VertexDeclaration()373     VertexDeclaration::VertexDeclaration()
374     {
375     }
376     //-----------------------------------------------------------------------------
~VertexDeclaration()377     VertexDeclaration::~VertexDeclaration()
378     {
379     }
380     //-----------------------------------------------------------------------------
getElements(void) const381     const VertexDeclaration::VertexElementList& VertexDeclaration::getElements(void) const
382     {
383         return mElementList;
384     }
385     //-----------------------------------------------------------------------------
addElement(unsigned short source,size_t offset,VertexElementType theType,VertexElementSemantic semantic,unsigned short index)386     const VertexElement& VertexDeclaration::addElement(unsigned short source,
387         size_t offset, VertexElementType theType,
388         VertexElementSemantic semantic, unsigned short index)
389     {
390 		// Refine colour type to a specific type
391 		if (theType == VET_COLOUR)
392 		{
393 			theType = VertexElement::getBestColourVertexElementType();
394 		}
395         mElementList.push_back(
396             VertexElement(source, offset, theType, semantic, index)
397             );
398 		return mElementList.back();
399     }
400     //-----------------------------------------------------------------------------
insertElement(unsigned short atPosition,unsigned short source,size_t offset,VertexElementType theType,VertexElementSemantic semantic,unsigned short index)401     const VertexElement& VertexDeclaration::insertElement(unsigned short atPosition,
402         unsigned short source, size_t offset, VertexElementType theType,
403         VertexElementSemantic semantic, unsigned short index)
404     {
405         if (atPosition >= mElementList.size())
406         {
407             return addElement(source, offset, theType, semantic, index);
408         }
409 
410         VertexElementList::iterator i = mElementList.begin();
411         for (unsigned short n = 0; n < atPosition; ++n)
412             ++i;
413 
414         i = mElementList.insert(i,
415             VertexElement(source, offset, theType, semantic, index));
416         return *i;
417 
418     }
419     //-----------------------------------------------------------------------------
getElement(unsigned short index) const420     const VertexElement* VertexDeclaration::getElement(unsigned short index) const
421     {
422         assert(index < mElementList.size() && "Index out of bounds");
423 
424         VertexElementList::const_iterator i = mElementList.begin();
425         for (unsigned short n = 0; n < index; ++n)
426             ++i;
427 
428         return &(*i);
429 
430     }
431     //-----------------------------------------------------------------------------
removeElement(unsigned short elem_index)432     void VertexDeclaration::removeElement(unsigned short elem_index)
433     {
434         assert(elem_index < mElementList.size() && "Index out of bounds");
435         VertexElementList::iterator i = mElementList.begin();
436         for (unsigned short n = 0; n < elem_index; ++n)
437             ++i;
438         mElementList.erase(i);
439     }
440     //-----------------------------------------------------------------------------
removeElement(VertexElementSemantic semantic,unsigned short index)441     void VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index)
442     {
443 		VertexElementList::iterator ei, eiend;
444 		eiend = mElementList.end();
445 		for (ei = mElementList.begin(); ei != eiend; ++ei)
446 		{
447 			if (ei->getSemantic() == semantic && ei->getIndex() == index)
448 			{
449 				mElementList.erase(ei);
450                 break;
451 			}
452 		}
453     }
454 	//-----------------------------------------------------------------------------
removeAllElements(void)455 	void VertexDeclaration::removeAllElements(void)
456 	{
457 		mElementList.clear();
458 	}
459     //-----------------------------------------------------------------------------
modifyElement(unsigned short elem_index,unsigned short source,size_t offset,VertexElementType theType,VertexElementSemantic semantic,unsigned short index)460     void VertexDeclaration::modifyElement(unsigned short elem_index,
461         unsigned short source, size_t offset, VertexElementType theType,
462         VertexElementSemantic semantic, unsigned short index)
463     {
464         assert(elem_index < mElementList.size() && "Index out of bounds");
465         VertexElementList::iterator i = mElementList.begin();
466         std::advance(i, elem_index);
467         (*i) = VertexElement(source, offset, theType, semantic, index);
468     }
469     //-----------------------------------------------------------------------------
findElementBySemantic(VertexElementSemantic sem,unsigned short index) const470 	const VertexElement* VertexDeclaration::findElementBySemantic(
471 		VertexElementSemantic sem, unsigned short index) const
472 	{
473 		VertexElementList::const_iterator ei, eiend;
474 		eiend = mElementList.end();
475 		for (ei = mElementList.begin(); ei != eiend; ++ei)
476 		{
477 			if (ei->getSemantic() == sem && ei->getIndex() == index)
478 			{
479 				return &(*ei);
480 			}
481 		}
482 
483 		return NULL;
484 
485 
486 	}
487 	//-----------------------------------------------------------------------------
findElementsBySource(unsigned short source) const488 	VertexDeclaration::VertexElementList VertexDeclaration::findElementsBySource(
489 		unsigned short source) const
490 	{
491 		VertexElementList retList;
492 		VertexElementList::const_iterator ei, eiend;
493 		eiend = mElementList.end();
494 		for (ei = mElementList.begin(); ei != eiend; ++ei)
495 		{
496 			if (ei->getSource() == source)
497 			{
498 				retList.push_back(*ei);
499 			}
500 		}
501 		return retList;
502 
503 	}
504 
505 	//-----------------------------------------------------------------------------
getVertexSize(unsigned short source) const506 	size_t VertexDeclaration::getVertexSize(unsigned short source) const
507 	{
508 		VertexElementList::const_iterator i, iend;
509 		iend = mElementList.end();
510 		size_t sz = 0;
511 
512 		for (i = mElementList.begin(); i != iend; ++i)
513 		{
514 			if (i->getSource() == source)
515 			{
516 				sz += i->getSize();
517 
518 			}
519 		}
520 		return sz;
521 	}
522     //-----------------------------------------------------------------------------
clone(HardwareBufferManagerBase * mgr) const523     VertexDeclaration* VertexDeclaration::clone(HardwareBufferManagerBase* mgr) const
524     {
525 		HardwareBufferManagerBase* pManager = mgr ? mgr : HardwareBufferManager::getSingletonPtr();
526         VertexDeclaration* ret = pManager->createVertexDeclaration();
527 
528 		VertexElementList::const_iterator i, iend;
529 		iend = mElementList.end();
530 		for (i = mElementList.begin(); i != iend; ++i)
531 		{
532             ret->addElement(i->getSource(), i->getOffset(), i->getType(), i->getSemantic(), i->getIndex());
533         }
534         return ret;
535     }
536     //-----------------------------------------------------------------------------
537     // Sort routine for VertexElement
vertexElementLess(const VertexElement & e1,const VertexElement & e2)538     bool VertexDeclaration::vertexElementLess(const VertexElement& e1, const VertexElement& e2)
539     {
540         // Sort by source first
541         if (e1.getSource() < e2.getSource())
542         {
543             return true;
544         }
545         else if (e1.getSource() == e2.getSource())
546         {
547             // Use ordering of semantics to sort
548             if (e1.getSemantic() < e2.getSemantic())
549             {
550                 return true;
551             }
552             else if (e1.getSemantic() == e2.getSemantic())
553             {
554                 // Use index to sort
555                 if (e1.getIndex() < e2.getIndex())
556                 {
557                     return true;
558                 }
559             }
560         }
561         return false;
562     }
sort(void)563     void VertexDeclaration::sort(void)
564     {
565         mElementList.sort(VertexDeclaration::vertexElementLess);
566     }
567     //-----------------------------------------------------------------------------
closeGapsInSource(void)568     void VertexDeclaration::closeGapsInSource(void)
569     {
570         if (mElementList.empty())
571             return;
572 
573         // Sort first
574         sort();
575 
576         VertexElementList::iterator i, iend;
577         iend = mElementList.end();
578         unsigned short targetIdx = 0;
579         unsigned short lastIdx = getElement(0)->getSource();
580         unsigned short c = 0;
581         for (i = mElementList.begin(); i != iend; ++i, ++c)
582         {
583             VertexElement& elem = *i;
584             if (lastIdx != elem.getSource())
585             {
586                 targetIdx++;
587                 lastIdx = elem.getSource();
588             }
589             if (targetIdx != elem.getSource())
590             {
591                 modifyElement(c, targetIdx, elem.getOffset(), elem.getType(),
592                     elem.getSemantic(), elem.getIndex());
593             }
594 
595         }
596 
597     }
598     //-----------------------------------------------------------------------
getAutoOrganisedDeclaration(bool skeletalAnimation,bool vertexAnimation,bool vertexAnimationNormals) const599     VertexDeclaration* VertexDeclaration::getAutoOrganisedDeclaration(
600 		bool skeletalAnimation, bool vertexAnimation, bool vertexAnimationNormals) const
601     {
602         VertexDeclaration* newDecl = this->clone();
603         // Set all sources to the same buffer (for now)
604         const VertexDeclaration::VertexElementList& elems = newDecl->getElements();
605         VertexDeclaration::VertexElementList::const_iterator i;
606         unsigned short c = 0;
607         for (i = elems.begin(); i != elems.end(); ++i, ++c)
608         {
609             const VertexElement& elem = *i;
610             // Set source & offset to 0 for now, before sort
611             newDecl->modifyElement(c, 0, 0, elem.getType(), elem.getSemantic(), elem.getIndex());
612         }
613         newDecl->sort();
614         // Now sort out proper buffer assignments and offsets
615         size_t offset = 0;
616         c = 0;
617 		unsigned short buffer = 0;
618         VertexElementSemantic prevSemantic = VES_POSITION;
619         for (i = elems.begin(); i != elems.end(); ++i, ++c)
620         {
621             const VertexElement& elem = *i;
622 
623             bool splitWithPrev = false;
624             bool splitWithNext = false;
625             switch (elem.getSemantic())
626             {
627             case VES_POSITION:
628                 // Split positions if vertex animated with only positions
629 				// group with normals otherwise
630 				splitWithPrev = false;
631                 splitWithNext = vertexAnimation && !vertexAnimationNormals;
632                 break;
633             case VES_NORMAL:
634                 // Normals can't share with blend weights/indices
635                 splitWithPrev = (prevSemantic == VES_BLEND_WEIGHTS || prevSemantic == VES_BLEND_INDICES);
636                 // All animated meshes have to split after normal
637                 splitWithNext = (skeletalAnimation || (vertexAnimation && vertexAnimationNormals));
638                 break;
639             case VES_BLEND_WEIGHTS:
640                 // Blend weights/indices can be sharing with their own buffer only
641                 splitWithPrev = true;
642                 break;
643             case VES_BLEND_INDICES:
644                 // Blend weights/indices can be sharing with their own buffer only
645                 splitWithNext = true;
646                 break;
647 			default:
648             case VES_DIFFUSE:
649             case VES_SPECULAR:
650             case VES_TEXTURE_COORDINATES:
651             case VES_BINORMAL:
652             case VES_TANGENT:
653 				// Make sure position is separate if animated & there were no normals
654 				splitWithPrev = prevSemantic == VES_POSITION &&
655 					(skeletalAnimation || vertexAnimation);
656                 break;
657             }
658 
659             if (splitWithPrev && offset)
660             {
661                 ++buffer;
662                 offset = 0;
663             }
664 
665             prevSemantic = elem.getSemantic();
666             newDecl->modifyElement(c, buffer, offset,
667                 elem.getType(), elem.getSemantic(), elem.getIndex());
668 
669             if (splitWithNext)
670             {
671                 ++buffer;
672                 offset = 0;
673             }
674             else
675             {
676                 offset += elem.getSize();
677             }
678         }
679 
680         return newDecl;
681 
682 
683     }
684     //-----------------------------------------------------------------------------
getMaxSource(void) const685     unsigned short VertexDeclaration::getMaxSource(void) const
686     {
687         VertexElementList::const_iterator i, iend;
688         iend = mElementList.end();
689         unsigned short ret = 0;
690         for (i = mElementList.begin(); i != iend; ++i)
691         {
692             if (i->getSource() > ret)
693             {
694                 ret = i->getSource();
695             }
696 
697         }
698         return ret;
699     }
700     //-----------------------------------------------------------------------------
getNextFreeTextureCoordinate() const701 	unsigned short VertexDeclaration::getNextFreeTextureCoordinate() const
702 	{
703 		unsigned short texCoord = 0;
704 		for (VertexElementList::const_iterator i = mElementList.begin();
705 			 i != mElementList.end(); ++i)
706 		{
707 			const VertexElement& el = *i;
708 			if (el.getSemantic() == VES_TEXTURE_COORDINATES)
709 			{
710 				++texCoord;
711 			}
712 		}
713 		return texCoord;
714 	}
715     //-----------------------------------------------------------------------------
VertexBufferBinding()716 	VertexBufferBinding::VertexBufferBinding() : mHighIndex(0)
717 	{
718 	}
719     //-----------------------------------------------------------------------------
~VertexBufferBinding()720 	VertexBufferBinding::~VertexBufferBinding()
721 	{
722         unsetAllBindings();
723 	}
724     //-----------------------------------------------------------------------------
setBinding(unsigned short index,const HardwareVertexBufferSharedPtr & buffer)725 	void VertexBufferBinding::setBinding(unsigned short index, const HardwareVertexBufferSharedPtr& buffer)
726 	{
727         // NB will replace any existing buffer ptr at this index, and will thus cause
728         // reference count to decrement on that buffer (possibly destroying it)
729 		mBindingMap[index] = buffer;
730 		mHighIndex = std::max(mHighIndex, (unsigned short)(index+1));
731 	}
732     //-----------------------------------------------------------------------------
unsetBinding(unsigned short index)733 	void VertexBufferBinding::unsetBinding(unsigned short index)
734 	{
735 		VertexBufferBindingMap::iterator i = mBindingMap.find(index);
736 		if (i == mBindingMap.end())
737 		{
738 			OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
739 				"Cannot find buffer binding for index " + StringConverter::toString(index),
740 				"VertexBufferBinding::unsetBinding");
741 		}
742 		mBindingMap.erase(i);
743 	}
744     //-----------------------------------------------------------------------------
unsetAllBindings(void)745     void VertexBufferBinding::unsetAllBindings(void)
746     {
747         mBindingMap.clear();
748         mHighIndex = 0;
749     }
750     //-----------------------------------------------------------------------------
751 	const VertexBufferBinding::VertexBufferBindingMap&
getBindings(void) const752 	VertexBufferBinding::getBindings(void) const
753 	{
754 		return mBindingMap;
755 	}
756     //-----------------------------------------------------------------------------
getBuffer(unsigned short index) const757 	const HardwareVertexBufferSharedPtr& VertexBufferBinding::getBuffer(unsigned short index) const
758 	{
759 		VertexBufferBindingMap::const_iterator i = mBindingMap.find(index);
760 		if (i == mBindingMap.end())
761 		{
762 			OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No buffer is bound to that index.",
763 				"VertexBufferBinding::getBuffer");
764 		}
765 		return i->second;
766 	}
767 	//-----------------------------------------------------------------------------
isBufferBound(unsigned short index) const768 	bool VertexBufferBinding::isBufferBound(unsigned short index) const
769 	{
770 		return mBindingMap.find(index) != mBindingMap.end();
771 	}
772     //-----------------------------------------------------------------------------
getLastBoundIndex(void) const773     unsigned short VertexBufferBinding::getLastBoundIndex(void) const
774     {
775         return mBindingMap.empty() ? 0 : mBindingMap.rbegin()->first + 1;
776     }
777     //-----------------------------------------------------------------------------
hasGaps(void) const778     bool VertexBufferBinding::hasGaps(void) const
779     {
780         if (mBindingMap.empty())
781             return false;
782         if (mBindingMap.rbegin()->first + 1 == (int) mBindingMap.size())
783             return false;
784         return true;
785     }
786     //-----------------------------------------------------------------------------
closeGaps(BindingIndexMap & bindingIndexMap)787     void VertexBufferBinding::closeGaps(BindingIndexMap& bindingIndexMap)
788     {
789         bindingIndexMap.clear();
790 
791         VertexBufferBindingMap newBindingMap;
792 
793         VertexBufferBindingMap::const_iterator it;
794         ushort targetIndex = 0;
795         for (it = mBindingMap.begin(); it != mBindingMap.end(); ++it, ++targetIndex)
796         {
797             bindingIndexMap[it->first] = targetIndex;
798             newBindingMap[targetIndex] = it->second;
799         }
800 
801         mBindingMap.swap(newBindingMap);
802         mHighIndex = targetIndex;
803     }
804     //-----------------------------------------------------------------------------
hasInstanceData() const805     bool VertexBufferBinding::hasInstanceData() const
806     {
807 		VertexBufferBinding::VertexBufferBindingMap::const_iterator i, iend;
808 		iend = mBindingMap.end();
809 		for (i = mBindingMap.begin(); i != iend; ++i)
810 		{
811 			if ( i->second->isInstanceData() )
812             {
813                 return true;
814             }
815         }
816         return false;
817     }
818     //-----------------------------------------------------------------------------
HardwareVertexBufferSharedPtr(HardwareVertexBuffer * buf)819     HardwareVertexBufferSharedPtr::HardwareVertexBufferSharedPtr(HardwareVertexBuffer* buf)
820         : SharedPtr<HardwareVertexBuffer>(buf)
821     {
822 
823     }
824 
825 
826 
827 
828 }
829