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

Revision 690, 17.3 KB checked in by mattausch, 18 years ago (diff)

added ogre 1.07 main

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