Batch.h 7.2 KB

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