Batch.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 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 "HashMap.h"
  25. #include "MathDefs.h"
  26. #include "GraphicsDefs.h"
  27. #include "Ptr.h"
  28. #include "Vector4.h"
  29. class Camera;
  30. class Drawable;
  31. class Geometry;
  32. class Graphics;
  33. class Light;
  34. class Material;
  35. class Pass;
  36. class Matrix3x4;
  37. class ShaderVariation;
  38. class VertexBuffer;
  39. /// Description of a 3D geometry draw call
  40. struct Batch
  41. {
  42. /// Construct with defaults
  43. Batch() :
  44. light_(0),
  45. shaderData_(0),
  46. shaderDataSize_(0),
  47. geometryType_(GEOM_STATIC),
  48. overrideView_(false),
  49. hasPriority_(false)
  50. {
  51. }
  52. /// Calculate sort key, which consists of priority flag, light, pass and geometry
  53. void CalculateSortKey();
  54. /// Prepare for rendering
  55. void Prepare(Graphics* graphics, const HashMap<StringHash, Vector4>& shaderParameters, bool setModelTransform = true) const;
  56. /// Prepare and draw
  57. void Draw(Graphics* graphics, const HashMap<StringHash, Vector4>& shaderParameters) const;
  58. /// Geometry
  59. Geometry* geometry_;
  60. /// Model world transform
  61. const Matrix3x4* worldTransform_;
  62. /// Camera
  63. Camera* camera_;
  64. /// Light that affects the geometry, if any
  65. Light* light_;
  66. /// Material
  67. Material* material_;
  68. /// Material pass
  69. Pass* pass_;
  70. /// Vertex shader
  71. ShaderVariation* vertexShader_;
  72. /// Pixel shader
  73. ShaderVariation* pixelShader_;
  74. /// Vertex shader data
  75. const float* shaderData_;
  76. /// Vertex shader data size in floats
  77. unsigned shaderDataSize_;
  78. /// Distance from camera
  79. float distance_;
  80. /// Geometry type
  81. GeometryType geometryType_;
  82. /// Vertex shader index
  83. unsigned char vertexShaderIndex_;
  84. /// Override view transform flag
  85. bool overrideView_;
  86. /// Priority flag
  87. bool hasPriority_;
  88. /// State sorting key
  89. unsigned long long sortKey_;
  90. };
  91. /// Data for one geometry instance
  92. struct InstanceData
  93. {
  94. /// Construct undefined
  95. InstanceData()
  96. {
  97. }
  98. /// Construct with transform and distance
  99. InstanceData(const Matrix3x4* worldTransform, float distance) :
  100. worldTransform_(worldTransform),
  101. distance_(distance)
  102. {
  103. }
  104. /// World transform
  105. const Matrix3x4* worldTransform_;
  106. /// Distance from camera
  107. float distance_;
  108. };
  109. /// Instanced 3D geometry draw call
  110. struct BatchGroup
  111. {
  112. /// Construct with defaults
  113. BatchGroup() :
  114. startIndex_(M_MAX_UNSIGNED)
  115. {
  116. }
  117. /// Destruct
  118. ~BatchGroup()
  119. {
  120. }
  121. /// Pre-set the instance transforms. Buffer must be big enough to hold all transforms
  122. void SetTransforms(void* lockedData, unsigned& freeIndex);
  123. /// Prepare and draw
  124. void Draw(Graphics* graphics, VertexBuffer* instanceBuffer, const HashMap<StringHash, Vector4>& shaderParameters) const;
  125. /// Geometry
  126. Geometry* geometry_;
  127. /// Instance data
  128. PODVector<InstanceData> instances_;
  129. /// Camera
  130. Camera* camera_;
  131. /// Light that affects the geometry, if any
  132. Light* light_;
  133. /// Material
  134. Material* material_;
  135. /// Material pass
  136. Pass* pass_;
  137. /// Vertex shader
  138. ShaderVariation* vertexShader_;
  139. /// Pixel shader
  140. ShaderVariation* pixelShader_;
  141. /// Vertex shader index
  142. unsigned char vertexShaderIndex_;
  143. /// Instance stream start index, or M_MAX_UNSIGNED if transforms not pre-set
  144. unsigned startIndex_;
  145. };
  146. /// Instanced draw call key
  147. struct BatchGroupKey
  148. {
  149. /// Light that affects the geometry, if any
  150. Light* light_;
  151. /// Material pass
  152. Pass* pass_;
  153. /// Material
  154. Material* material_;
  155. /// Geometry
  156. Geometry* geometry_;
  157. /// Test for equality with another batch group key
  158. bool operator == (const BatchGroupKey& rhs) const { return light_ == rhs.light_ && pass_ == rhs.pass_ && material_ == rhs.material_ && geometry_ == rhs.geometry_; }
  159. /// Test for inequality with another batch group key
  160. bool operator != (const BatchGroupKey& rhs) const { return light_ != rhs.light_ || pass_ != rhs.pass_ || material_ != rhs.material_ || geometry_ != rhs.geometry_; }
  161. /// Test if less than another batch group key
  162. bool operator < (const BatchGroupKey& rhs) const
  163. {
  164. if (light_ == rhs.light_)
  165. {
  166. if (pass_ == rhs.pass_)
  167. {
  168. if (material_ == rhs.material_)
  169. return geometry_ < rhs.geometry_;
  170. else
  171. return material_ < rhs.material_;
  172. }
  173. else
  174. return pass_ < rhs.pass_;
  175. }
  176. else
  177. return light_ < rhs.light_;
  178. }
  179. /// Test if greater than another batch group key
  180. bool operator > (const BatchGroupKey& rhs) const
  181. {
  182. if (light_ == rhs.light_)
  183. {
  184. if (pass_ == rhs.pass_)
  185. {
  186. if (material_ == rhs.material_)
  187. return geometry_ > rhs.geometry_;
  188. else
  189. return material_ > rhs.material_;
  190. }
  191. else
  192. return pass_ > rhs.pass_;
  193. }
  194. else
  195. return light_ > rhs.light_;
  196. }
  197. };
  198. /// Queue that contains both instanced and non-instanced draw calls
  199. struct BatchQueue
  200. {
  201. public:
  202. /// Clear everything
  203. void Clear();
  204. /// Add a batch, with instancing if possible
  205. void AddBatch(const Batch& batch, bool noInstancing = false);
  206. /// Sort non-instanced draw calls back to front
  207. void SortBackToFront();
  208. /// Sort instanced and non-instanced draw calls front to back
  209. void SortFrontToBack();
  210. /// Pre-set instance transforms of all groups. The vertex buffer must be big enough to hold all transforms
  211. void SetTransforms(void* lockedData, unsigned& freeIndex);
  212. /// Return the combined amount of instances
  213. unsigned GetNumInstances() const;
  214. /// Unsorted non-instanced draw calls
  215. PODVector<Batch> batches_;
  216. /// Sorted non-instanced draw calls with priority flag
  217. PODVector<Batch*> sortedPriorityBatches_;
  218. /// Sorted non-instanced draw calls
  219. PODVector<Batch*> sortedBatches_;
  220. /// Instanced draw calls with priority flag
  221. Map<BatchGroupKey, BatchGroup> priorityBatchGroups_;
  222. /// Instanced draw calls
  223. Map<BatchGroupKey, BatchGroup> batchGroups_;
  224. };
  225. /// Queue for light related draw calls
  226. struct LightBatchQueue
  227. {
  228. /// Light drawable
  229. Light* light_;
  230. /// Shadowcaster draw calls
  231. BatchQueue shadowBatches_;
  232. /// Lit geometry draw calls
  233. BatchQueue litBatches_;
  234. /// Light volume draw calls, should be only one
  235. PODVector<Batch> volumeBatches_;
  236. /// Last split flag for clearing the stencil buffer
  237. bool lastSplit_;
  238. };