Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreHardwareVertexBuffer.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 22.1 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30#include "OgreHardwareVertexBuffer.h"
31#include "OgreColourValue.h"
32#include "OgreException.h"
33#include "OgreStringConverter.h"
34#include "OgreHardwareBufferManager.h"
35#include "OgreDefaultHardwareBufferManager.h"
36#include "OgreRoot.h"
37#include "OgreRenderSystem.h"
38
39namespace Ogre {
40
41    //-----------------------------------------------------------------------------
42    HardwareVertexBuffer::HardwareVertexBuffer(size_t vertexSize, 
43        size_t numVertices, HardwareBuffer::Usage usage, 
44        bool useSystemMemory, bool useShadowBuffer) 
45        : HardwareBuffer(usage, useSystemMemory, useShadowBuffer), 
46          mNumVertices(numVertices),
47          mVertexSize(vertexSize)
48    {
49        // Calculate the size of the vertices
50        mSizeInBytes = mVertexSize * numVertices;
51
52        // Create a shadow buffer if required
53        if (mUseShadowBuffer)
54        {
55            mpShadowBuffer = new DefaultHardwareVertexBuffer(mVertexSize, 
56                    mNumVertices, HardwareBuffer::HBU_DYNAMIC);
57        }
58
59    }
60    //-----------------------------------------------------------------------------
61    HardwareVertexBuffer::~HardwareVertexBuffer()
62    {
63                HardwareBufferManager* mgr = HardwareBufferManager::getSingletonPtr();
64                if (mgr)
65                {
66                        mgr->_notifyVertexBufferDestroyed(this);
67                }
68        if (mpShadowBuffer)
69        {
70            delete mpShadowBuffer;
71        }
72    }
73    //-----------------------------------------------------------------------------
74    VertexElement::VertexElement(unsigned short source, size_t offset, 
75        VertexElementType theType, VertexElementSemantic semantic, unsigned short index)
76        : mSource(source), mOffset(offset), mType(theType), 
77        mSemantic(semantic), mIndex(index)
78    {
79    }
80    //-----------------------------------------------------------------------------
81        size_t VertexElement::getSize(void) const
82        {
83                return getTypeSize(mType);
84        }
85        //-----------------------------------------------------------------------------
86        size_t VertexElement::getTypeSize(VertexElementType etype)
87        {
88                switch(etype)
89                {
90                case VET_COLOUR:
91                case VET_COLOUR_ABGR:
92                case VET_COLOUR_ARGB:
93                        return sizeof(RGBA);
94                case VET_FLOAT1:
95                        return sizeof(float);
96                case VET_FLOAT2:
97                        return sizeof(float)*2;
98                case VET_FLOAT3:
99                        return sizeof(float)*3;
100                case VET_FLOAT4:
101                        return sizeof(float)*4;
102                case VET_SHORT1:
103                        return sizeof(short);
104                case VET_SHORT2:
105                        return sizeof(short)*2;
106                case VET_SHORT3:
107                        return sizeof(short)*3;
108                case VET_SHORT4:
109                        return sizeof(short)*4;
110        case VET_UBYTE4:
111            return sizeof(unsigned char)*4;
112                }
113                return 0;
114        }
115        //-----------------------------------------------------------------------------
116        unsigned short VertexElement::getTypeCount(VertexElementType etype)
117        {
118                switch (etype)
119                {
120                case VET_COLOUR:
121                case VET_COLOUR_ABGR:
122                case VET_COLOUR_ARGB:
123                        return 1;
124                case VET_FLOAT1:
125                        return 1;
126                case VET_FLOAT2:
127                        return 2;
128                case VET_FLOAT3:
129                        return 3;
130                case VET_FLOAT4:
131                        return 4;
132                case VET_SHORT1:
133                        return 1;
134                case VET_SHORT2:
135                        return 2;
136                case VET_SHORT3:
137                        return 3;
138                case VET_SHORT4:
139                        return 4;
140        case VET_UBYTE4:
141            return 4;
142                }
143                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid type", 
144                        "VertexElement::getTypeCount");
145        }
146        //-----------------------------------------------------------------------------
147        VertexElementType VertexElement::multiplyTypeCount(VertexElementType baseType, 
148                unsigned short count)
149        {
150                switch (baseType)
151                {
152                case VET_FLOAT1:
153                        switch(count)
154                        {
155                        case 1:
156                                return VET_FLOAT1;
157                        case 2:
158                                return VET_FLOAT2;
159                        case 3:
160                                return VET_FLOAT3;
161                        case 4:
162                                return VET_FLOAT4;
163            default:
164                break;
165                        }
166                        break;
167                case VET_SHORT1:
168                        switch(count)
169                        {
170                        case 1:
171                                return VET_SHORT1;
172                        case 2:
173                                return VET_SHORT2;
174                        case 3:
175                                return VET_SHORT3;
176                        case 4:
177                                return VET_SHORT4;
178            default:
179                break;
180                        }
181                        break;
182        default:
183            break;
184                }
185                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid base type", 
186                        "VertexElement::multiplyTypeCount");
187        }
188        //--------------------------------------------------------------------------
189        VertexElementType VertexElement::getBestColourVertexElementType(void)
190        {
191                // Use the current render system to determine if possible
192                if (Root::getSingletonPtr() && Root::getSingletonPtr()->getRenderSystem())
193                {
194                        return Root::getSingleton().getRenderSystem()->getColourVertexElementType();
195                }
196                else
197                {
198                        // We can't know the specific type right now, so pick a type
199                        // based on platform
200#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
201                        return VET_COLOUR_ARGB; // prefer D3D format on windows
202#else
203                        return VET_COLOUR_ABGR; // prefer GL format on everything else
204#endif
205
206                }
207        }
208        //--------------------------------------------------------------------------
209        void VertexElement::convertColourValue(VertexElementType srcType, 
210                VertexElementType dstType, uint32* ptr)
211        {
212                if (srcType == dstType)
213                        return;
214
215                // Conversion between ARGB and ABGR is always a case of flipping R/B
216                *ptr = 
217                   ((*ptr&0x00FF0000)>>16)|((*ptr&0x000000FF)<<16)|(*ptr&0xFF00FF00);                           
218        }
219        //--------------------------------------------------------------------------
220        uint32 VertexElement::convertColourValue(const ColourValue& src, 
221                VertexElementType dst)
222        {
223                switch(dst)
224                {
225#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
226        default:
227#endif
228                case VET_COLOUR_ARGB:
229                        return src.getAsARGB();
230#if OGRE_PLATFORM != OGRE_PLATFORM_WIN32
231        default:
232#endif
233                case VET_COLOUR_ABGR: 
234                        return src.getAsABGR();
235                };
236
237        }
238        //-----------------------------------------------------------------------------
239        VertexElementType VertexElement::getBaseType(VertexElementType multiType)
240        {
241                switch (multiType)
242                {
243                        case VET_FLOAT1:
244                        case VET_FLOAT2:
245                        case VET_FLOAT3:
246                        case VET_FLOAT4:
247                                return VET_FLOAT1;
248                        case VET_COLOUR:
249                                return VET_COLOUR;
250                        case VET_COLOUR_ABGR:
251                                return VET_COLOUR_ABGR;
252                        case VET_COLOUR_ARGB:
253                                return VET_COLOUR_ARGB;
254                        case VET_SHORT1:
255                        case VET_SHORT2:
256                        case VET_SHORT3:
257                        case VET_SHORT4:
258                                return VET_SHORT1;
259                        case VET_UBYTE4:
260                                return VET_UBYTE4;
261                };
262        // To keep compiler happy
263        return VET_FLOAT1;
264        }
265        //-----------------------------------------------------------------------------
266    VertexDeclaration::VertexDeclaration()
267    {
268    }
269    //-----------------------------------------------------------------------------
270    VertexDeclaration::~VertexDeclaration()
271    {
272    }
273    //-----------------------------------------------------------------------------
274    const VertexDeclaration::VertexElementList& VertexDeclaration::getElements(void) const
275    {
276        return mElementList;
277    }
278    //-----------------------------------------------------------------------------
279    const VertexElement& VertexDeclaration::addElement(unsigned short source, 
280        size_t offset, VertexElementType theType,
281        VertexElementSemantic semantic, unsigned short index)
282    {
283                // Refine colour type to a specific type
284                if (theType == VET_COLOUR)
285                {
286                        theType = VertexElement::getBestColourVertexElementType();
287                }
288        mElementList.push_back(
289            VertexElement(source, offset, theType, semantic, index)
290            );
291                return mElementList.back();
292    }
293    //-----------------------------------------------------------------------------
294    const VertexElement& VertexDeclaration::insertElement(unsigned short atPosition,
295        unsigned short source, size_t offset, VertexElementType theType,
296        VertexElementSemantic semantic, unsigned short index)
297    {
298        if (atPosition >= mElementList.size())
299        {
300            return addElement(source, offset, theType, semantic, index);
301        }
302
303        VertexElementList::iterator i = mElementList.begin();
304        for (unsigned short n = 0; n < atPosition; ++n)
305            ++i;
306
307        i = mElementList.insert(i, 
308            VertexElement(source, offset, theType, semantic, index));
309        return *i;
310
311    }
312    //-----------------------------------------------------------------------------
313    const VertexElement* VertexDeclaration::getElement(unsigned short index)
314    {
315        assert(index < mElementList.size() && "Index out of bounds");
316
317        VertexElementList::iterator i = mElementList.begin();
318        for (unsigned short n = 0; n < index; ++n)
319            ++i;
320
321        return &(*i);
322
323    }
324    //-----------------------------------------------------------------------------
325    void VertexDeclaration::removeElement(unsigned short elem_index)
326    {
327        assert(elem_index < mElementList.size() && "Index out of bounds");
328        VertexElementList::iterator i = mElementList.begin();
329        for (unsigned short n = 0; n < elem_index; ++n)
330            ++i;
331        mElementList.erase(i);
332    }
333    //-----------------------------------------------------------------------------
334    void VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index)
335    {
336                VertexElementList::iterator ei, eiend;
337                eiend = mElementList.end();
338                for (ei = mElementList.begin(); ei != eiend; ++ei)
339                {
340                        if (ei->getSemantic() == semantic && ei->getIndex() == index)
341                        {
342                                mElementList.erase(ei);
343                break;
344                        }
345                }
346    }
347        //-----------------------------------------------------------------------------
348        void VertexDeclaration::removeAllElements(void)
349        {
350                mElementList.clear();
351        }
352    //-----------------------------------------------------------------------------
353    void VertexDeclaration::modifyElement(unsigned short elem_index, 
354        unsigned short source, size_t offset, VertexElementType theType,
355        VertexElementSemantic semantic, unsigned short index)
356    {
357        assert(elem_index < mElementList.size() && "Index out of bounds");
358        VertexElementList::iterator i = mElementList.begin();
359        std::advance(i, elem_index);
360        (*i) = VertexElement(source, offset, theType, semantic, index);
361    }
362    //-----------------------------------------------------------------------------
363        const VertexElement* VertexDeclaration::findElementBySemantic(
364                VertexElementSemantic sem, unsigned short index)
365        {
366                VertexElementList::const_iterator ei, eiend;
367                eiend = mElementList.end();
368                for (ei = mElementList.begin(); ei != eiend; ++ei)
369                {
370                        if (ei->getSemantic() == sem && ei->getIndex() == index)
371                        {
372                                return &(*ei);
373                        }
374                }
375
376                return NULL;
377
378
379        }
380        //-----------------------------------------------------------------------------
381        VertexDeclaration::VertexElementList VertexDeclaration::findElementsBySource(
382                unsigned short source)
383        {
384                VertexElementList retList;
385                VertexElementList::const_iterator ei, eiend;
386                eiend = mElementList.end();
387                for (ei = mElementList.begin(); ei != eiend; ++ei)
388                {
389                        if (ei->getSource() == source)
390                        {
391                                retList.push_back(*ei);
392                        }
393                }
394                return retList;
395
396        }
397
398        //-----------------------------------------------------------------------------
399        size_t VertexDeclaration::getVertexSize(unsigned short source)
400        {
401                VertexElementList::const_iterator i, iend;
402                iend = mElementList.end();
403                size_t sz = 0;
404
405                for (i = mElementList.begin(); i != iend; ++i)
406                {
407                        if (i->getSource() == source)
408                        {
409                                sz += i->getSize();
410
411                        }
412                }
413                return sz;
414        }
415    //-----------------------------------------------------------------------------
416    VertexDeclaration* VertexDeclaration::clone(void)
417    {
418        VertexDeclaration* ret = HardwareBufferManager::getSingleton().createVertexDeclaration();
419
420                VertexElementList::const_iterator i, iend;
421                iend = mElementList.end();
422                for (i = mElementList.begin(); i != iend; ++i)
423                {
424            ret->addElement(i->getSource(), i->getOffset(), i->getType(), i->getSemantic(), i->getIndex());
425        }
426        return ret;
427    }
428    //-----------------------------------------------------------------------------
429    // Sort routine for VertexElement
430    bool VertexDeclaration::vertexElementLess(const VertexElement& e1, const VertexElement& e2)
431    {
432        // Sort by source first
433        if (e1.getSource() < e2.getSource())
434        {
435            return true;
436        }
437        else if (e1.getSource() == e2.getSource())
438        {
439            // Use ordering of semantics to sort
440            if (e1.getSemantic() < e2.getSemantic())
441            {
442                return true;
443            }
444            else if (e1.getSemantic() == e2.getSemantic())
445            {
446                // Use index to sort
447                if (e1.getIndex() < e2.getIndex())
448                {
449                    return true;
450                }
451            }
452        }
453        return false;
454    }
455    void VertexDeclaration::sort(void)
456    {
457        mElementList.sort(VertexDeclaration::vertexElementLess);
458    }
459    //-----------------------------------------------------------------------------
460    void VertexDeclaration::closeGapsInSource(void)
461    {
462        if (mElementList.empty())
463            return;
464
465        // Sort first
466        sort();
467
468        VertexElementList::iterator i, iend;
469        iend = mElementList.end();
470        unsigned short targetIdx = 0;
471        unsigned short lastIdx = getElement(0)->getSource();
472        unsigned short c = 0;
473        for (i = mElementList.begin(); i != iend; ++i, ++c)
474        {
475            VertexElement& elem = *i;
476            if (lastIdx != elem.getSource())
477            {
478                targetIdx++;
479                lastIdx = elem.getSource();
480            }
481            if (targetIdx != elem.getSource())
482            {
483                modifyElement(c, targetIdx, elem.getOffset(), elem.getType(), 
484                    elem.getSemantic(), elem.getIndex());
485            }
486
487        }
488
489    }
490    //-----------------------------------------------------------------------
491    VertexDeclaration* VertexDeclaration::getAutoOrganisedDeclaration(
492                bool skeletalAnimation, bool vertexAnimation)
493    {
494        VertexDeclaration* newDecl = this->clone();
495        // Set all sources to the same buffer (for now)
496        const VertexDeclaration::VertexElementList& elems = newDecl->getElements();
497        VertexDeclaration::VertexElementList::const_iterator i;
498        unsigned short c = 0;
499        for (i = elems.begin(); i != elems.end(); ++i, ++c)
500        {
501            const VertexElement& elem = *i;
502            // Set source & offset to 0 for now, before sort
503            newDecl->modifyElement(c, 0, 0, elem.getType(), elem.getSemantic(), elem.getIndex());
504        }
505        newDecl->sort();
506        // Now sort out proper buffer assignments and offsets
507        size_t offset = 0;
508        c = 0;
509                unsigned short buffer = 0;
510        VertexElementSemantic prevSemantic = VES_POSITION;
511        for (i = elems.begin(); i != elems.end(); ++i, ++c)
512        {
513            const VertexElement& elem = *i;
514
515            bool splitWithPrev = false;
516            bool splitWithNext = false;
517            switch (elem.getSemantic())
518            {
519            case VES_POSITION:
520                // For morph animation, we need positions on their own
521                splitWithPrev = vertexAnimation;
522                splitWithNext = vertexAnimation;
523                break;
524            case VES_NORMAL:
525                // Normals can't sharing with blend weights/indices
526                splitWithPrev = (prevSemantic == VES_BLEND_WEIGHTS || prevSemantic == VES_BLEND_INDICES);
527                // All animated meshes have to split after normal
528                splitWithNext = (skeletalAnimation || vertexAnimation);
529                break;
530            case VES_BLEND_WEIGHTS:
531                // Blend weights/indices can be sharing with their own buffer only
532                splitWithPrev = true;
533                break;
534            case VES_BLEND_INDICES:
535                // Blend weights/indices can be sharing with their own buffer only
536                splitWithNext = true;
537                break;
538            }
539
540            if (splitWithPrev && offset)
541            {
542                ++buffer;
543                offset = 0;
544            }
545
546            prevSemantic = elem.getSemantic();
547            newDecl->modifyElement(c, buffer, offset,
548                elem.getType(), elem.getSemantic(), elem.getIndex());
549
550            if (splitWithNext)
551            {
552                ++buffer;
553                offset = 0;
554            }
555            else
556            {
557                offset += elem.getSize();
558            }
559        }
560
561        return newDecl;
562
563
564    }
565    //-----------------------------------------------------------------------------
566    unsigned short VertexDeclaration::getMaxSource(void) const
567    {
568        VertexElementList::const_iterator i, iend;
569        iend = mElementList.end();
570        unsigned short ret = 0;
571        for (i = mElementList.begin(); i != iend; ++i)
572        {
573            if (i->getSource() > ret)
574            {
575                ret = i->getSource();
576            }
577
578        }
579        return ret;
580    }
581    //-----------------------------------------------------------------------------
582        VertexBufferBinding::VertexBufferBinding() : mHighIndex(0)
583        {
584        }
585    //-----------------------------------------------------------------------------
586        VertexBufferBinding::~VertexBufferBinding()
587        {
588        unsetAllBindings();
589        }
590    //-----------------------------------------------------------------------------
591        void VertexBufferBinding::setBinding(unsigned short index, const HardwareVertexBufferSharedPtr& buffer)
592        {
593        // NB will replace any existing buffer ptr at this index, and will thus cause
594        // reference count to decrement on that buffer (possibly destroying it)
595                mBindingMap[index] = buffer;
596                mHighIndex = std::max(mHighIndex, (unsigned short)(index+1));
597        }
598    //-----------------------------------------------------------------------------
599        void VertexBufferBinding::unsetBinding(unsigned short index)
600        {
601                VertexBufferBindingMap::iterator i = mBindingMap.find(index);
602                if (i == mBindingMap.end())
603                {
604                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
605                                "Cannot find buffer binding for index " + StringConverter::toString(index),
606                                "VertexBufferBinding::unsetBinding");
607                }
608                mBindingMap.erase(i);
609        }
610    //-----------------------------------------------------------------------------
611    void VertexBufferBinding::unsetAllBindings(void)
612    {
613        mBindingMap.clear();
614        mHighIndex = 0;
615    }
616    //-----------------------------------------------------------------------------
617        const VertexBufferBinding::VertexBufferBindingMap& 
618        VertexBufferBinding::getBindings(void) const
619        {
620                return mBindingMap;
621        }
622    //-----------------------------------------------------------------------------
623        const HardwareVertexBufferSharedPtr& VertexBufferBinding::getBuffer(unsigned short index) const
624        {
625                VertexBufferBindingMap::const_iterator i = mBindingMap.find(index);
626                if (i == mBindingMap.end())
627                {
628                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No buffer is bound to that index.",
629                                "VertexBufferBinding::getBuffer");
630                }
631                return i->second;
632        }
633        //-----------------------------------------------------------------------------
634        bool VertexBufferBinding::isBufferBound(unsigned short index) const
635        {
636                return mBindingMap.find(index) != mBindingMap.end();
637        }
638    //-----------------------------------------------------------------------------
639    unsigned short VertexBufferBinding::getLastBoundIndex(void) const
640    {
641        return mBindingMap.empty() ? 0 : mBindingMap.rbegin()->first + 1;
642    }
643    //-----------------------------------------------------------------------------
644    bool VertexBufferBinding::hasGaps(void) const
645    {
646        if (mBindingMap.empty())
647            return false;
648        if (mBindingMap.rbegin()->first + 1 == mBindingMap.size())
649            return false;
650        return true;
651    }
652    //-----------------------------------------------------------------------------
653    void VertexBufferBinding::closeGaps(BindingIndexMap& bindingIndexMap)
654    {
655        bindingIndexMap.clear();
656
657        VertexBufferBindingMap newBindingMap;
658
659        VertexBufferBindingMap::const_iterator it;
660        ushort targetIndex = 0;
661        for (it = mBindingMap.begin(); it != mBindingMap.end(); ++it, ++targetIndex)
662        {
663            bindingIndexMap[it->first] = targetIndex;
664            newBindingMap[targetIndex] = it->second;
665        }
666
667        mBindingMap.swap(newBindingMap);
668        mHighIndex = targetIndex;
669    }
670    //-----------------------------------------------------------------------------
671    HardwareVertexBufferSharedPtr::HardwareVertexBufferSharedPtr(HardwareVertexBuffer* buf)
672        : SharedPtr<HardwareVertexBuffer>(buf)
673    {
674
675    }
676
677
678
679
680}
Note: See TracBrowser for help on using the repository browser.