Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreHardwareVertexBuffer.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2002 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #include "OgreStableHeaders.h"
00026 #include "OgreHardwareVertexBuffer.h"
00027 #include "OgreColourValue.h"
00028 #include "OgreException.h"
00029 #include "OgreStringConverter.h"
00030 #include "OgreHardwareBufferManager.h"
00031 #include "OgreDefaultHardwareBufferManager.h"
00032 
00033 namespace Ogre {
00034 
00035     //-----------------------------------------------------------------------------
00036     HardwareVertexBuffer::HardwareVertexBuffer(size_t vertexSize,  
00037         size_t numVertices, HardwareBuffer::Usage usage, 
00038         bool useSystemMemory, bool useShadowBuffer) 
00039         : HardwareBuffer(usage, useSystemMemory, useShadowBuffer), 
00040           mNumVertices(numVertices),
00041           mVertexSize(vertexSize)
00042     {
00043         // Calculate the size of the vertices
00044         mSizeInBytes = mVertexSize * numVertices;
00045 
00046         // Create a shadow buffer if required
00047         if (mUseShadowBuffer)
00048         {
00049             mpShadowBuffer = new DefaultHardwareVertexBuffer(mVertexSize, 
00050                     mNumVertices, HardwareBuffer::HBU_DYNAMIC);
00051         }
00052 
00053     }
00054     //-----------------------------------------------------------------------------
00055     HardwareVertexBuffer::~HardwareVertexBuffer()
00056     {
00057         if (mpShadowBuffer)
00058         {
00059             delete mpShadowBuffer;
00060         }
00061     }
00062     //-----------------------------------------------------------------------------
00063     VertexElement::VertexElement(unsigned short source, size_t offset, 
00064         VertexElementType theType, VertexElementSemantic semantic, unsigned short index)
00065         : mSource(source), mOffset(offset), mType(theType), 
00066         mSemantic(semantic), mIndex(index)
00067     {
00068     }
00069     //-----------------------------------------------------------------------------
00070     size_t VertexElement::getSize(void) const
00071     {
00072         return getTypeSize(mType);
00073     }
00074     //-----------------------------------------------------------------------------
00075     size_t VertexElement::getTypeSize(VertexElementType etype)
00076     {
00077         switch(etype)
00078         {
00079         case VET_COLOUR:
00080             return sizeof(RGBA);
00081         case VET_FLOAT1:
00082             return sizeof(float);
00083         case VET_FLOAT2:
00084             return sizeof(float)*2;
00085         case VET_FLOAT3:
00086             return sizeof(float)*3;
00087         case VET_FLOAT4:
00088             return sizeof(float)*4;
00089         case VET_SHORT1:
00090             return sizeof(short);
00091         case VET_SHORT2:
00092             return sizeof(short)*2;
00093         case VET_SHORT3:
00094             return sizeof(short)*3;
00095         case VET_SHORT4:
00096             return sizeof(short)*4;
00097         case VET_UBYTE4:
00098             return sizeof(unsigned char)*4;
00099         }
00100         return 0;
00101     }
00102     //-----------------------------------------------------------------------------
00103     unsigned short VertexElement::getTypeCount(VertexElementType etype)
00104     {
00105         switch (etype)
00106         {
00107         case VET_COLOUR:
00108             return 1;
00109         case VET_FLOAT1:
00110             return 1;
00111         case VET_FLOAT2:
00112             return 2;
00113         case VET_FLOAT3:
00114             return 3;
00115         case VET_FLOAT4:
00116             return 4;
00117         case VET_SHORT1:
00118             return 1;
00119         case VET_SHORT2:
00120             return 2;
00121         case VET_SHORT3:
00122             return 3;
00123         case VET_SHORT4:
00124             return 4;
00125         case VET_UBYTE4:
00126             return 4;
00127         }
00128         Except(Exception::ERR_INVALIDPARAMS, "Invalid type", 
00129             "VertexElement::getTypeCount");
00130     }
00131     //-----------------------------------------------------------------------------
00132     VertexElementType VertexElement::multiplyTypeCount(VertexElementType baseType, 
00133         unsigned short count)
00134     {
00135         switch (baseType)
00136         {
00137         case VET_FLOAT1:
00138             switch(count)
00139             {
00140             case 1:
00141                 return VET_FLOAT1;
00142             case 2:
00143                 return VET_FLOAT2;
00144             case 3:
00145                 return VET_FLOAT3;
00146             case 4:
00147                 return VET_FLOAT4;
00148             default:
00149                 break;
00150             }
00151             break;
00152         case VET_SHORT1:
00153             switch(count)
00154             {
00155             case 1:
00156                 return VET_SHORT1;
00157             case 2:
00158                 return VET_SHORT2;
00159             case 3:
00160                 return VET_SHORT3;
00161             case 4:
00162                 return VET_SHORT4;
00163             default:
00164                 break;
00165             }
00166             break;
00167         default:
00168             break;
00169         }
00170         Except(Exception::ERR_INVALIDPARAMS, "Invalid base type", 
00171             "VertexElement::multiplyTypeCount");
00172     }
00173     //-----------------------------------------------------------------------------
00174     VertexElementType VertexElement::getBaseType(VertexElementType multiType)
00175     {
00176         switch (multiType)
00177         {
00178             case VET_FLOAT1:
00179             case VET_FLOAT2:
00180             case VET_FLOAT3:
00181             case VET_FLOAT4:
00182                 return VET_FLOAT1;
00183             case VET_COLOUR:
00184                 return VET_COLOUR;
00185             case VET_SHORT1:
00186             case VET_SHORT2:
00187             case VET_SHORT3:
00188             case VET_SHORT4:
00189                 return VET_SHORT1;
00190             case VET_UBYTE4:
00191                 return VET_UBYTE4;
00192         };
00193         // To keep compiler happy
00194         return VET_FLOAT1;
00195     }
00196     //-----------------------------------------------------------------------------
00197     VertexDeclaration::VertexDeclaration()
00198     {
00199     }
00200     //-----------------------------------------------------------------------------
00201     VertexDeclaration::~VertexDeclaration()
00202     {
00203     }
00204     //-----------------------------------------------------------------------------
00205     const VertexDeclaration::VertexElementList& VertexDeclaration::getElements(void) const
00206     {
00207         return mElementList;
00208     }
00209     //-----------------------------------------------------------------------------
00210     const VertexElement& VertexDeclaration::addElement(unsigned short source, 
00211         size_t offset, VertexElementType theType,
00212         VertexElementSemantic semantic, unsigned short index)
00213     {
00214         mElementList.push_back(
00215             VertexElement(source, offset, theType, semantic, index)
00216             );
00217         return mElementList.back();
00218     }
00219     //-----------------------------------------------------------------------------
00220     const VertexElement& VertexDeclaration::insertElement(unsigned short atPosition,
00221         unsigned short source, size_t offset, VertexElementType theType,
00222         VertexElementSemantic semantic, unsigned short index)
00223     {
00224         if (atPosition >= mElementList.size())
00225         {
00226             return addElement(source, offset, theType, semantic, index);
00227         }
00228 
00229         VertexElementList::iterator i = mElementList.begin();
00230         for (unsigned short n = 0; n < atPosition; ++n)
00231             ++i;
00232 
00233         i = mElementList.insert(i, 
00234             VertexElement(source, offset, theType, semantic, index));
00235         return *i;
00236 
00237     }
00238     //-----------------------------------------------------------------------------
00239     const VertexElement* VertexDeclaration::getElement(unsigned short index)
00240     {
00241         assert(index < mElementList.size() && "Index out of bounds");
00242 
00243         VertexElementList::iterator i = mElementList.begin();
00244         for (unsigned short n = 0; n < index; ++n)
00245             ++i;
00246 
00247         return &(*i);
00248 
00249     }
00250     //-----------------------------------------------------------------------------
00251     void VertexDeclaration::removeElement(unsigned short elem_index)
00252     {
00253         assert(elem_index < mElementList.size() && "Index out of bounds");
00254         VertexElementList::iterator i = mElementList.begin();
00255         for (unsigned short n = 0; n < elem_index; ++n)
00256             ++i;
00257         mElementList.erase(i);
00258     }
00259     //-----------------------------------------------------------------------------
00260     void VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index)
00261     {
00262         VertexElementList::iterator ei, eiend;
00263         eiend = mElementList.end();
00264         for (ei = mElementList.begin(); ei != eiend; ++ei)
00265         {
00266             if (ei->getSemantic() == semantic && ei->getIndex() == index)
00267             {
00268                 mElementList.erase(ei);
00269                 break;
00270             }
00271         }
00272     }
00273     //-----------------------------------------------------------------------------
00274     void VertexDeclaration::modifyElement(unsigned short elem_index, 
00275         unsigned short source, size_t offset, VertexElementType theType,
00276         VertexElementSemantic semantic, unsigned short index)
00277     {
00278         assert(elem_index < mElementList.size() && "Index out of bounds");
00279         VertexElementList::iterator i = mElementList.begin();
00280         std::advance(i, elem_index);
00281         (*i) = VertexElement(source, offset, theType, semantic, index);
00282     }
00283     //-----------------------------------------------------------------------------
00284     const VertexElement* VertexDeclaration::findElementBySemantic(
00285         VertexElementSemantic sem, unsigned short index)
00286     {
00287         VertexElementList::const_iterator ei, eiend;
00288         eiend = mElementList.end();
00289         for (ei = mElementList.begin(); ei != eiend; ++ei)
00290         {
00291             if (ei->getSemantic() == sem && ei->getIndex() == index)
00292             {
00293                 return &(*ei);
00294             }
00295         }
00296 
00297         return NULL;
00298 
00299 
00300     }
00301     //-----------------------------------------------------------------------------
00302     VertexDeclaration::VertexElementList VertexDeclaration::findElementsBySource(
00303         unsigned short source)
00304     {
00305         VertexElementList retList;
00306         VertexElementList::const_iterator ei, eiend;
00307         eiend = mElementList.end();
00308         for (ei = mElementList.begin(); ei != eiend; ++ei)
00309         {
00310             if (ei->getSource() == source)
00311             {
00312                 retList.push_back(*ei);
00313             }
00314         }
00315         return retList;
00316 
00317     }
00318 
00319     //-----------------------------------------------------------------------------
00320     size_t VertexDeclaration::getVertexSize(unsigned short source)
00321     {
00322         VertexElementList::const_iterator i, iend;
00323         iend = mElementList.end();
00324         size_t sz = 0;
00325 
00326         for (i = mElementList.begin(); i != iend; ++i)
00327         {
00328             if (i->getSource() == source)
00329             {
00330                 sz += i->getSize();
00331 
00332             }
00333         }
00334         return sz;
00335     }
00336     //-----------------------------------------------------------------------------
00337     VertexDeclaration* VertexDeclaration::clone(void)
00338     {
00339         VertexDeclaration* ret = HardwareBufferManager::getSingleton().createVertexDeclaration();
00340 
00341         VertexElementList::const_iterator i, iend;
00342         iend = mElementList.end();
00343         for (i = mElementList.begin(); i != iend; ++i)
00344         {
00345             ret->addElement(i->getSource(), i->getOffset(), i->getType(), i->getSemantic(), i->getIndex());
00346         }
00347         return ret;
00348     }
00349     //-----------------------------------------------------------------------------
00350     // Sort routine for VertexElement
00351     bool VertexDeclaration::vertexElementLess(const VertexElement& e1, const VertexElement& e2)
00352     {
00353         // Sort by source first
00354         if (e1.getSource() < e2.getSource())
00355         {
00356             return true;
00357         }
00358         else if (e1.getSource() == e2.getSource())
00359         {
00360             // Use ordering of semantics to sort
00361             if (e1.getSemantic() < e2.getSemantic())
00362             {
00363                 return true;
00364             }
00365             else if (e1.getSemantic() == e2.getSemantic())
00366             {
00367                 // Use index to sort
00368                 if (e1.getIndex() < e2.getIndex())
00369                 {
00370                     return true;
00371                 }
00372             }
00373         }
00374         return false;
00375     }
00376     void VertexDeclaration::sort(void)
00377     {
00378         mElementList.sort(VertexDeclaration::vertexElementLess);
00379     }
00380     //-----------------------------------------------------------------------------
00381     void VertexDeclaration::closeGapsInSource(void)
00382     {
00383         if (mElementList.empty())
00384             return;
00385 
00386         // Sort first
00387         sort();
00388 
00389         VertexElementList::iterator i, iend;
00390         iend = mElementList.end();
00391         unsigned short targetIdx = 0;
00392         unsigned short lastIdx = getElement(0)->getSource();
00393         unsigned short c = 0;
00394         for (i = mElementList.begin(); i != iend; ++i, ++c)
00395         {
00396             VertexElement& elem = *i;
00397             if (lastIdx != elem.getSource())
00398             {
00399                 targetIdx++;
00400                 lastIdx = elem.getSource();
00401             }
00402             if (targetIdx != elem.getSource())
00403             {
00404                 modifyElement(c, targetIdx, elem.getOffset(), elem.getType(), 
00405                     elem.getSemantic(), elem.getIndex());
00406             }
00407 
00408         }
00409 
00410     }
00411     //-----------------------------------------------------------------------
00412     VertexDeclaration* VertexDeclaration::getAutoOrganisedDeclaration(bool animated)
00413     {
00414         VertexDeclaration* newDecl = this->clone();
00415         // Set all sources to the same buffer (for now)
00416         const VertexDeclaration::VertexElementList& elems = newDecl->getElements();
00417         VertexDeclaration::VertexElementList::const_iterator i;
00418         unsigned short c = 0;
00419         for (i = elems.begin(); i != elems.end(); ++i, ++c)
00420         {
00421             const VertexElement& elem = *i;
00422             // Set source & offset to 0 for now, before sort
00423             newDecl->modifyElement(c, 0, 0, elem.getType(), elem.getSemantic(), elem.getIndex());
00424         }
00425         newDecl->sort();
00426         // Now sort out proper buffer assignments and offsets
00427         size_t offset0 = 0;
00428         size_t offset1 = 0;
00429         c = 0;
00430         for (i = elems.begin(); i != elems.end(); ++i, ++c)
00431         {
00432             const VertexElement& elem = *i;
00433             if (animated && 
00434                 elem.getSemantic() != VES_POSITION && elem.getSemantic() != VES_NORMAL)
00435             {
00436                 // Animated meshes have pos & norm in buffer 0, everything else in 1
00437                 newDecl->modifyElement(c, 1, offset1, elem.getType(), elem.getSemantic(), elem.getIndex());
00438                 offset1 += elem.getSize();
00439             }
00440             else
00441             {
00442                 newDecl->modifyElement(c, 0, offset0, elem.getType(), elem.getSemantic(), elem.getIndex());
00443                 offset0 += elem.getSize();
00444             }
00445         }
00446 
00447         return newDecl;
00448 
00449 
00450     }
00451     //-----------------------------------------------------------------------------
00452     unsigned short VertexDeclaration::getMaxSource(void) const
00453     {
00454         VertexElementList::const_iterator i, iend;
00455         iend = mElementList.end();
00456         unsigned short ret = 0;
00457         for (i = mElementList.begin(); i != iend; ++i)
00458         {
00459             if (i->getSource() > ret)
00460             {
00461                 ret = i->getSource();
00462             }
00463 
00464         }
00465         return ret;
00466     }
00467     //-----------------------------------------------------------------------------
00468     VertexBufferBinding::VertexBufferBinding() : mHighIndex(0)
00469     {
00470     }
00471     //-----------------------------------------------------------------------------
00472     VertexBufferBinding::~VertexBufferBinding()
00473     {
00474         unsetAllBindings();
00475     }
00476     //-----------------------------------------------------------------------------
00477     void VertexBufferBinding::setBinding(unsigned short index, HardwareVertexBufferSharedPtr buffer)
00478     {
00479         // NB will replace any existing buffer ptr at this index, and will thus cause
00480         // reference count to decrement on that buffer (possibly destroying it)
00481         mBindingMap[index] = buffer;
00482         mHighIndex = std::max(mHighIndex, (unsigned short)(index+1));
00483     }
00484     //-----------------------------------------------------------------------------
00485     void VertexBufferBinding::unsetBinding(unsigned short index)
00486     {
00487         VertexBufferBindingMap::iterator i = mBindingMap.find(index);
00488         if (i == mBindingMap.end())
00489         {
00490             Except(Exception::ERR_ITEM_NOT_FOUND,
00491                 "Cannot find buffer binding for index " + StringConverter::toString(index),
00492                 "VertexBufferBinding::unsetBinding");
00493         }
00494         mBindingMap.erase(i);
00495     }
00496     //-----------------------------------------------------------------------------
00497     void VertexBufferBinding::unsetAllBindings(void)
00498     {
00499         mBindingMap.clear();
00500     }
00501     //-----------------------------------------------------------------------------
00502     const VertexBufferBinding::VertexBufferBindingMap& 
00503     VertexBufferBinding::getBindings(void) const
00504     {
00505         return mBindingMap;
00506     }
00507     //-----------------------------------------------------------------------------
00508     HardwareVertexBufferSharedPtr VertexBufferBinding::getBuffer(unsigned short index)
00509     {
00510         VertexBufferBindingMap::iterator i = mBindingMap.find(index);
00511         if (i == mBindingMap.end())
00512         {
00513             Except(Exception::ERR_ITEM_NOT_FOUND, "No buffer is bound to that index.",
00514                 "VertexBufferBinding::getBuffer");
00515         }
00516         return i->second;
00517     }
00518     //-----------------------------------------------------------------------------
00519     HardwareVertexBufferSharedPtr::HardwareVertexBufferSharedPtr(HardwareVertexBuffer* buf)
00520         : SharedPtr<HardwareVertexBuffer>(buf)
00521     {
00522 
00523     }
00524 
00525 
00526 
00527 
00528 }

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:29 2004