]> git.tdb.fi Git - libs/gl.git/blob - source/effects/shadowmap.h
Refactor some parts of the Blender exporter to improve reusability
[libs/gl.git] / source / effects / shadowmap.h
1 #ifndef MSP_GL_SHADOWMAP_H_
2 #define MSP_GL_SHADOWMAP_H_
3
4 #include "camera.h"
5 #include "effect.h"
6 #include "framebuffer.h"
7 #include "programdata.h"
8 #include "rect.h"
9 #include "texture2d.h"
10 #include "vector.h"
11
12 namespace Msp {
13 namespace GL {
14
15 class DirectionalLight;
16 class Light;
17 class PointLight;
18
19 /**
20 Creates shadows on a renderable through a shadow map texture.  In the setup
21 phase, the scene is rendered to a depth texture from the point of view of the
22 lightsource.  This texture is then used in the rendering phase together with
23 texture coordinate generation to determine whether each fragment is lit.
24 */
25 class ShadowMap: public Effect
26 {
27 public:
28         struct Template: Effect::Template
29         {
30                 class Loader: public DataFile::DerivedObjectLoader<Template, Effect::Template::Loader>
31                 {
32                 private:
33                         static ActionMap shared_actions;
34
35                 public:
36                         Loader(Template &, Collection &);
37                 private:
38                         virtual void init_actions();
39
40                         void light(const std::string &);
41                         void size_square(unsigned);
42                         void target(float, float, float);
43                 };
44
45                 struct ShadowedLight
46                 {
47                         class Loader: public DataFile::ObjectLoader<ShadowedLight>
48                         {
49                         private:
50                                 static ActionMap shared_actions;
51
52                         public:
53                                 Loader(ShadowedLight &);
54                         private:
55                                 virtual void init_actions();
56                         };
57
58                         const Light *light = 0;
59                         unsigned size;
60                         std::string shadow_caster_name;
61                 };
62
63                 unsigned width = 2048;
64                 unsigned height = 2048;
65                 const Lighting *lighting = 0;
66                 std::vector<ShadowedLight> lights;
67                 Vector3 target;
68                 float radius = 1.0f;
69                 float depth_bias = 4.0f;
70                 float darkness = 1.0f;
71
72                 virtual ShadowMap *create(const std::map<std::string, Renderable *> &) const;
73         };
74
75 private:
76         enum ShadowType
77         {
78                 NONE,
79                 DIRECTIONAL,
80                 TETRAHEDRON
81         };
82
83         struct ShadowedLight
84         {
85                 const Light *light;
86                 unsigned index;
87                 Rect region;
88                 ShadowType type;
89                 unsigned view_index;
90                 Renderable *shadow_caster;
91         };
92
93         struct ShadowView
94         {
95                 unsigned light_index;
96                 unsigned face;
97                 Camera camera;
98                 Matrix face_matrix;
99         };
100
101         unsigned width;
102         unsigned height;
103         const Lighting *lighting;
104         std::vector<ShadowedLight> lights;
105         std::vector<ShadowView> views;
106         Framebuffer fbo;
107         Texture2D depth_buf;
108         const Sampler &sampler;
109         Vector3 target;
110         float radius = 1.0f;
111         float depth_bias = 4.0f;
112         float darkness = 1.0f;
113         ProgramData shdata;
114         bool rendered = false;
115         std::string debug_name;
116
117         ShadowMap(unsigned, unsigned, Renderable &, const Lighting *);
118 public:
119         ShadowMap(unsigned, Renderable &, const DirectionalLight &, Renderable &);
120         ShadowMap(unsigned, unsigned, Renderable &, const Lighting &);
121
122         void add_light(const DirectionalLight &, unsigned, Renderable &);
123         void add_light(const PointLight &, unsigned, Renderable &);
124 private:
125         void add_light(const Light &, unsigned, ShadowType, Renderable &);
126
127 public:
128         /** Sets the ShadowMap target point and radius.  The transformation matrix is
129         computed so that a sphere with the specified parameters will be completely
130         covered by the ShadowMap. */
131         void set_target(const Vector3 &, float);
132
133         /** Sets the darkness of shadows.  Must be in the range between 0.0 and 1.0,
134         inclusive.  Only usable with shaders, and provided through the
135         shadow_darkness uniform. */
136         void set_darkness(float);
137
138         /** Sets a distance beyond objects from which the shadow starts.  Expressed
139         in pixel-sized units.  Must be positive; values less than 1.0 are not
140         recommended.  Larger values produce less depth artifacts, but may prevent
141         thin objects from casting shadows on nearby sufraces. */
142         void set_depth_bias(float);
143
144         const Texture2D &get_depth_texture() const { return depth_buf; }
145
146         virtual void setup_frame(Renderer &);
147         virtual void finish_frame();
148
149         virtual void render(Renderer &, Tag = Tag()) const;
150
151         virtual void set_debug_name(const std::string &);
152 };
153
154 } // namespace GL
155 } // namespace Msp
156
157 #endif