source: OGRE/trunk/ogrenew/OgreMain/src/OgreHardwareVertexBuffer.cpp @ 692

Revision 692, 19.6 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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