#ifndef LIGHT_NODE_HPP
#define LIGHT_NODE_HPP
#include "Constants.hpp"
#include "GlslLayout.hpp"
#include "Node.hpp"
#include <numeric>
#include <vector>
namespace wren {
class Camera;
class DirectionalLight;
class FrameBuffer;
class PointLight;
class ShaderProgram;
class ShadowVolumeCaster;
class SpotLight;
class TextureRtt;
class LightNode : public Node {
public:
enum Type { TYPE_DIRECTIONAL, TYPE_POINT, TYPE_SPOT, TYPE_COUNT };
static void setAmbientLight(const glm::vec3 &ambientLight) { cGlobalAmbientIntensity = ambientLight; }
static int activeLightsCastingShadows() {
return std::accumulate(cActiveLightsCastingShadows.begin(), cActiveLightsCastingShadows.end(), 0);
}
static int activeLightsCastingShadows(Type type) { return cActiveLightsCastingShadows[type]; }
static void updateUniforms();
static const glm::vec3 &ambientLight() { return cGlobalAmbientIntensity; }
void setOn(bool on);
void setCastShadows(bool castShadows);
void setColor(const glm::vec3 &color);
void setIntensity(float intensity) { mIntensity = intensity; }
void setAmbientIntensity(float ambientIntensity) { mAmbientIntensity = ambientIntensity; }
void registerShadowListener(ShadowVolumeCaster *listener) { mShadowListeners.emplace(listener, listener); }
void unregisterShadowListener(ShadowVolumeCaster *listener) { mShadowListeners.erase(listener); }
const glm::vec3 &color() const { return mColor; }
float intensity() const { return mIntensity; }
float ambientIntensity() const { return mAmbientIntensity; }
bool on() const { return mOn; }
bool castShadows() const { return mCastShadows; }
virtual LightNode::Type type() = 0;
protected:
LightNode();
virtual ~LightNode();
static std::vector<int> cActiveLightsCastingShadows;
std::unordered_map<ShadowVolumeCaster *, ShadowVolumeCaster *> mShadowListeners;
private:
void enableShadowCasting();
void disableShadowCasting();
static glm::vec3 cGlobalAmbientIntensity;
static GlslLayout::Lights cActiveLights;
bool mOn;
bool mCastShadows;
float mIntensity;
float mAmbientIntensity;
glm::vec3 mColor;
};
}
#endif