AuxGeomBase.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <AzCore/std/containers/vector.h>
  10. #include <AzCore/Math/Transform.h>
  11. #include <AzCore/Math/Matrix3x3.h>
  12. #include <AzCore/Math/Color.h>
  13. #include <Atom/RHI/GeometryView.h>
  14. #include <Atom/RPI.Public/AuxGeom/AuxGeomDraw.h>
  15. namespace AZ
  16. {
  17. namespace Render
  18. {
  19. /**
  20. * Define common types used for data throughout the AuxGeom system
  21. */
  22. //! Index type used for indexed draws
  23. using AuxGeomIndex = u32;
  24. //! Colors are packed into one byte per color
  25. using AuxGeomColor = AZ::u32;
  26. /**
  27. * Positions are stored in this struct.
  28. * We use this struct rather than AZ::Vector3 because an AZStd::vector of AZ::Vector3 has a stride of 16 bytes because of
  29. * alignment constraints.
  30. */
  31. struct AuxGeomPosition
  32. {
  33. AuxGeomPosition(const AZ::Vector3& pos)
  34. {
  35. m_x = pos.GetX();
  36. m_y = pos.GetY();
  37. m_z = pos.GetZ();
  38. };
  39. AuxGeomPosition(float x, float y, float z)
  40. {
  41. m_x = x;
  42. m_y = y;
  43. m_z = z;
  44. };
  45. float m_x;
  46. float m_y;
  47. float m_z;
  48. };
  49. struct AuxGeomDynamicVertex
  50. {
  51. AuxGeomDynamicVertex(const AZ::Vector3& pos, AuxGeomColor color)
  52. : m_position(pos)
  53. , m_color(color)
  54. {
  55. };
  56. AuxGeomPosition m_position;
  57. AuxGeomColor m_color;
  58. };
  59. //! Used for dynamic primitives
  60. //! This is not a scoped enum because we want to be able to use its values as array indices
  61. enum AuxGeomPrimitiveType
  62. {
  63. PrimitiveType_PointList,
  64. PrimitiveType_LineList,
  65. PrimitiveType_TriangleList,
  66. PrimitiveType_Count
  67. };
  68. enum AuxGeomDepthReadType
  69. {
  70. DepthRead_On,
  71. DepthRead_Off,
  72. DepthRead_Count
  73. };
  74. enum AuxGeomDepthWriteType
  75. {
  76. DepthWrite_On,
  77. DepthWrite_Off,
  78. DepthWrite_Count,
  79. };
  80. enum AuxGeomBlendMode
  81. {
  82. BlendMode_Alpha,
  83. BlendMode_Off,
  84. BlendMode_Count
  85. };
  86. enum AuxGeomFaceCullMode
  87. {
  88. FaceCull_None,
  89. FaceCull_Front,
  90. FaceCull_Back,
  91. FaceCull_Count
  92. };
  93. //! Each dynamic primitive drawn through the AuxGeom draw interface is stored in the scene data as an instance of this struct
  94. struct PrimitiveBufferEntry
  95. {
  96. RHI::GeometryView m_geometryView;
  97. AZ::Vector3 m_center; // used for depth sorting blended draws
  98. AuxGeomPrimitiveType m_primitiveType;
  99. AuxGeomDepthReadType m_depthReadType;
  100. AuxGeomDepthWriteType m_depthWriteType;
  101. AuxGeomFaceCullMode m_faceCullMode;
  102. AuxGeomBlendMode m_blendMode;
  103. AuxGeomIndex m_indexOffset; // The index into the shared index buffer for all primitives
  104. AuxGeomIndex m_indexCount; // The number of indices (a primitive can be a list of lines rather than one line for example)
  105. AZ::u8 m_width; // for points and lines
  106. //if < 0, then will render using the View's view and proj matrices, otherwise this indexes into AuxGeomBufferData::m_viewProjOverrides
  107. int32_t m_viewProjOverrideIndex = -1;
  108. };
  109. //! Internally we use a non-scoped enum for this so that we can use it as an index
  110. enum AuxGeomShapePerpectiveType
  111. {
  112. PerspectiveType_ViewProjection,
  113. PerspectiveType_ManualOverride, // View Perspective transform passed in through the view Projection override
  114. PerspectiveType_Count
  115. };
  116. //! Internally we use a non-scoped enum for this so that we can use it as an index
  117. enum AuxGeomDrawStyle
  118. {
  119. DrawStyle_Point,
  120. DrawStyle_Line,
  121. DrawStyle_Solid,
  122. DrawStyle_Shaded, // only available for fixed shapes.
  123. DrawStyle_Count
  124. };
  125. //! Used for shape objects
  126. //! This is not a scoped enum because we want to be able to use its values as array indices
  127. enum AuxGeomShapeType
  128. {
  129. ShapeType_Sphere,
  130. ShapeType_Hemisphere,
  131. ShapeType_Cone,
  132. ShapeType_Cylinder,
  133. ShapeType_CylinderNoEnds, // Cylinder without disks on either end
  134. ShapeType_Disk,
  135. ShapeType_Quad,
  136. ShapeType_Count
  137. };
  138. //! Each fixed shape drawn through the AuxGeom draw interface is stored in the scene data as an instance of this struct
  139. struct ShapeBufferEntry
  140. {
  141. AuxGeomShapeType m_shapeType;
  142. AuxGeomDepthReadType m_depthRead;
  143. AuxGeomDepthWriteType m_depthWrite;
  144. AuxGeomFaceCullMode m_faceCullMode;
  145. AZ::Color m_color;
  146. AZ::Vector3 m_position;
  147. AZ::Vector3 m_scale;
  148. AZ::Matrix3x3 m_rotationMatrix;
  149. //if < 0, then will render using the View's view and proj matrices, otherwise this indexes into AuxGeomBufferData::m_viewProjOverrides
  150. int32_t m_viewProjOverrideIndex = -1;
  151. float m_pointSize; // only used for DrawStyle_Point
  152. };
  153. //! Each box drawn through the AuxGeom draw interface is stored in the scene data as an instance of this struct
  154. //! Objects can either be Shapes or Boxes.
  155. //! Boxes are kept separate because they do not have LODs so they have a different processing path. It also saves the
  156. //! memory of storing a shape type for boxes.
  157. //! Keeping them in a separate list also makes instancing possible.
  158. struct BoxBufferEntry
  159. {
  160. AuxGeomDepthReadType m_depthRead;
  161. AuxGeomDepthWriteType m_depthWrite;
  162. AuxGeomFaceCullMode m_faceCullMode;
  163. AZ::Color m_color;
  164. AZ::Vector3 m_position;
  165. AZ::Vector3 m_scale;
  166. AZ::Matrix3x3 m_rotationMatrix;
  167. //if < 0, then will render using the View's view and proj matrices, otherwise this indexes into AuxGeomBufferData::m_viewProjOverrides
  168. int32_t m_viewProjOverrideIndex = -1;
  169. float m_pointSize; // only used for DrawStyle_Point
  170. };
  171. using PrimitiveBuffer = AZStd::vector<PrimitiveBufferEntry>;
  172. using VertexBuffer = AZStd::vector<AuxGeomDynamicVertex>;
  173. using IndexBuffer = AZStd::vector<AuxGeomIndex>;
  174. using ShapeBuffer = AZStd::vector<ShapeBufferEntry>;
  175. using BoxBuffer = AZStd::vector<BoxBufferEntry>;
  176. //! We have a single index and vertex buffer for all dynamic primitives.
  177. //! Each AuxGeom API call is a separate draw call
  178. struct DynamicPrimitiveData
  179. {
  180. PrimitiveBuffer m_primitiveBuffer; //!< State for each dynamic primitive draw
  181. VertexBuffer m_vertexBuffer; //!< The vertices for all dynamic verts
  182. IndexBuffer m_indexBuffer; //!< The indices for all dynamic primitives
  183. };
  184. //! This is all the data that is stored for each frame and returned from AuxGeomDrawQueue::Commit
  185. struct AuxGeomBufferData
  186. {
  187. DynamicPrimitiveData m_primitiveData; //!< The dynamic primitives
  188. ShapeBuffer m_opaqueShapes[DrawStyle_Count]; //!< The opaque shape objects
  189. ShapeBuffer m_translucentShapes[DrawStyle_Count]; //!< The translucent shape objects
  190. BoxBuffer m_opaqueBoxes[DrawStyle_Count]; //!< The opaque box objects
  191. BoxBuffer m_translucentBoxes[DrawStyle_Count]; //!< The translucent box objects
  192. AZStd::vector<AZ::Matrix4x4> m_viewProjOverrides;
  193. int32_t m_2DViewProjOverrideIndex = -1;
  194. };
  195. //! The maximum index allowed for of dynamic vertex indices
  196. static const size_t MaxDynamicVertexIndex = std::numeric_limits<AuxGeomIndex>::max();
  197. //! The maximum number of dynamic vertices we allow in one vertex buffer
  198. static const size_t MaxDynamicVertexCount = AZStd::min<size_t>(MaxDynamicVertexIndex + 1, 1*1024*1024); // limit max vertex count to 1M
  199. //! Utility functions to convert api enums to internal enums.
  200. //! We prefer scoped enums in public interfaces but internally we use the unscoped enum for array sizes,
  201. //! indices and loop counters.
  202. inline AuxGeomDrawStyle ConvertRPIDrawStyle(RPI::AuxGeomDraw::DrawStyle rpiDrawStyle)
  203. {
  204. switch (rpiDrawStyle)
  205. {
  206. case RPI::AuxGeomDraw::DrawStyle::Point: return DrawStyle_Point;
  207. case RPI::AuxGeomDraw::DrawStyle::Line: return DrawStyle_Line;
  208. case RPI::AuxGeomDraw::DrawStyle::Solid: return DrawStyle_Solid;
  209. case RPI::AuxGeomDraw::DrawStyle::Shaded: return DrawStyle_Shaded;
  210. }
  211. AZ_Assert(false, "Invalid RPI::DrawStyle value passed to AuxGeom");
  212. return DrawStyle_Count;
  213. }
  214. inline AuxGeomDepthReadType ConvertRPIDepthTestFlag(RPI::AuxGeomDraw::DepthTest rpiDepthTest)
  215. {
  216. switch (rpiDepthTest)
  217. {
  218. case RPI::AuxGeomDraw::DepthTest::On: return DepthRead_On;
  219. case RPI::AuxGeomDraw::DepthTest::Off: return DepthRead_Off;
  220. }
  221. AZ_Assert(false, "Invalid RPI::DepthTest value passed to AuxGeom");
  222. return DepthRead_Count;
  223. }
  224. inline AuxGeomDepthWriteType ConvertRPIDepthWriteFlag(RPI::AuxGeomDraw::DepthWrite rpiDepthWrite)
  225. {
  226. switch (rpiDepthWrite)
  227. {
  228. case RPI::AuxGeomDraw::DepthWrite::On: return DepthWrite_On;
  229. case RPI::AuxGeomDraw::DepthWrite::Off: return DepthWrite_Off;
  230. }
  231. AZ_Assert(false, "Invalid RPI::DepthWrite value passed to AuxGeom");
  232. return DepthWrite_Count;
  233. }
  234. inline AuxGeomFaceCullMode ConvertRPIFaceCullFlag(RPI::AuxGeomDraw::FaceCullMode rpiFaceCull)
  235. {
  236. switch(rpiFaceCull)
  237. {
  238. case RPI::AuxGeomDraw::FaceCullMode::None: return FaceCull_None;
  239. case RPI::AuxGeomDraw::FaceCullMode::Front: return FaceCull_Front;
  240. case RPI::AuxGeomDraw::FaceCullMode::Back: return FaceCull_Back;
  241. }
  242. AZ_Assert(false, "Invalid RPI::FaceCullMode value passed to AuxGeom");
  243. return FaceCull_Count;
  244. }
  245. } // namespace Render
  246. } // namespace AZ