1 | /* |
---|
2 | ----------------------------------------------------------------------------- |
---|
3 | This source file is part of OGRE |
---|
4 | (Object-oriented Graphics Rendering Engine) |
---|
5 | For the latest info, see http://www.ogre3d.org/ |
---|
6 | |
---|
7 | Copyright (c) 2000-2013 Torus Knot Software Ltd |
---|
8 | |
---|
9 | Permission is hereby granted, free of charge, to any person obtaining a copy |
---|
10 | of this software and associated documentation files (the "Software"), to deal |
---|
11 | in the Software without restriction, including without limitation the rights |
---|
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
---|
13 | copies of the Software, and to permit persons to whom the Software is |
---|
14 | furnished to do so, subject to the following conditions: |
---|
15 | |
---|
16 | The above copyright notice and this permission notice shall be included in |
---|
17 | all copies or substantial portions of the Software. |
---|
18 | |
---|
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
---|
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
---|
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
---|
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
---|
25 | THE SOFTWARE. |
---|
26 | ----------------------------------------------------------------------------- |
---|
27 | */ |
---|
28 | #ifndef __HardwareVertexBuffer__ |
---|
29 | #define __HardwareVertexBuffer__ |
---|
30 | |
---|
31 | // Precompiler options |
---|
32 | #include "OgrePrerequisites.h" |
---|
33 | #include "OgreHardwareBuffer.h" |
---|
34 | #include "OgreSharedPtr.h" |
---|
35 | #include "OgreColourValue.h" |
---|
36 | #include "OgreHeaderPrefix.h" |
---|
37 | |
---|
38 | namespace Ogre { |
---|
39 | class HardwareBufferManagerBase; |
---|
40 | |
---|
41 | /** \addtogroup Core |
---|
42 | * @{ |
---|
43 | */ |
---|
44 | /** \addtogroup RenderSystem |
---|
45 | * @{ |
---|
46 | */ |
---|
47 | /** Specialisation of HardwareBuffer for a vertex buffer. */ |
---|
48 | class _OgreExport HardwareVertexBuffer : public HardwareBuffer |
---|
49 | { |
---|
50 | protected: |
---|
51 | |
---|
52 | HardwareBufferManagerBase* mMgr; |
---|
53 | size_t mNumVertices; |
---|
54 | size_t mVertexSize; |
---|
55 | bool mIsInstanceData; |
---|
56 | size_t mInstanceDataStepRate; |
---|
57 | /// Checks if vertex instance data is supported by the render system |
---|
58 | virtual bool checkIfVertexInstanceDataIsSupported(); |
---|
59 | |
---|
60 | public: |
---|
61 | /// Should be called by HardwareBufferManager |
---|
62 | HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, |
---|
63 | HardwareBuffer::Usage usage, bool useSystemMemory, bool useShadowBuffer); |
---|
64 | ~HardwareVertexBuffer(); |
---|
65 | /// Return the manager of this buffer, if any |
---|
66 | HardwareBufferManagerBase* getManager() const { return mMgr; } |
---|
67 | /// Gets the size in bytes of a single vertex in this buffer |
---|
68 | size_t getVertexSize(void) const { return mVertexSize; } |
---|
69 | /// Get the number of vertices in this buffer |
---|
70 | size_t getNumVertices(void) const { return mNumVertices; } |
---|
71 | /// Get if this vertex buffer is an "instance data" buffer (per instance) |
---|
72 | bool isInstanceData() const { return mIsInstanceData; } |
---|
73 | /// Set if this vertex buffer is an "instance data" buffer (per instance) |
---|
74 | void setIsInstanceData(const bool val); |
---|
75 | /// Get the number of instances to draw using the same per-instance data before advancing in the buffer by one element. |
---|
76 | size_t getInstanceDataStepRate() const; |
---|
77 | /// Set the number of instances to draw using the same per-instance data before advancing in the buffer by one element. |
---|
78 | void setInstanceDataStepRate(const size_t val); |
---|
79 | |
---|
80 | |
---|
81 | // NB subclasses should override lock, unlock, readData, writeData |
---|
82 | |
---|
83 | }; |
---|
84 | |
---|
85 | /** Shared pointer implementation used to share vertex buffers. */ |
---|
86 | class _OgreExport HardwareVertexBufferSharedPtr : public SharedPtr<HardwareVertexBuffer> |
---|
87 | { |
---|
88 | public: |
---|
89 | HardwareVertexBufferSharedPtr() : SharedPtr<HardwareVertexBuffer>() {} |
---|
90 | explicit HardwareVertexBufferSharedPtr(HardwareVertexBuffer* buf); |
---|
91 | |
---|
92 | |
---|
93 | }; |
---|
94 | |
---|
95 | /** Locking helper. */ |
---|
96 | typedef HardwareBufferLockGuard<HardwareVertexBufferSharedPtr> HardwareVertexBufferLockGuard; |
---|
97 | |
---|
98 | /// Vertex element semantics, used to identify the meaning of vertex buffer contents |
---|
99 | enum VertexElementSemantic { |
---|
100 | /// Position, 3 reals per vertex |
---|
101 | VES_POSITION = 1, |
---|
102 | /// Blending weights |
---|
103 | VES_BLEND_WEIGHTS = 2, |
---|
104 | /// Blending indices |
---|
105 | VES_BLEND_INDICES = 3, |
---|
106 | /// Normal, 3 reals per vertex |
---|
107 | VES_NORMAL = 4, |
---|
108 | /// Diffuse colours |
---|
109 | VES_DIFFUSE = 5, |
---|
110 | /// Specular colours |
---|
111 | VES_SPECULAR = 6, |
---|
112 | /// Texture coordinates |
---|
113 | VES_TEXTURE_COORDINATES = 7, |
---|
114 | /// Binormal (Y axis if normal is Z) |
---|
115 | VES_BINORMAL = 8, |
---|
116 | /// Tangent (X axis if normal is Z) |
---|
117 | VES_TANGENT = 9, |
---|
118 | /// The number of VertexElementSemantic elements (note - the first value VES_POSITION is 1) |
---|
119 | VES_COUNT = 9 |
---|
120 | }; |
---|
121 | |
---|
122 | /// Vertex element type, used to identify the base types of the vertex contents |
---|
123 | enum VertexElementType |
---|
124 | { |
---|
125 | VET_FLOAT1 = 0, |
---|
126 | VET_FLOAT2 = 1, |
---|
127 | VET_FLOAT3 = 2, |
---|
128 | VET_FLOAT4 = 3, |
---|
129 | /// alias to more specific colour type - use the current rendersystem's colour packing |
---|
130 | VET_COLOUR = 4, |
---|
131 | VET_SHORT1 = 5, |
---|
132 | VET_SHORT2 = 6, |
---|
133 | VET_SHORT3 = 7, |
---|
134 | VET_SHORT4 = 8, |
---|
135 | VET_UBYTE4 = 9, |
---|
136 | /// D3D style compact colour |
---|
137 | VET_COLOUR_ARGB = 10, |
---|
138 | /// GL style compact colour |
---|
139 | VET_COLOUR_ABGR = 11, |
---|
140 | VET_DOUBLE1 = 12, |
---|
141 | VET_DOUBLE2 = 13, |
---|
142 | VET_DOUBLE3 = 14, |
---|
143 | VET_DOUBLE4 = 15, |
---|
144 | VET_USHORT1 = 16, |
---|
145 | VET_USHORT2 = 17, |
---|
146 | VET_USHORT3 = 18, |
---|
147 | VET_USHORT4 = 19, |
---|
148 | VET_INT1 = 20, |
---|
149 | VET_INT2 = 21, |
---|
150 | VET_INT3 = 22, |
---|
151 | VET_INT4 = 23, |
---|
152 | VET_UINT1 = 24, |
---|
153 | VET_UINT2 = 25, |
---|
154 | VET_UINT3 = 26, |
---|
155 | VET_UINT4 = 27 |
---|
156 | }; |
---|
157 | |
---|
158 | /** This class declares the usage of a single vertex buffer as a component |
---|
159 | of a complete VertexDeclaration. |
---|
160 | @remarks |
---|
161 | Several vertex buffers can be used to supply the input geometry for a |
---|
162 | rendering operation, and in each case a vertex buffer can be used in |
---|
163 | different ways for different operations; the buffer itself does not |
---|
164 | define the semantics (position, normal etc), the VertexElement |
---|
165 | class does. |
---|
166 | */ |
---|
167 | class _OgreExport VertexElement : public VertexDataAlloc |
---|
168 | { |
---|
169 | protected: |
---|
170 | /// The source vertex buffer, as bound to an index using VertexBufferBinding |
---|
171 | unsigned short mSource; |
---|
172 | /// The offset in the buffer that this element starts at |
---|
173 | size_t mOffset; |
---|
174 | /// The type of element |
---|
175 | VertexElementType mType; |
---|
176 | /// The meaning of the element |
---|
177 | VertexElementSemantic mSemantic; |
---|
178 | /// Index of the item, only applicable for some elements like texture coords |
---|
179 | unsigned short mIndex; |
---|
180 | public: |
---|
181 | /// Constructor, should not be called directly, only needed because of list |
---|
182 | VertexElement() {} |
---|
183 | /// Constructor, should not be called directly, call VertexDeclaration::addElement |
---|
184 | VertexElement(unsigned short source, size_t offset, VertexElementType theType, |
---|
185 | VertexElementSemantic semantic, unsigned short index = 0); |
---|
186 | /// Gets the vertex buffer index from where this element draws it's values |
---|
187 | unsigned short getSource(void) const { return mSource; } |
---|
188 | /// Gets the offset into the buffer where this element starts |
---|
189 | size_t getOffset(void) const { return mOffset; } |
---|
190 | /// Gets the data format of this element |
---|
191 | VertexElementType getType(void) const { return mType; } |
---|
192 | /// Gets the meaning of this element |
---|
193 | VertexElementSemantic getSemantic(void) const { return mSemantic; } |
---|
194 | /// Gets the index of this element, only applicable for repeating elements |
---|
195 | unsigned short getIndex(void) const { return mIndex; } |
---|
196 | /// Gets the size of this element in bytes |
---|
197 | size_t getSize(void) const; |
---|
198 | /// Utility method for helping to calculate offsets |
---|
199 | static size_t getTypeSize(VertexElementType etype); |
---|
200 | /// Utility method which returns the count of values in a given type |
---|
201 | static unsigned short getTypeCount(VertexElementType etype); |
---|
202 | /** Simple converter function which will turn a single-value type into a |
---|
203 | multi-value type based on a parameter. |
---|
204 | */ |
---|
205 | static VertexElementType multiplyTypeCount(VertexElementType baseType, unsigned short count); |
---|
206 | /** Simple converter function which will a type into it's single-value |
---|
207 | equivalent - makes switches on type easier. |
---|
208 | */ |
---|
209 | static VertexElementType getBaseType(VertexElementType multiType); |
---|
210 | |
---|
211 | /** Utility method for converting colour from |
---|
212 | one packed 32-bit colour type to another. |
---|
213 | @param srcType The source type |
---|
214 | @param dstType The destination type |
---|
215 | @param ptr Read / write value to change |
---|
216 | */ |
---|
217 | static void convertColourValue(VertexElementType srcType, |
---|
218 | VertexElementType dstType, uint32* ptr); |
---|
219 | |
---|
220 | /** Utility method for converting colour to |
---|
221 | a packed 32-bit colour type. |
---|
222 | @param src source colour |
---|
223 | @param dst The destination type |
---|
224 | */ |
---|
225 | static uint32 convertColourValue(const ColourValue& src, |
---|
226 | VertexElementType dst); |
---|
227 | |
---|
228 | /** Utility method to get the most appropriate packed colour vertex element format. */ |
---|
229 | static VertexElementType getBestColourVertexElementType(void); |
---|
230 | |
---|
231 | inline bool operator== (const VertexElement& rhs) const |
---|
232 | { |
---|
233 | if (mType != rhs.mType || |
---|
234 | mIndex != rhs.mIndex || |
---|
235 | mOffset != rhs.mOffset || |
---|
236 | mSemantic != rhs.mSemantic || |
---|
237 | mSource != rhs.mSource) |
---|
238 | return false; |
---|
239 | else |
---|
240 | return true; |
---|
241 | |
---|
242 | } |
---|
243 | /** Adjusts a pointer to the base of a vertex to point at this element. |
---|
244 | @remarks |
---|
245 | This variant is for void pointers, passed as a parameter because we can't |
---|
246 | rely on covariant return types. |
---|
247 | @param pBase Pointer to the start of a vertex in this buffer. |
---|
248 | @param pElem Pointer to a pointer which will be set to the start of this element. |
---|
249 | */ |
---|
250 | inline void baseVertexPointerToElement(void* pBase, void** pElem) const |
---|
251 | { |
---|
252 | // The only way we can do this is to cast to char* in order to use byte offset |
---|
253 | // then cast back to void*. |
---|
254 | *pElem = static_cast<void*>( |
---|
255 | static_cast<unsigned char*>(pBase) + mOffset); |
---|
256 | } |
---|
257 | /** Adjusts a pointer to the base of a vertex to point at this element. |
---|
258 | @remarks |
---|
259 | This variant is for float pointers, passed as a parameter because we can't |
---|
260 | rely on covariant return types. |
---|
261 | @param pBase Pointer to the start of a vertex in this buffer. |
---|
262 | @param pElem Pointer to a pointer which will be set to the start of this element. |
---|
263 | */ |
---|
264 | inline void baseVertexPointerToElement(void* pBase, float** pElem) const |
---|
265 | { |
---|
266 | // The only way we can do this is to cast to char* in order to use byte offset |
---|
267 | // then cast back to float*. However we have to go via void* because casting |
---|
268 | // directly is not allowed |
---|
269 | *pElem = static_cast<float*>( |
---|
270 | static_cast<void*>( |
---|
271 | static_cast<unsigned char*>(pBase) + mOffset)); |
---|
272 | } |
---|
273 | |
---|
274 | /** Adjusts a pointer to the base of a vertex to point at this element. |
---|
275 | @remarks |
---|
276 | This variant is for RGBA pointers, passed as a parameter because we can't |
---|
277 | rely on covariant return types. |
---|
278 | @param pBase Pointer to the start of a vertex in this buffer. |
---|
279 | @param pElem Pointer to a pointer which will be set to the start of this element. |
---|
280 | */ |
---|
281 | inline void baseVertexPointerToElement(void* pBase, RGBA** pElem) const |
---|
282 | { |
---|
283 | *pElem = static_cast<RGBA*>( |
---|
284 | static_cast<void*>( |
---|
285 | static_cast<unsigned char*>(pBase) + mOffset)); |
---|
286 | } |
---|
287 | /** Adjusts a pointer to the base of a vertex to point at this element. |
---|
288 | @remarks |
---|
289 | This variant is for char pointers, passed as a parameter because we can't |
---|
290 | rely on covariant return types. |
---|
291 | @param pBase Pointer to the start of a vertex in this buffer. |
---|
292 | @param pElem Pointer to a pointer which will be set to the start of this element. |
---|
293 | */ |
---|
294 | inline void baseVertexPointerToElement(void* pBase, unsigned char** pElem) const |
---|
295 | { |
---|
296 | *pElem = static_cast<unsigned char*>(pBase) + mOffset; |
---|
297 | } |
---|
298 | |
---|
299 | /** Adjusts a pointer to the base of a vertex to point at this element. |
---|
300 | @remarks |
---|
301 | This variant is for ushort pointers, passed as a parameter because we can't |
---|
302 | rely on covariant return types. |
---|
303 | @param pBase Pointer to the start of a vertex in this buffer. |
---|
304 | @param pElem Pointer to a pointer which will be set to the start of this element. |
---|
305 | */ |
---|
306 | inline void baseVertexPointerToElement(void* pBase, unsigned short** pElem) const |
---|
307 | { |
---|
308 | *pElem = static_cast<unsigned short*>( |
---|
309 | static_cast<void*>( |
---|
310 | static_cast<unsigned char*>(pBase) + mOffset)); |
---|
311 | } |
---|
312 | |
---|
313 | |
---|
314 | }; |
---|
315 | /** This class declares the format of a set of vertex inputs, which |
---|
316 | can be issued to the rendering API through a RenderOperation. |
---|
317 | @remarks |
---|
318 | You should be aware that the ordering and structure of the |
---|
319 | VertexDeclaration can be very important on DirectX with older |
---|
320 | cards,so if you want to maintain maximum compatibility with |
---|
321 | all render systems and all cards you should be careful to follow these |
---|
322 | rules:<ol> |
---|
323 | <li>VertexElements should be added in the following order, and the order of the |
---|
324 | elements within a shared buffer should be as follows: |
---|
325 | position, blending weights, normals, diffuse colours, specular colours, |
---|
326 | texture coordinates (in order, with no gaps)</li> |
---|
327 | <li>You must not have unused gaps in your buffers which are not referenced |
---|
328 | by any VertexElement</li> |
---|
329 | <li>You must not cause the buffer & offset settings of 2 VertexElements to overlap</li> |
---|
330 | </ol> |
---|
331 | Whilst GL and more modern graphics cards in D3D will allow you to defy these rules, |
---|
332 | sticking to them will ensure that your buffers have the maximum compatibility. |
---|
333 | @par |
---|
334 | Like the other classes in this functional area, these declarations should be created and |
---|
335 | destroyed using the HardwareBufferManager. |
---|
336 | */ |
---|
337 | class _OgreExport VertexDeclaration : public VertexDataAlloc |
---|
338 | { |
---|
339 | public: |
---|
340 | /// Defines the list of vertex elements that makes up this declaration |
---|
341 | typedef list<VertexElement>::type VertexElementList; |
---|
342 | /// Sort routine for vertex elements |
---|
343 | static bool vertexElementLess(const VertexElement& e1, const VertexElement& e2); |
---|
344 | protected: |
---|
345 | VertexElementList mElementList; |
---|
346 | public: |
---|
347 | /// Standard constructor, not you should use HardwareBufferManager::createVertexDeclaration |
---|
348 | VertexDeclaration(); |
---|
349 | virtual ~VertexDeclaration(); |
---|
350 | |
---|
351 | /** Get the number of elements in the declaration. */ |
---|
352 | size_t getElementCount(void) const { return mElementList.size(); } |
---|
353 | /** Gets read-only access to the list of vertex elements. */ |
---|
354 | const VertexElementList& getElements(void) const; |
---|
355 | /** Get a single element. */ |
---|
356 | const VertexElement* getElement(unsigned short index) const; |
---|
357 | |
---|
358 | /** Sorts the elements in this list to be compatible with the maximum |
---|
359 | number of rendering APIs / graphics cards. |
---|
360 | @remarks |
---|
361 | Older graphics cards require vertex data to be presented in a more |
---|
362 | rigid way, as defined in the main documentation for this class. As well |
---|
363 | as the ordering being important, where shared source buffers are used, the |
---|
364 | declaration must list all the elements for each source in turn. |
---|
365 | */ |
---|
366 | void sort(void); |
---|
367 | |
---|
368 | /** Remove any gaps in the source buffer list used by this declaration. |
---|
369 | @remarks |
---|
370 | This is useful if you've modified a declaration and want to remove |
---|
371 | any gaps in the list of buffers being used. Note, however, that if this |
---|
372 | declaration is already being used with a VertexBufferBinding, you will |
---|
373 | need to alter that too. This method is mainly useful when reorganising |
---|
374 | buffers based on an altered declaration. |
---|
375 | @note |
---|
376 | This will cause the vertex declaration to be re-sorted. |
---|
377 | */ |
---|
378 | void closeGapsInSource(void); |
---|
379 | |
---|
380 | /** Generates a new VertexDeclaration for optimal usage based on the current |
---|
381 | vertex declaration, which can be used with VertexData::reorganiseBuffers later |
---|
382 | if you wish, or simply used as a template. |
---|
383 | @remarks |
---|
384 | Different buffer organisations and buffer usages will be returned |
---|
385 | depending on the parameters passed to this method. |
---|
386 | @param skeletalAnimation Whether this vertex data is going to be |
---|
387 | skeletally animated |
---|
388 | @param vertexAnimation Whether this vertex data is going to be vertex animated |
---|
389 | @param vertexAnimationNormals Whether vertex data animation is going to include normals animation |
---|
390 | */ |
---|
391 | VertexDeclaration* getAutoOrganisedDeclaration(bool skeletalAnimation, |
---|
392 | bool vertexAnimation, bool vertexAnimationNormals) const; |
---|
393 | |
---|
394 | /** Gets the index of the highest source value referenced by this declaration. */ |
---|
395 | unsigned short getMaxSource(void) const; |
---|
396 | |
---|
397 | |
---|
398 | |
---|
399 | /** Adds a new VertexElement to this declaration. |
---|
400 | @remarks |
---|
401 | This method adds a single element (positions, normals etc) to the end of the |
---|
402 | vertex declaration. <b>Please read the information in VertexDeclaration about |
---|
403 | the importance of ordering and structure for compatibility with older D3D drivers</b>. |
---|
404 | @param source The binding index of HardwareVertexBuffer which will provide the source for this element. |
---|
405 | See VertexBufferBinding for full information. |
---|
406 | @param offset The offset in bytes where this element is located in the buffer |
---|
407 | @param theType The data format of the element (3 floats, a colour etc) |
---|
408 | @param semantic The meaning of the data (position, normal, diffuse colour etc) |
---|
409 | @param index Optional index for multi-input elements like texture coordinates |
---|
410 | @return A reference to the VertexElement added. |
---|
411 | */ |
---|
412 | virtual const VertexElement& addElement(unsigned short source, size_t offset, VertexElementType theType, |
---|
413 | VertexElementSemantic semantic, unsigned short index = 0); |
---|
414 | /** Inserts a new VertexElement at a given position in this declaration. |
---|
415 | @remarks |
---|
416 | This method adds a single element (positions, normals etc) at a given position in this |
---|
417 | vertex declaration. <b>Please read the information in VertexDeclaration about |
---|
418 | the importance of ordering and structure for compatibility with older D3D drivers</b>. |
---|
419 | @param source The binding index of HardwareVertexBuffer which will provide the source for this element. |
---|
420 | See VertexBufferBinding for full information. |
---|
421 | @param offset The offset in bytes where this element is located in the buffer |
---|
422 | @param theType The data format of the element (3 floats, a colour etc) |
---|
423 | @param semantic The meaning of the data (position, normal, diffuse colour etc) |
---|
424 | @param index Optional index for multi-input elements like texture coordinates |
---|
425 | @return A reference to the VertexElement added. |
---|
426 | */ |
---|
427 | virtual const VertexElement& insertElement(unsigned short atPosition, |
---|
428 | unsigned short source, size_t offset, VertexElementType theType, |
---|
429 | VertexElementSemantic semantic, unsigned short index = 0); |
---|
430 | |
---|
431 | /** Remove the element at the given index from this declaration. */ |
---|
432 | virtual void removeElement(unsigned short elem_index); |
---|
433 | |
---|
434 | /** Remove the element with the given semantic and usage index. |
---|
435 | @remarks |
---|
436 | In this case 'index' means the usage index for repeating elements such |
---|
437 | as texture coordinates. For other elements this will always be 0 and does |
---|
438 | not refer to the index in the vector. |
---|
439 | */ |
---|
440 | virtual void removeElement(VertexElementSemantic semantic, unsigned short index = 0); |
---|
441 | |
---|
442 | /** Remove all elements. */ |
---|
443 | virtual void removeAllElements(void); |
---|
444 | |
---|
445 | /** Modify an element in-place, params as addElement. |
---|
446 | @remarks |
---|
447 | <b>Please read the information in VertexDeclaration about |
---|
448 | the importance of ordering and structure for compatibility with older D3D drivers</b>. |
---|
449 | */ |
---|
450 | virtual void modifyElement(unsigned short elem_index, unsigned short source, size_t offset, VertexElementType theType, |
---|
451 | VertexElementSemantic semantic, unsigned short index = 0); |
---|
452 | |
---|
453 | /** Finds a VertexElement with the given semantic, and index if there is more than |
---|
454 | one element with the same semantic. |
---|
455 | @remarks |
---|
456 | If the element is not found, this method returns null. |
---|
457 | */ |
---|
458 | virtual const VertexElement* findElementBySemantic(VertexElementSemantic sem, unsigned short index = 0) const; |
---|
459 | /** Based on the current elements, gets the size of the vertex for a given buffer source. |
---|
460 | @param source The buffer binding index for which to get the vertex size. |
---|
461 | */ |
---|
462 | |
---|
463 | /** Gets a list of elements which use a given source. |
---|
464 | @remarks |
---|
465 | Note that the list of elements is returned by value therefore is separate from |
---|
466 | the declaration as soon as this method returns. |
---|
467 | */ |
---|
468 | virtual VertexElementList findElementsBySource(unsigned short source) const; |
---|
469 | |
---|
470 | /** Gets the vertex size defined by this declaration for a given source. */ |
---|
471 | virtual size_t getVertexSize(unsigned short source) const; |
---|
472 | |
---|
473 | /** Return the index of the next free texture coordinate set which may be added |
---|
474 | to this declaration. |
---|
475 | */ |
---|
476 | virtual unsigned short getNextFreeTextureCoordinate() const; |
---|
477 | |
---|
478 | /** Clones this declaration. |
---|
479 | @param mgr Optional HardwareBufferManager to use for creating the clone |
---|
480 | (if null, use the current default). |
---|
481 | */ |
---|
482 | virtual VertexDeclaration* clone(HardwareBufferManagerBase* mgr = 0) const; |
---|
483 | |
---|
484 | inline bool operator== (const VertexDeclaration& rhs) const |
---|
485 | { |
---|
486 | if (mElementList.size() != rhs.mElementList.size()) |
---|
487 | return false; |
---|
488 | |
---|
489 | VertexElementList::const_iterator i, iend, rhsi, rhsiend; |
---|
490 | iend = mElementList.end(); |
---|
491 | rhsiend = rhs.mElementList.end(); |
---|
492 | rhsi = rhs.mElementList.begin(); |
---|
493 | for (i = mElementList.begin(); i != iend && rhsi != rhsiend; ++i, ++rhsi) |
---|
494 | { |
---|
495 | if ( !(*i == *rhsi) ) |
---|
496 | return false; |
---|
497 | } |
---|
498 | |
---|
499 | return true; |
---|
500 | } |
---|
501 | inline bool operator!= (const VertexDeclaration& rhs) const |
---|
502 | { |
---|
503 | return !(*this == rhs); |
---|
504 | } |
---|
505 | |
---|
506 | }; |
---|
507 | |
---|
508 | /** Records the state of all the vertex buffer bindings required to provide a vertex declaration |
---|
509 | with the input data it needs for the vertex elements. |
---|
510 | @remarks |
---|
511 | Why do we have this binding list rather than just have VertexElement referring to the |
---|
512 | vertex buffers direct? Well, in the underlying APIs, binding the vertex buffers to an |
---|
513 | index (or 'stream') is the way that vertex data is linked, so this structure better |
---|
514 | reflects the realities of that. In addition, by separating the vertex declaration from |
---|
515 | the list of vertex buffer bindings, it becomes possible to reuse bindings between declarations |
---|
516 | and vice versa, giving opportunities to reduce the state changes required to perform rendering. |
---|
517 | @par |
---|
518 | Like the other classes in this functional area, these binding maps should be created and |
---|
519 | destroyed using the HardwareBufferManager. |
---|
520 | */ |
---|
521 | class _OgreExport VertexBufferBinding : public VertexDataAlloc |
---|
522 | { |
---|
523 | public: |
---|
524 | /// Defines the vertex buffer bindings used as source for vertex declarations |
---|
525 | typedef map<unsigned short, HardwareVertexBufferSharedPtr>::type VertexBufferBindingMap; |
---|
526 | protected: |
---|
527 | VertexBufferBindingMap mBindingMap; |
---|
528 | mutable unsigned short mHighIndex; |
---|
529 | public: |
---|
530 | /// Constructor, should not be called direct, use HardwareBufferManager::createVertexBufferBinding |
---|
531 | VertexBufferBinding(); |
---|
532 | virtual ~VertexBufferBinding(); |
---|
533 | /** Set a binding, associating a vertex buffer with a given index. |
---|
534 | @remarks |
---|
535 | If the index is already associated with a vertex buffer, |
---|
536 | the association will be replaced. This may cause the old buffer |
---|
537 | to be destroyed if nothing else is referring to it. |
---|
538 | You should assign bindings from 0 and not leave gaps, although you can |
---|
539 | bind them in any order. |
---|
540 | */ |
---|
541 | virtual void setBinding(unsigned short index, const HardwareVertexBufferSharedPtr& buffer); |
---|
542 | /** Removes an existing binding. */ |
---|
543 | virtual void unsetBinding(unsigned short index); |
---|
544 | |
---|
545 | /** Removes all the bindings. */ |
---|
546 | virtual void unsetAllBindings(void); |
---|
547 | |
---|
548 | /// Gets a read-only version of the buffer bindings |
---|
549 | virtual const VertexBufferBindingMap& getBindings(void) const; |
---|
550 | |
---|
551 | /// Gets the buffer bound to the given source index |
---|
552 | virtual const HardwareVertexBufferSharedPtr& getBuffer(unsigned short index) const; |
---|
553 | /// Gets whether a buffer is bound to the given source index |
---|
554 | virtual bool isBufferBound(unsigned short index) const; |
---|
555 | |
---|
556 | virtual size_t getBufferCount(void) const { return mBindingMap.size(); } |
---|
557 | |
---|
558 | /** Gets the highest index which has already been set, plus 1. |
---|
559 | @remarks |
---|
560 | This is to assist in binding the vertex buffers such that there are |
---|
561 | not gaps in the list. |
---|
562 | */ |
---|
563 | virtual unsigned short getNextIndex(void) const { return mHighIndex++; } |
---|
564 | |
---|
565 | /** Gets the last bound index. |
---|
566 | */ |
---|
567 | virtual unsigned short getLastBoundIndex(void) const; |
---|
568 | |
---|
569 | typedef map<ushort, ushort>::type BindingIndexMap; |
---|
570 | |
---|
571 | /** Check whether any gaps in the bindings. |
---|
572 | */ |
---|
573 | virtual bool hasGaps(void) const; |
---|
574 | |
---|
575 | /** Remove any gaps in the bindings. |
---|
576 | @remarks |
---|
577 | This is useful if you've removed vertex buffer from this vertex buffer |
---|
578 | bindings and want to remove any gaps in the bindings. Note, however, |
---|
579 | that if this bindings is already being used with a VertexDeclaration, |
---|
580 | you will need to alter that too. This method is mainly useful when |
---|
581 | reorganising buffers manually. |
---|
582 | @param |
---|
583 | bindingIndexMap To be retrieve the binding index map that used to |
---|
584 | translation old index to new index; will be cleared by this method |
---|
585 | before fill-in. |
---|
586 | */ |
---|
587 | virtual void closeGaps(BindingIndexMap& bindingIndexMap); |
---|
588 | |
---|
589 | /// Returns true if this binding has an element that contains instance data |
---|
590 | virtual bool hasInstanceData() const; |
---|
591 | |
---|
592 | |
---|
593 | }; |
---|
594 | /** @} */ |
---|
595 | /** @} */ |
---|
596 | |
---|
597 | |
---|
598 | |
---|
599 | } |
---|
600 | |
---|
601 | #include "OgreHeaderSuffix.h" |
---|
602 | |
---|
603 | #endif |
---|
604 | |
---|