primitive_batch.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #pragma once
  2. #include <QMatrix4x4>
  3. #include <QVector3D>
  4. #include <QVector4D>
  5. #include <cstddef>
  6. #include <cstdint>
  7. #include <vector>
  8. namespace Render::GL {
  9. class Buffer;
  10. class Mesh;
  11. struct PrimitiveInstanceGpu {
  12. QVector4D model_col0{1.0F, 0.0F, 0.0F, 0.0F};
  13. QVector4D model_col1{0.0F, 1.0F, 0.0F, 0.0F};
  14. QVector4D model_col2{0.0F, 0.0F, 1.0F, 0.0F};
  15. QVector4D color_alpha{1.0F, 1.0F, 1.0F, 1.0F};
  16. void set_transform(const QMatrix4x4 &m) {
  17. model_col0 = QVector4D(m(0, 0), m(1, 0), m(2, 0), m(0, 3));
  18. model_col1 = QVector4D(m(0, 1), m(1, 1), m(2, 1), m(1, 3));
  19. model_col2 = QVector4D(m(0, 2), m(1, 2), m(2, 2), m(2, 3));
  20. }
  21. void set_color(const QVector3D &color, float alpha = 1.0F) {
  22. color_alpha = QVector4D(color.x(), color.y(), color.z(), alpha);
  23. }
  24. };
  25. static_assert(sizeof(PrimitiveInstanceGpu) == 64,
  26. "PrimitiveInstanceGpu must be 64 bytes for GPU alignment");
  27. struct PrimitiveBatchParams {
  28. QMatrix4x4 view_proj;
  29. QVector3D light_direction{0.35F, 0.8F, 0.45F};
  30. float ambient_strength{0.3F};
  31. };
  32. enum class PrimitiveType : uint8_t { Sphere = 0, Cylinder = 1, Cone = 2 };
  33. struct PrimitiveBatchCmd {
  34. PrimitiveType type{PrimitiveType::Sphere};
  35. std::vector<PrimitiveInstanceGpu> instances;
  36. PrimitiveBatchParams params;
  37. [[nodiscard]] auto instance_count() const -> std::size_t {
  38. return instances.size();
  39. }
  40. [[nodiscard]] auto instance_data() const -> const PrimitiveInstanceGpu * {
  41. return instances.empty() ? nullptr : instances.data();
  42. }
  43. };
  44. class PrimitiveBatcher {
  45. public:
  46. PrimitiveBatcher();
  47. ~PrimitiveBatcher();
  48. void add_sphere(const QMatrix4x4 &transform, const QVector3D &color,
  49. float alpha = 1.0F);
  50. void add_cylinder(const QMatrix4x4 &transform, const QVector3D &color,
  51. float alpha = 1.0F);
  52. void add_cone(const QMatrix4x4 &transform, const QVector3D &color,
  53. float alpha = 1.0F);
  54. [[nodiscard]] auto sphere_count() const -> std::size_t {
  55. return m_spheres.size();
  56. }
  57. [[nodiscard]] auto cylinder_count() const -> std::size_t {
  58. return m_cylinders.size();
  59. }
  60. [[nodiscard]] auto cone_count() const -> std::size_t {
  61. return m_cones.size();
  62. }
  63. [[nodiscard]] auto total_count() const -> std::size_t {
  64. return m_spheres.size() + m_cylinders.size() + m_cones.size();
  65. }
  66. [[nodiscard]] auto
  67. sphere_data() const -> const std::vector<PrimitiveInstanceGpu> & {
  68. return m_spheres;
  69. }
  70. [[nodiscard]] auto
  71. cylinder_data() const -> const std::vector<PrimitiveInstanceGpu> & {
  72. return m_cylinders;
  73. }
  74. [[nodiscard]] auto
  75. cone_data() const -> const std::vector<PrimitiveInstanceGpu> & {
  76. return m_cones;
  77. }
  78. void clear();
  79. void reserve(std::size_t spheres, std::size_t cylinders, std::size_t cones);
  80. private:
  81. std::vector<PrimitiveInstanceGpu> m_spheres;
  82. std::vector<PrimitiveInstanceGpu> m_cylinders;
  83. std::vector<PrimitiveInstanceGpu> m_cones;
  84. };
  85. struct PrimitiveBatchStats {
  86. uint32_t spheres_submitted{0};
  87. uint32_t cylinders_submitted{0};
  88. uint32_t cones_submitted{0};
  89. uint32_t batches_rendered{0};
  90. uint32_t draw_calls_saved{0};
  91. void reset() {
  92. spheres_submitted = 0;
  93. cylinders_submitted = 0;
  94. cones_submitted = 0;
  95. batches_rendered = 0;
  96. draw_calls_saved = 0;
  97. }
  98. };
  99. auto get_primitive_batch_stats() -> const PrimitiveBatchStats &;
  100. void reset_primitive_batch_stats();
  101. } // namespace Render::GL