Batch.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. //
  2. // Copyright (c) 2008-2015 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 "../Container/Ptr.h"
  24. #include "../Graphics/Drawable.h"
  25. #include "../Graphics/Material.h"
  26. #include "../Math/MathDefs.h"
  27. #include "../Math/Matrix3x4.h"
  28. #include "../Math/Rect.h"
  29. namespace Atomic
  30. {
  31. class Camera;
  32. class Drawable;
  33. class Geometry;
  34. class Light;
  35. class Material;
  36. class Matrix3x4;
  37. class Pass;
  38. class ShaderVariation;
  39. class Texture2D;
  40. class VertexBuffer;
  41. class View;
  42. class Zone;
  43. struct LightBatchQueue;
  44. /// Queued 3D geometry draw call.
  45. struct Batch
  46. {
  47. /// Construct with defaults.
  48. Batch() :
  49. isBase_(false),
  50. lightQueue_(0)
  51. {
  52. }
  53. /// Construct from a drawable's source batch.
  54. Batch(const SourceBatch& rhs) :
  55. distance_(rhs.distance_),
  56. renderOrder_(rhs.material_ ? rhs.material_->GetRenderOrder() : DEFAULT_RENDER_ORDER),
  57. isBase_(false),
  58. geometry_(rhs.geometry_),
  59. material_(rhs.material_),
  60. worldTransform_(rhs.worldTransform_),
  61. numWorldTransforms_(rhs.numWorldTransforms_),
  62. lightQueue_(0),
  63. geometryType_(rhs.geometryType_)
  64. {
  65. }
  66. /// Calculate state sorting key, which consists of base pass flag, light, pass and geometry.
  67. void CalculateSortKey();
  68. /// Prepare for rendering.
  69. void Prepare(View* view, bool setModelTransform, bool allowDepthWrite) const;
  70. /// Prepare and draw.
  71. void Draw(View* view, bool allowDepthWrite) const;
  72. /// State sorting key.
  73. unsigned long long sortKey_;
  74. /// Distance from camera.
  75. float distance_;
  76. /// 8-bit render order modifier from material.
  77. unsigned char renderOrder_;
  78. /// 8-bit light mask for stencil marking in deferred rendering.
  79. unsigned char lightMask_;
  80. /// Base batch flag. This tells to draw the object fully without light optimizations.
  81. bool isBase_;
  82. /// Geometry.
  83. Geometry* geometry_;
  84. /// Material.
  85. Material* material_;
  86. /// World transform(s). For a skinned model, these are the bone transforms.
  87. const Matrix3x4* worldTransform_;
  88. /// Number of world transforms.
  89. unsigned numWorldTransforms_;
  90. /// Camera.
  91. Camera* camera_;
  92. /// Zone.
  93. Zone* zone_;
  94. /// Light properties.
  95. LightBatchQueue* lightQueue_;
  96. /// Material pass.
  97. Pass* pass_;
  98. /// Vertex shader.
  99. ShaderVariation* vertexShader_;
  100. /// Pixel shader.
  101. ShaderVariation* pixelShader_;
  102. /// %Geometry type.
  103. GeometryType geometryType_;
  104. };
  105. /// Data for one geometry instance.
  106. struct InstanceData
  107. {
  108. /// Construct undefined.
  109. InstanceData()
  110. {
  111. }
  112. /// Construct with transform and distance.
  113. InstanceData(const Matrix3x4* worldTransform, float distance) :
  114. worldTransform_(worldTransform),
  115. distance_(distance)
  116. {
  117. }
  118. /// World transform.
  119. const Matrix3x4* worldTransform_;
  120. /// Distance from camera.
  121. float distance_;
  122. };
  123. /// Instanced 3D geometry draw call.
  124. struct BatchGroup : public Batch
  125. {
  126. /// Construct with defaults.
  127. BatchGroup() :
  128. startIndex_(M_MAX_UNSIGNED)
  129. {
  130. }
  131. /// Construct from a batch.
  132. BatchGroup(const Batch& batch) :
  133. Batch(batch),
  134. startIndex_(M_MAX_UNSIGNED)
  135. {
  136. }
  137. /// Destruct.
  138. ~BatchGroup()
  139. {
  140. }
  141. /// Add world transform(s) from a batch.
  142. void AddTransforms(const Batch& batch)
  143. {
  144. InstanceData newInstance;
  145. newInstance.distance_ = batch.distance_;
  146. for (unsigned i = 0; i < batch.numWorldTransforms_; ++i)
  147. {
  148. newInstance.worldTransform_ = &batch.worldTransform_[i];
  149. instances_.Push(newInstance);
  150. }
  151. }
  152. /// Pre-set the instance transforms. Buffer must be big enough to hold all transforms.
  153. void SetTransforms(void* lockedData, unsigned& freeIndex);
  154. /// Prepare and draw.
  155. void Draw(View* view, bool allowDepthWrite) const;
  156. /// Instance data.
  157. PODVector<InstanceData> instances_;
  158. /// Instance stream start index, or M_MAX_UNSIGNED if transforms not pre-set.
  159. unsigned startIndex_;
  160. };
  161. /// Instanced draw call grouping key.
  162. struct BatchGroupKey
  163. {
  164. /// Construct undefined.
  165. BatchGroupKey()
  166. {
  167. }
  168. /// Construct from a batch.
  169. BatchGroupKey(const Batch& batch) :
  170. zone_(batch.zone_),
  171. lightQueue_(batch.lightQueue_),
  172. pass_(batch.pass_),
  173. material_(batch.material_),
  174. geometry_(batch.geometry_),
  175. renderOrder_(batch.renderOrder_)
  176. {
  177. }
  178. /// Zone.
  179. Zone* zone_;
  180. /// Light properties.
  181. LightBatchQueue* lightQueue_;
  182. /// Material pass.
  183. Pass* pass_;
  184. /// Material.
  185. Material* material_;
  186. /// Geometry.
  187. Geometry* geometry_;
  188. /// 8-bit render order modifier from material.
  189. unsigned char renderOrder_;
  190. /// Test for equality with another batch group key.
  191. bool operator ==(const BatchGroupKey& rhs) const
  192. {
  193. return zone_ == rhs.zone_ && lightQueue_ == rhs.lightQueue_ && pass_ == rhs.pass_ && material_ == rhs.material_ &&
  194. geometry_ == rhs.geometry_ && renderOrder_ == rhs.renderOrder_;
  195. }
  196. /// Test for inequality with another batch group key.
  197. bool operator !=(const BatchGroupKey& rhs) const
  198. {
  199. return zone_ != rhs.zone_ || lightQueue_ != rhs.lightQueue_ || pass_ != rhs.pass_ || material_ != rhs.material_ ||
  200. geometry_ != rhs.geometry_ || renderOrder_ != rhs.renderOrder_;
  201. }
  202. /// Return hash value.
  203. unsigned ToHash() const;
  204. };
  205. /// Queue that contains both instanced and non-instanced draw calls.
  206. struct BatchQueue
  207. {
  208. public:
  209. /// Clear for new frame by clearing all groups and batches.
  210. void Clear(int maxSortedInstances);
  211. /// Sort non-instanced draw calls back to front.
  212. void SortBackToFront();
  213. /// Sort instanced and non-instanced draw calls front to back.
  214. void SortFrontToBack();
  215. /// Sort batches front to back while also maintaining state sorting.
  216. void SortFrontToBack2Pass(PODVector<Batch*>& batches);
  217. /// Pre-set instance transforms of all groups. The vertex buffer must be big enough to hold all transforms.
  218. void SetTransforms(void* lockedData, unsigned& freeIndex);
  219. /// Draw.
  220. void Draw(View* view, bool markToStencil, bool usingLightOptimization, bool allowDepthWrite) const;
  221. /// Return the combined amount of instances.
  222. unsigned GetNumInstances() const;
  223. /// Return whether the batch group is empty.
  224. bool IsEmpty() const { return batches_.Empty() && batchGroups_.Empty(); }
  225. /// Instanced draw calls.
  226. HashMap<BatchGroupKey, BatchGroup> batchGroups_;
  227. /// Shader remapping table for 2-pass state and distance sort.
  228. HashMap<unsigned, unsigned> shaderRemapping_;
  229. /// Material remapping table for 2-pass state and distance sort.
  230. HashMap<unsigned short, unsigned short> materialRemapping_;
  231. /// Geometry remapping table for 2-pass state and distance sort.
  232. HashMap<unsigned short, unsigned short> geometryRemapping_;
  233. /// Unsorted non-instanced draw calls.
  234. PODVector<Batch> batches_;
  235. /// Sorted non-instanced draw calls.
  236. PODVector<Batch*> sortedBatches_;
  237. /// Sorted instanced draw calls.
  238. PODVector<BatchGroup*> sortedBatchGroups_;
  239. /// Maximum sorted instances.
  240. unsigned maxSortedInstances_;
  241. };
  242. /// Queue for shadow map draw calls
  243. struct ShadowBatchQueue
  244. {
  245. /// Shadow map camera.
  246. Camera* shadowCamera_;
  247. /// Shadow map viewport.
  248. IntRect shadowViewport_;
  249. /// Shadow caster draw calls.
  250. BatchQueue shadowBatches_;
  251. /// Directional light cascade near split distance.
  252. float nearSplit_;
  253. /// Directional light cascade far split distance.
  254. float farSplit_;
  255. };
  256. /// Queue for light related draw calls.
  257. struct LightBatchQueue
  258. {
  259. /// Per-pixel light.
  260. Light* light_;
  261. /// Light negative flag.
  262. bool negative_;
  263. /// Shadow map depth texture.
  264. Texture2D* shadowMap_;
  265. /// Lit geometry draw calls, base (replace blend mode)
  266. BatchQueue litBaseBatches_;
  267. /// Lit geometry draw calls, non-base (additive)
  268. BatchQueue litBatches_;
  269. /// Shadow map split queues.
  270. Vector<ShadowBatchQueue> shadowSplits_;
  271. /// Per-vertex lights.
  272. PODVector<Light*> vertexLights_;
  273. /// Light volume draw calls.
  274. PODVector<Batch> volumeBatches_;
  275. };
  276. }