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