Batch.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. //
  2. // Copyright (c) 2008-2014 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "Drawable.h"
  24. #include "MathDefs.h"
  25. #include "Matrix3x4.h"
  26. #include "Ptr.h"
  27. #include "Rect.h"
  28. namespace Urho3D
  29. {
  30. class Camera;
  31. class Drawable;
  32. class Geometry;
  33. class Light;
  34. class Material;
  35. class Matrix3x4;
  36. class Pass;
  37. class ShaderVariation;
  38. class Texture2D;
  39. class VertexBuffer;
  40. class View;
  41. class Zone;
  42. struct LightBatchQueue;
  43. /// Queued 3D geometry draw call.
  44. struct Batch
  45. {
  46. /// Construct with defaults.
  47. Batch() :
  48. lightQueue_(0),
  49. isBase_(false)
  50. {
  51. }
  52. /// Construct from a drawable's source batch.
  53. Batch(const SourceBatch& rhs) :
  54. distance_(rhs.distance_),
  55. geometry_(rhs.geometry_),
  56. material_(rhs.material_),
  57. worldTransform_(rhs.worldTransform_),
  58. numWorldTransforms_(rhs.numWorldTransforms_),
  59. lightQueue_(0),
  60. geometryType_(rhs.geometryType_),
  61. overrideView_(rhs.overrideView_),
  62. isBase_(false)
  63. {
  64. }
  65. /// Calculate state sorting key, which consists of base pass flag, light, pass and geometry.
  66. void CalculateSortKey();
  67. /// Prepare for rendering.
  68. void Prepare(View* view, bool setModelTransform = true) const;
  69. /// Prepare and draw.
  70. void Draw(View* view) const;
  71. /// State sorting key.
  72. unsigned long long sortKey_;
  73. /// Distance from camera.
  74. float distance_;
  75. /// Geometry.
  76. Geometry* geometry_;
  77. /// Material.
  78. Material* material_;
  79. /// World transform(s). For a skinned model, these are the bone transforms.
  80. const Matrix3x4* worldTransform_;
  81. /// Number of world transforms.
  82. unsigned numWorldTransforms_;
  83. /// Camera.
  84. Camera* camera_;
  85. /// Zone.
  86. Zone* zone_;
  87. /// Light properties.
  88. LightBatchQueue* lightQueue_;
  89. /// Material pass.
  90. Pass* pass_;
  91. /// Vertex shader.
  92. ShaderVariation* vertexShader_;
  93. /// Pixel shader.
  94. ShaderVariation* pixelShader_;
  95. /// %Geometry type.
  96. GeometryType geometryType_;
  97. /// Override view transform flag. When set, the camera's view transform is replaced with an identity matrix.
  98. bool overrideView_;
  99. /// Base batch flag. This tells to draw the object fully without light optimizations.
  100. bool isBase_;
  101. /// 8-bit light mask for stencil marking in deferred rendering.
  102. unsigned char lightMask_;
  103. };
  104. /// Data for one geometry instance.
  105. struct InstanceData
  106. {
  107. /// Construct undefined.
  108. InstanceData()
  109. {
  110. }
  111. /// Construct with transform and distance.
  112. InstanceData(const Matrix3x4* worldTransform, float distance) :
  113. worldTransform_(worldTransform),
  114. distance_(distance)
  115. {
  116. }
  117. /// World transform.
  118. const Matrix3x4* worldTransform_;
  119. /// Distance from camera.
  120. float distance_;
  121. };
  122. /// Instanced 3D geometry draw call.
  123. struct BatchGroup : public Batch
  124. {
  125. /// Construct with defaults.
  126. BatchGroup() :
  127. startIndex_(M_MAX_UNSIGNED)
  128. {
  129. }
  130. /// Construct from a batch.
  131. BatchGroup(const Batch& batch) :
  132. Batch(batch),
  133. startIndex_(M_MAX_UNSIGNED)
  134. {
  135. }
  136. /// Destruct.
  137. ~BatchGroup()
  138. {
  139. }
  140. /// Add world transform(s) from a batch.
  141. void AddTransforms(const Batch& batch)
  142. {
  143. InstanceData newInstance;
  144. newInstance.distance_ = batch.distance_;
  145. for (unsigned i = 0; i < batch.numWorldTransforms_; ++i)
  146. {
  147. newInstance.worldTransform_ = &batch.worldTransform_[i];
  148. instances_.Push(newInstance);
  149. }
  150. }
  151. /// Pre-set the instance transforms. Buffer must be big enough to hold all transforms.
  152. void SetTransforms(void* lockedData, unsigned& freeIndex);
  153. /// Prepare and draw.
  154. void Draw(View* view) const;
  155. /// Instance data.
  156. PODVector<InstanceData> instances_;
  157. /// Instance stream start index, or M_MAX_UNSIGNED if transforms not pre-set.
  158. unsigned startIndex_;
  159. };
  160. /// Instanced draw call grouping key.
  161. struct BatchGroupKey
  162. {
  163. /// Construct undefined.
  164. BatchGroupKey()
  165. {
  166. }
  167. /// Construct from a batch.
  168. BatchGroupKey(const Batch& batch) :
  169. zone_(batch.zone_),
  170. lightQueue_(batch.lightQueue_),
  171. pass_(batch.pass_),
  172. material_(batch.material_),
  173. geometry_(batch.geometry_)
  174. {
  175. }
  176. /// Zone.
  177. Zone* zone_;
  178. /// Light properties.
  179. LightBatchQueue* lightQueue_;
  180. /// Material pass.
  181. Pass* pass_;
  182. /// Material.
  183. Material* material_;
  184. /// Geometry.
  185. Geometry* geometry_;
  186. /// Test for equality with another batch group key.
  187. bool operator == (const BatchGroupKey& rhs) const { return zone_ == rhs.zone_ && lightQueue_ == rhs.lightQueue_ && pass_ == rhs.pass_ && material_ == rhs.material_ && geometry_ == rhs.geometry_; }
  188. /// Test for inequality with another batch group key.
  189. bool operator != (const BatchGroupKey& rhs) const { return zone_ != rhs.zone_ || lightQueue_ != rhs.lightQueue_ || pass_ != rhs.pass_ || material_ != rhs.material_ || geometry_ != rhs.geometry_; }
  190. /// Return hash value.
  191. unsigned ToHash() const;
  192. };
  193. /// Queue that contains both instanced and non-instanced draw calls.
  194. struct BatchQueue
  195. {
  196. public:
  197. /// Clear for new frame by clearing all groups and batches.
  198. void Clear(int maxSortedInstances);
  199. /// Sort non-instanced draw calls back to front.
  200. void SortBackToFront();
  201. /// Sort instanced and non-instanced draw calls front to back.
  202. void SortFrontToBack();
  203. /// Sort batches front to back while also maintaining state sorting.
  204. void SortFrontToBack2Pass(PODVector<Batch*>& batches);
  205. /// Pre-set instance transforms of all groups. The vertex buffer must be big enough to hold all transforms.
  206. void SetTransforms(void* lockedData, unsigned& freeIndex);
  207. /// Draw.
  208. void Draw(View* view, bool markToStencil = false, bool usingLightOptimization = false) const;
  209. /// Return the combined amount of instances.
  210. unsigned GetNumInstances() const;
  211. /// Return whether the batch group is empty.
  212. bool IsEmpty() const { return batches_.Empty() && batchGroups_.Empty(); }
  213. /// Instanced draw calls.
  214. HashMap<BatchGroupKey, BatchGroup> batchGroups_;
  215. /// Shader remapping table for 2-pass state and distance sort.
  216. HashMap<unsigned, unsigned> shaderRemapping_;
  217. /// Material remapping table for 2-pass state and distance sort.
  218. HashMap<unsigned short, unsigned short> materialRemapping_;
  219. /// Geometry remapping table for 2-pass state and distance sort.
  220. HashMap<unsigned short, unsigned short> geometryRemapping_;
  221. /// Unsorted non-instanced draw calls.
  222. PODVector<Batch> batches_;
  223. /// Sorted non-instanced draw calls.
  224. PODVector<Batch*> sortedBatches_;
  225. /// Sorted instanced draw calls.
  226. PODVector<BatchGroup*> sortedBatchGroups_;
  227. /// Maximum sorted instances.
  228. unsigned maxSortedInstances_;
  229. };
  230. /// Queue for shadow map draw calls
  231. struct ShadowBatchQueue
  232. {
  233. /// Shadow map camera.
  234. Camera* shadowCamera_;
  235. /// Shadow map viewport.
  236. IntRect shadowViewport_;
  237. /// Shadow caster draw calls.
  238. BatchQueue shadowBatches_;
  239. /// Directional light cascade near split distance.
  240. float nearSplit_;
  241. /// Directional light cascade far split distance.
  242. float farSplit_;
  243. };
  244. /// Queue for light related draw calls.
  245. struct LightBatchQueue
  246. {
  247. /// Per-pixel light.
  248. Light* light_;
  249. /// Shadow map depth texture.
  250. Texture2D* shadowMap_;
  251. /// Lit geometry draw calls, base (replace blend mode)
  252. BatchQueue litBaseBatches_;
  253. /// Lit geometry draw calls, non-base (additive)
  254. BatchQueue litBatches_;
  255. /// Shadow map split queues.
  256. Vector<ShadowBatchQueue> shadowSplits_;
  257. /// Per-vertex lights.
  258. PODVector<Light*> vertexLights_;
  259. /// Light volume draw calls.
  260. PODVector<Batch> volumeBatches_;
  261. };
  262. }