Batch.h 9.6 KB

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