LightSystem.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #pragma once
  2. #include "../quadtree/DynamicQuadtree.h"
  3. #include "LightPointEmission.h"
  4. #include "LightDirectionEmission.h"
  5. #include "LightShape.h"
  6. #include "NormalsSprite.h"
  7. #include "../tools/pool.h"
  8. #include <unordered_set>
  9. namespace ltbl
  10. {
  11. class LightSystem : sf::NonCopyable
  12. {
  13. friend class LightPointEmission;
  14. friend class LightDirectionEmission;
  15. friend class LightShape;
  16. public:
  17. struct Penumbra {
  18. sf::Vector2f _source;
  19. sf::Vector2f _lightEdge;
  20. sf::Vector2f _darkEdge;
  21. float _lightBrightness;
  22. float _darkBrightness;
  23. float _distance;
  24. };
  25. private:
  26. sf::RenderTexture _lightTempTexture, _emissionTempTexture, _antumbraTempTexture, _compositionTexture, _normalsTexture;
  27. static void getPenumbrasPoint(std::vector<Penumbra> &penumbras, std::vector<int> &innerBoundaryIndices, std::vector<sf::Vector2f> &innerBoundaryVectors, std::vector<int> &outerBoundaryIndices, std::vector<sf::Vector2f> &outerBoundaryVectors, const sf::ConvexShape &shape, const sf::Vector2f &sourceCenter, float sourceRadius);
  28. static void getPenumbrasDirection(std::vector<Penumbra> &penumbras, std::vector<int> &innerBoundaryIndices, std::vector<sf::Vector2f> &innerBoundaryVectors, std::vector<int> &outerBoundaryIndices, std::vector<sf::Vector2f> &outerBoundaryVectors, const sf::ConvexShape &shape, const sf::Vector2f &sourceDirection, float sourceRadius, float sourceDistance);
  29. DynamicQuadtree _shapeQuadtree;
  30. DynamicQuadtree _lightPointEmissionQuadtree;
  31. std::unordered_set<std::shared_ptr<LightPointEmission>> _pointEmissionLights;
  32. std::unordered_set<std::shared_ptr<LightDirectionEmission>> _directionEmissionLights;
  33. //! Pool for light shapes.
  34. //! The idea is that even if there will be cache misses (because of the QuadTree),
  35. //! shapes are more likely to be in the CPU L2 or L3 cache.
  36. //! We currently allow 2048 shapes maximum.
  37. MemoryPool<LightShape, sizeof(LightShape) * 2048u> _lightShapesPool;
  38. public:
  39. float _directionEmissionRange;
  40. float _directionEmissionRadiusMultiplier;
  41. sf::Color _ambientColor;
  42. bool _normalsEnabled = false;
  43. LightSystem()
  44. : _directionEmissionRange(10000.0f), _directionEmissionRadiusMultiplier(1.1f), _ambientColor(sf::Color(16, 16, 16))
  45. {}
  46. void create(const sf::FloatRect& rootRegion, const sf::Vector2u& imageSize,
  47. const sf::Texture& penumbraTexture,
  48. sf::Shader& unshadowShader, sf::Shader& lightOverShapeShader, sf::Shader& normalsShader);
  49. void render(const sf::View &view,
  50. sf::Shader &unshadowShader, sf::Shader &lightOverShapeShader, sf::Shader& normalsShader);
  51. //! Request a new shape from the pool.
  52. LightShape* allocateShape();
  53. //! Destroy a previously allocated shape from the pool.
  54. void deallocateShape(LightShape* pLightShape);
  55. //! Add the shape to the quadtree.
  56. void addShape(LightShape* pLightShape);
  57. //! Remove the shape from the quadtree.
  58. void removeShape(LightShape* pLightShape);
  59. void addLight(const std::shared_ptr<LightPointEmission> &pointEmissionLight);
  60. void addLight(const std::shared_ptr<LightDirectionEmission> &directionEmissionLight);
  61. void removeLight(const std::shared_ptr<LightPointEmission> &pointEmissionLight);
  62. void removeLight(const std::shared_ptr<LightDirectionEmission> &directionEmissionLight);
  63. void trimLightPointEmissionQuadtree() {
  64. _lightPointEmissionQuadtree.trim();
  65. }
  66. void trimShapeQuadtree() {
  67. _shapeQuadtree.trim();
  68. }
  69. const sf::Texture &getLightingTexture() const {
  70. return _compositionTexture.getTexture();
  71. }
  72. //----- Normals -----//
  73. //! Whether the light system should consider the normals target.
  74. void normalsEnabled(bool enabled);
  75. //! Set the normals texture view.
  76. void normalsTargetSetView(sf::View view);
  77. //! Clear the normals texture.
  78. void normalsTargetClear();
  79. //! Display the normals target.
  80. void normalsTargetDisplay();
  81. //! Draw a sf::Drawable (usually a Sprite containing the normals texture) into the texture target.
  82. void normalsTargetDraw(const sf::Drawable& drawable, sf::RenderStates states = sf::RenderStates());
  83. };
  84. }