/src/ogre/OgreMain/include/OgreVertexIndexData.h
Line | Count | Source (jump to first uncovered line) |
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-2014 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 __VertexIndexData_H__ |
29 | | #define __VertexIndexData_H__ |
30 | | |
31 | | #include "OgrePrerequisites.h" |
32 | | #include "OgreHardwareVertexBuffer.h" |
33 | | #include "OgreHardwareIndexBuffer.h" |
34 | | #include "OgreHeaderPrefix.h" |
35 | | |
36 | | namespace Ogre { |
37 | | /** \addtogroup Core |
38 | | * @{ |
39 | | */ |
40 | | /** \addtogroup RenderSystem |
41 | | * @{ |
42 | | */ |
43 | | |
44 | | /** collects together all the vertex-related information used to render geometry. |
45 | | * |
46 | | * The RenderOperation requires a pointer to a VertexData object, and it is also used in Mesh and |
47 | | * SubMesh to store the vertex positions, normals, texture coordinates etc. VertexData can either be |
48 | | * used alone (in order to render unindexed geometry, where the stream of vertices defines the |
49 | | * triangles), or in combination with IndexData where the triangles are defined by indexes which refer |
50 | | * to the entries in VertexData. It’s worth noting that you don’t necessarily have to use VertexData to |
51 | | * store your applications geometry; all that is required is that you can build a VertexData structure |
52 | | * when it comes to rendering. This is pretty easy since all of VertexData’s members are pointers, so |
53 | | * you could maintain your vertex buffers and declarations in alternative structures if you like, so |
54 | | * long as you can convert them for rendering. |
55 | | */ |
56 | | class _OgreExport VertexData : public VertexDataAlloc |
57 | | { |
58 | | private: |
59 | | /// Protected copy constructor, to prevent misuse |
60 | | VertexData(const VertexData& rhs); /* do nothing, should not use */ |
61 | | /// Protected operator=, to prevent misuse |
62 | | VertexData& operator=(const VertexData& rhs); /* do not use */ |
63 | | |
64 | | HardwareBufferManagerBase* mMgr; |
65 | | |
66 | | typedef std::vector<HardwareBufferUsage> BufferUsageList; |
67 | | void reorganiseBuffers(VertexDeclaration* newDeclaration, const BufferUsageList& bufferUsage, |
68 | | HardwareBufferManagerBase* mgr); |
69 | | public: |
70 | | /** Constructor. |
71 | | @note |
72 | | This constructor creates the VertexDeclaration and VertexBufferBinding |
73 | | automatically, and arranges for their deletion afterwards. |
74 | | @param mgr Optional HardwareBufferManager from which to create resources |
75 | | */ |
76 | | VertexData(HardwareBufferManagerBase* mgr = 0); |
77 | | /** Constructor. |
78 | | @note |
79 | | This constructor receives the VertexDeclaration and VertexBufferBinding |
80 | | from the caller, and as such does not arrange for their deletion afterwards, |
81 | | the caller remains responsible for that. |
82 | | @param dcl The VertexDeclaration to use |
83 | | @param bind The VertexBufferBinding to use |
84 | | */ |
85 | | VertexData(VertexDeclaration* dcl, VertexBufferBinding* bind); |
86 | | ~VertexData(); |
87 | | |
88 | | /** Declaration of the the format of the vertex input. |
89 | | Note that this is created for you on construction. |
90 | | */ |
91 | | VertexDeclaration* vertexDeclaration; |
92 | | /** Defines which vertex buffers are bound to which sources. |
93 | | Note that this is created for you on construction. |
94 | | */ |
95 | | VertexBufferBinding* vertexBufferBinding; |
96 | | /// Whether this class should delete the declaration and binding |
97 | | bool mDeleteDclBinding; |
98 | | /// The position in the bound buffers to start reading vertex data from. This allows you to use a single buffer for many different renderables. |
99 | | uint32 vertexStart; |
100 | | /// The number of vertices to process in this particular rendering group |
101 | | uint32 vertexCount; |
102 | | |
103 | | |
104 | | /// Struct used to hold hardware morph / pose vertex data information |
105 | | struct HardwareAnimationData |
106 | | { |
107 | | unsigned short targetBufferIndex; |
108 | | float parametric; |
109 | | }; |
110 | | typedef std::vector<HardwareAnimationData> HardwareAnimationDataList; |
111 | | /// Number of hardware animation data items used |
112 | | uint32 hwAnimDataItemsUsed; |
113 | | /// VertexElements used for hardware morph / pose animation |
114 | | HardwareAnimationDataList hwAnimationDataList; |
115 | | |
116 | | /** Clones this vertex data, potentially including replicating any vertex buffers. |
117 | | @param copyData Whether to create new vertex buffers too or just reference the existing ones |
118 | | @param mgr If supplied, the buffer manager through which copies should be made |
119 | | @remarks The caller is expected to delete the returned pointer when ready |
120 | | */ |
121 | | VertexData* clone(bool copyData = true, HardwareBufferManagerBase* mgr = 0) const OGRE_NODISCARD; |
122 | | |
123 | | /** Modifies the vertex data to be suitable for use for rendering shadow geometry as in @cite mcguire2003fast |
124 | | |
125 | | Preparing vertex data to generate a shadow volume involves firstly ensuring that the |
126 | | vertex buffer containing the positions is a standalone vertex buffer, |
127 | | with no other components in it. This method will therefore break apart any existing |
128 | | vertex buffers if position is sharing a vertex buffer. |
129 | | Secondly, it will double the size of this vertex buffer so that there are 2 copies of |
130 | | the position data for the mesh. The first half is used for the original, and the second |
131 | | half is used for the 'extruded' version. The vertex count used to render will remain |
132 | | the same though, so as not to add any overhead to regular rendering of the object. |
133 | | Both copies of the position are required in one buffer because shadow volumes stretch |
134 | | from the original mesh to the extruded version. |
135 | | |
136 | | It's important to appreciate that this method can fundamentally change the structure of your |
137 | | vertex buffers, although in reality they will be new buffers. As it happens, if other |
138 | | objects are using the original buffers then they will be unaffected because the reference |
139 | | counting will keep them intact. However, if you have made any assumptions about the |
140 | | structure of the vertex data in the buffers of this object, you may have to rethink them. |
141 | | |
142 | | Because shadow volumes are rendered in turn, no additional |
143 | | index buffer space is allocated by this method, a shared index buffer allocated by the |
144 | | shadow rendering algorithm is used for addressing this extended vertex buffer. |
145 | | */ |
146 | | void prepareForShadowVolume(void); |
147 | | |
148 | | /** Convert the type of a vertex element of the given semantic |
149 | | |
150 | | currently the following conversions are supported: |
151 | | - #VET_FLOAT3 or #VET_FLOAT4 to #VET_INT_10_10_10_2_NORM |
152 | | - #VET_INT_10_10_10_2_NORM to #VET_FLOAT3 or #VET_FLOAT4 |
153 | | - #VET_HALF3 to #VET_HALF4, VET_[U]SHORT3 to VET_[U]SHORT4 |
154 | | - #VET_FLOAT3 to #VET_HALF3 |
155 | | @param semantic The semantic of the element to convert |
156 | | @param dstType The type to convert to |
157 | | @param index Optional index for multi-input semantics like texture coordinates |
158 | | */ |
159 | | void convertVertexElement(VertexElementSemantic semantic, VertexElementType dstType, uint16 index = 0); |
160 | | |
161 | | /** Additional shadow volume vertex buffer storage. |
162 | | |
163 | | This additional buffer is only used where we have prepared this VertexData for |
164 | | use in shadow volume construction, and where the current render system supports |
165 | | vertex programs. This buffer contains the 'w' vertex position component which will |
166 | | be used by that program to differentiate between extruded and non-extruded vertices. |
167 | | This 'w' component cannot be included in the original position buffer because |
168 | | DirectX does not allow 4-component positions in the fixed-function pipeline, and the original |
169 | | position buffer must still be usable for fixed-function rendering. |
170 | | |
171 | | Note that we don't store any vertex declaration or vertex buffer binding here because this |
172 | | can be reused in the shadow algorithm. |
173 | | */ |
174 | | HardwareVertexBufferSharedPtr hardwareShadowVolWBuffer; |
175 | | |
176 | | /** Reorganises the data in the vertex buffers according to the |
177 | | new vertex declaration passed in. Note that new vertex buffers |
178 | | are created and written to, so if the buffers being referenced |
179 | | by this vertex data object are also used by others, then the |
180 | | original buffers will not be damaged by this operation. |
181 | | Once this operation has completed, the new declaration |
182 | | passed in will overwrite the current one. |
183 | | This version of the method derives the buffer usages from the existing |
184 | | buffers, by using the 'most flexible' usage from the equivalent sources. |
185 | | @param newDeclaration The vertex declaration which will be used |
186 | | for the reorganised buffer state. Note that the new delcaration |
187 | | must not include any elements which do not already exist in the |
188 | | current declaration; you can drop elements by |
189 | | excluding them from the declaration if you wish, however. |
190 | | @param mgr Optional pointer to the manager to use to create new declarations |
191 | | and buffers etc. If not supplied, the HardwareBufferManager singleton will be used |
192 | | */ |
193 | | void reorganiseBuffers(VertexDeclaration* newDeclaration, HardwareBufferManagerBase* mgr = 0); |
194 | | |
195 | | /** Remove any gaps in the vertex buffer bindings. |
196 | | |
197 | | This is useful if you've removed elements and buffers from this vertex |
198 | | data and want to remove any gaps in the vertex buffer bindings. This |
199 | | method is mainly useful when reorganising vertex data manually. |
200 | | @note |
201 | | This will cause binding index of the elements in the vertex declaration |
202 | | to be altered to new binding index. |
203 | | */ |
204 | | void closeGapsInBindings(void); |
205 | | |
206 | | /** Remove all vertex buffers that never used by the vertex declaration. |
207 | | |
208 | | This is useful if you've removed elements from the vertex declaration |
209 | | and want to unreference buffers that never used any more. This method |
210 | | is mainly useful when reorganising vertex data manually. |
211 | | @note |
212 | | This also remove any gaps in the vertex buffer bindings. |
213 | | */ |
214 | | void removeUnusedBuffers(void); |
215 | | |
216 | | /** Convert all packed colour values (VET_COLOUR_*) in buffers used to |
217 | | another type. |
218 | | @param srcType The source colour type to assume if the ambiguous VET_COLOUR |
219 | | is encountered. |
220 | | @param destType The destination colour type, must be VET_COLOUR_ABGR or |
221 | | VET_COLOUR_ARGB. |
222 | | */ |
223 | | void convertPackedColour(VertexElementType srcType, VertexElementType destType); |
224 | | |
225 | | |
226 | | /** Allocate elements to serve a holder of morph / pose target data |
227 | | for hardware morphing / pose blending. |
228 | | |
229 | | This method will allocate the given number of 3D texture coordinate |
230 | | sets for use as a morph target or target pose offset (3D position). |
231 | | These elements will be saved in hwAnimationDataList. |
232 | | It will also assume that the source of these new elements will be new |
233 | | buffers which are not bound at this time, so will start the sources to |
234 | | 1 higher than the current highest binding source. The caller is |
235 | | expected to bind these new buffers when appropriate. For morph animation |
236 | | the original position buffer will be the 'from' keyframe data, whilst |
237 | | for pose animation it will be the original vertex data. |
238 | | If normals are animated, then twice the number of 3D texture coordinates are required |
239 | | @return The number of sets that were supported |
240 | | */ |
241 | | ushort allocateHardwareAnimationElements(ushort count, bool animateNormals); |
242 | | |
243 | | /** Internal method to clone vertex data definitions but to remove blend buffers. */ |
244 | | VertexData* _cloneRemovingBlendData() const; |
245 | | }; |
246 | | |
247 | | /** Summary class collecting together index data source information. */ |
248 | | class _OgreExport IndexData : public IndexDataAlloc |
249 | | { |
250 | | public: |
251 | | IndexData(); |
252 | | ~IndexData(); |
253 | | /// Pointer to the HardwareIndexBuffer to use, must be specified if useIndexes = true |
254 | | HardwareIndexBufferSharedPtr indexBuffer; |
255 | | |
256 | | /// Index in the buffer to start from for this operation |
257 | | uint32 indexStart; |
258 | | |
259 | | /// The number of indexes to use from the buffer |
260 | | uint32 indexCount; |
261 | | |
262 | | /** Clones this index data, potentially including replicating the index buffer. |
263 | | @param copyData Whether to create new buffers too or just reference the existing ones |
264 | | @param mgr If supplied, the buffer manager through which copies should be made |
265 | | @remarks The caller is expected to delete the returned pointer when finished |
266 | | */ |
267 | | IndexData* clone(bool copyData = true, HardwareBufferManagerBase* mgr = 0) const; |
268 | | |
269 | | /** Re-order the indexes in this index data structure to be more |
270 | | vertex cache friendly; that is to re-use the same vertices as close |
271 | | together as possible. |
272 | | |
273 | | Can only be used for index data which consists of triangle lists. |
274 | | It would in fact be pointless to use it on triangle strips or fans |
275 | | in any case. |
276 | | */ |
277 | | void optimiseVertexCacheTriList(void); |
278 | | |
279 | | }; |
280 | | |
281 | | /** Vertex cache profiler. |
282 | | |
283 | | Utility class for evaluating the effectiveness of the use of the vertex |
284 | | cache by a given index buffer. |
285 | | */ |
286 | | class _OgreExport VertexCacheProfiler : public BufferAlloc |
287 | | { |
288 | | public: |
289 | | VertexCacheProfiler(unsigned int cachesize = 16) |
290 | | : size ( cachesize ), tail (0), buffersize (0), hit (0), miss (0), triangles(0) |
291 | 0 | { |
292 | 0 | cache = OGRE_ALLOC_T(uint32, size, MEMCATEGORY_GEOMETRY); |
293 | 0 | } |
294 | | |
295 | | ~VertexCacheProfiler() |
296 | 0 | { |
297 | 0 | OGRE_FREE(cache, MEMCATEGORY_GEOMETRY); |
298 | 0 | } |
299 | | |
300 | | void profile(const HardwareIndexBufferSharedPtr& indexBuffer); |
301 | 0 | void reset() { hit = 0; miss = 0; tail = 0; buffersize = 0; triangles = 0; } |
302 | 0 | void flush() { tail = 0; buffersize = 0; } |
303 | | |
304 | 0 | unsigned int getHits() { return hit; } |
305 | 0 | unsigned int getMisses() { return miss; } |
306 | 0 | unsigned int getSize() { return size; } |
307 | | |
308 | | /** Get the average cache miss ratio |
309 | | |
310 | | @return ratio of vertex cache misses to the triangle count (0.5 - 3.0) |
311 | | */ |
312 | 0 | float getAvgCacheMissRatio() { return (float)miss / triangles; } |
313 | | private: |
314 | | unsigned int size; |
315 | | uint32 *cache; |
316 | | |
317 | | unsigned int tail, buffersize; |
318 | | unsigned int hit, miss; |
319 | | uint32 triangles; |
320 | | |
321 | | bool inCache(unsigned int index); |
322 | | }; |
323 | | /** @} */ |
324 | | /** @} */ |
325 | | } |
326 | | |
327 | | #include "OgreHeaderSuffix.h" |
328 | | |
329 | | #endif |
330 | | |