#define MSP_GL_SHADOWMAP_H_
#include "camera.h"
-#include "depthtest.h"
#include "effect.h"
#include "framebuffer.h"
#include "programdata.h"
+#include "rect.h"
#include "texture2d.h"
#include "vector.h"
namespace Msp {
namespace GL {
+class DirectionalLight;
class Light;
+class PointLight;
/**
Creates shadows on a renderable through a shadow map texture. In the setup
*/
class ShadowMap: public Effect
{
+public:
+ struct Template: Effect::Template
+ {
+ class Loader: public DataFile::DerivedObjectLoader<Template, Effect::Template::Loader>
+ {
+ private:
+ static ActionMap shared_actions;
+
+ public:
+ Loader(Template &, Collection &);
+ private:
+ virtual void init_actions();
+
+ void light(const std::string &);
+ void size_square(unsigned);
+ void target(float, float, float);
+ };
+
+ struct ShadowedLight
+ {
+ class Loader: public DataFile::ObjectLoader<ShadowedLight>
+ {
+ private:
+ static ActionMap shared_actions;
+
+ public:
+ Loader(ShadowedLight &);
+ private:
+ virtual void init_actions();
+ };
+
+ const Light *light = 0;
+ unsigned size;
+ std::string shadow_caster_name;
+ };
+
+ unsigned width = 2048;
+ unsigned height = 2048;
+ const Lighting *lighting = 0;
+ std::vector<ShadowedLight> lights;
+ Vector3 target;
+ float radius = 1.0f;
+ float depth_bias = 4.0f;
+ float darkness = 1.0f;
+
+ virtual ShadowMap *create(const std::map<std::string, Renderable *> &) const;
+ };
+
private:
- unsigned size;
- const Light &light;
- Renderable &shadow_caster;
+ enum ShadowType
+ {
+ NONE,
+ DIRECTIONAL,
+ TETRAHEDRON
+ };
+
+ struct ShadowedLight
+ {
+ const Light *light;
+ unsigned index;
+ Rect region;
+ ShadowType type;
+ unsigned view_index;
+ Renderable *shadow_caster;
+ };
+
+ struct ShadowView
+ {
+ unsigned light_index;
+ unsigned face;
+ Camera camera;
+ Matrix face_matrix;
+ };
+
+ unsigned width;
+ unsigned height;
+ const Lighting *lighting;
+ std::vector<ShadowedLight> lights;
+ std::vector<ShadowView> views;
Framebuffer fbo;
- Camera shadow_camera;
- Matrix shadow_matrix;
Texture2D depth_buf;
- DepthTest depth_test;
const Sampler &sampler;
Vector3 target;
- float radius;
- float depth_bias;
+ float radius = 1.0f;
+ float depth_bias = 4.0f;
+ float darkness = 1.0f;
ProgramData shdata;
- bool rendered;
+ bool rendered = false;
+ std::string debug_name;
+ ShadowMap(unsigned, unsigned, Renderable &, const Lighting *);
public:
- ShadowMap(unsigned, Renderable &, const Light &, Renderable &);
+ ShadowMap(unsigned, Renderable &, const DirectionalLight &, Renderable &);
+ ShadowMap(unsigned, unsigned, Renderable &, const Lighting &);
+ void add_light(const DirectionalLight &, unsigned, Renderable &);
+ void add_light(const PointLight &, unsigned, Renderable &);
+private:
+ void add_light(const Light &, unsigned, ShadowType, Renderable &);
+
+public:
/** Sets the ShadowMap target point and radius. The transformation matrix is
computed so that a sphere with the specified parameters will be completely
covered by the ShadowMap. */
void set_depth_bias(float);
const Texture2D &get_depth_texture() const { return depth_buf; }
- const Matrix &get_shadow_matrix() const { return shadow_matrix; }
virtual void setup_frame(Renderer &);
virtual void finish_frame();