123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- #pragma once
- #include "../quadtree/DynamicQuadtree.h"
- #include "LightPointEmission.h"
- #include "LightDirectionEmission.h"
- #include "LightShape.h"
- #include "NormalsSprite.h"
- #include "../tools/pool.h"
- #include <unordered_set>
- namespace ltbl
- {
- class LightSystem : sf::NonCopyable
- {
- friend class LightPointEmission;
- friend class LightDirectionEmission;
- friend class LightShape;
- public:
- struct Penumbra {
- sf::Vector2f _source;
- sf::Vector2f _lightEdge;
- sf::Vector2f _darkEdge;
- float _lightBrightness;
- float _darkBrightness;
- float _distance;
- };
- private:
- sf::RenderTexture _lightTempTexture, _emissionTempTexture, _antumbraTempTexture, _compositionTexture, _normalsTexture;
- 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);
- 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);
- DynamicQuadtree _shapeQuadtree;
- DynamicQuadtree _lightPointEmissionQuadtree;
- std::unordered_set<std::shared_ptr<LightPointEmission>> _pointEmissionLights;
- std::unordered_set<std::shared_ptr<LightDirectionEmission>> _directionEmissionLights;
- //! Pool for light shapes.
- //! The idea is that even if there will be cache misses (because of the QuadTree),
- //! shapes are more likely to be in the CPU L2 or L3 cache.
- //! We currently allow 2048 shapes maximum.
- MemoryPool<LightShape, sizeof(LightShape) * 2048u> _lightShapesPool;
- public:
- float _directionEmissionRange;
- float _directionEmissionRadiusMultiplier;
- sf::Color _ambientColor;
- bool _normalsEnabled = false;
- LightSystem()
- : _directionEmissionRange(10000.0f), _directionEmissionRadiusMultiplier(1.1f), _ambientColor(sf::Color(16, 16, 16))
- {}
- void create(const sf::FloatRect& rootRegion, const sf::Vector2u& imageSize,
- const sf::Texture& penumbraTexture,
- sf::Shader& unshadowShader, sf::Shader& lightOverShapeShader, sf::Shader& normalsShader);
- void render(const sf::View &view,
- sf::Shader &unshadowShader, sf::Shader &lightOverShapeShader, sf::Shader& normalsShader);
- //! Request a new shape from the pool.
- LightShape* allocateShape();
- //! Destroy a previously allocated shape from the pool.
- void deallocateShape(LightShape* pLightShape);
- //! Add the shape to the quadtree.
- void addShape(LightShape* pLightShape);
- //! Remove the shape from the quadtree.
- void removeShape(LightShape* pLightShape);
- void addLight(const std::shared_ptr<LightPointEmission> &pointEmissionLight);
- void addLight(const std::shared_ptr<LightDirectionEmission> &directionEmissionLight);
- void removeLight(const std::shared_ptr<LightPointEmission> &pointEmissionLight);
- void removeLight(const std::shared_ptr<LightDirectionEmission> &directionEmissionLight);
- void trimLightPointEmissionQuadtree() {
- _lightPointEmissionQuadtree.trim();
- }
- void trimShapeQuadtree() {
- _shapeQuadtree.trim();
- }
- const sf::Texture &getLightingTexture() const {
- return _compositionTexture.getTexture();
- }
- //----- Normals -----//
- //! Whether the light system should consider the normals target.
- void normalsEnabled(bool enabled);
- //! Set the normals texture view.
- void normalsTargetSetView(sf::View view);
- //! Clear the normals texture.
- void normalsTargetClear();
- //! Display the normals target.
- void normalsTargetDisplay();
- //! Draw a sf::Drawable (usually a Sprite containing the normals texture) into the texture target.
- void normalsTargetDraw(const sf::Drawable& drawable, sf::RenderStates states = sf::RenderStates());
- };
- }
|