]> git.tdb.fi Git - libs/gl.git/blob - source/effects/environmentmap.cpp
Access builtin resources through a global instance
[libs/gl.git] / source / effects / environmentmap.cpp
1 #include <algorithm>
2 #include <cmath>
3 #include "environmentmap.h"
4 #include "renderer.h"
5 #include "resources.h"
6 #include "texunit.h"
7
8 using namespace std;
9
10 namespace Msp {
11 namespace GL {
12
13 EnvironmentMap::EnvironmentMap(unsigned s, Renderable &r, Renderable &e):
14         Effect(r),
15         environment(e),
16         sampler(Resources::get_global().get<Sampler>("_linear_clamp.samp"))
17 {
18         init(s, RGB8);
19 }
20
21 EnvironmentMap::EnvironmentMap(unsigned s, PixelFormat f, Renderable &r, Renderable &e):
22         Effect(r),
23         environment(e),
24         sampler(Resources::get_global().get<Sampler>("_linear_clamp.samp"))
25 {
26         init(s, f);
27 }
28
29 void EnvironmentMap::init(unsigned s, PixelFormat f)
30 {
31         size = s;
32         rendered = false;
33         update_interval = 1;
34         update_delay = 0;
35
36         env_tex.storage(f, size);
37         depth_buf.storage(DEPTH_COMPONENT32F, size, size);
38         for(unsigned i=0; i<6; ++i)
39         {
40                 TextureCubeFace face = TextureCube::enumerate_faces(i);
41                 faces[i].fbo.attach(COLOR_ATTACHMENT0, env_tex, face, 0);
42                 faces[i].fbo.attach(DEPTH_ATTACHMENT, depth_buf);
43                 faces[i].fbo.require_complete();
44                 faces[i].camera.set_look_direction(TextureCube::get_face_direction(face));
45                 faces[i].camera.set_up_direction(TextureCube::get_t_direction(face));
46                 faces[i].camera.set_field_of_view(Geometry::Angle<float>::right());
47                 faces[i].camera.set_aspect_ratio(1);
48                 faces[i].camera.set_depth_clip(0.1, 100);
49         }
50
51         shdata.uniform("env_world_matrix", LinAl::SquareMatrix<float, 3>::identity());
52 }
53
54 void EnvironmentMap::set_depth_clip(float n, float f)
55 {
56         for(unsigned i=0; i<6; ++i)
57                 faces[i].camera.set_depth_clip(n, f);
58 }
59
60 void EnvironmentMap::set_update_interval(unsigned i)
61 {
62         update_interval = i;
63         update_delay = min(update_delay, update_interval-1);
64 }
65
66 void EnvironmentMap::queue_update()
67 {
68         update_delay = 0;
69 }
70
71 void EnvironmentMap::setup_frame(Renderer &renderer)
72 {
73         if(rendered)
74                 return;
75
76         rendered = true;
77         renderable.setup_frame(renderer);
78
79         if(update_delay)
80         {
81                 if(update_interval)
82                         --update_delay;
83                 return;
84         }
85         update_delay = update_interval-1;
86         environment.setup_frame(renderer);
87
88         const Matrix *matrix = renderable.get_matrix();
89         if(!matrix)
90                 return;
91
92         Renderer::Push push(renderer);
93         Renderer::Exclude exclude1(renderer, renderable);
94         Renderer::Exclude exclude2(renderer, *this);
95
96         Vector3 center = matrix->column(3).slice<3>(0);
97
98         BindRestore bind_fbo(faces[0].fbo);
99         for(unsigned i=0; i<6; ++i)
100         {
101                 faces[i].camera.set_position(center);
102                 faces[i].fbo.bind();
103                 faces[i].fbo.clear();
104                 renderer.set_camera(faces[i].camera);
105                 renderer.render(environment);
106         }
107 }
108
109 void EnvironmentMap::finish_frame()
110 {
111         if(rendered)
112         {
113                 rendered = false;
114                 renderable.finish_frame();
115                 environment.finish_frame();
116         }
117 }
118
119 void EnvironmentMap::render(Renderer &renderer, Tag tag) const
120 {
121         if(!enabled_passes.count(tag))
122                 return renderer.render(renderable, tag);
123
124         Renderer::Push _push_rend(renderer);
125
126         renderer.set_texture("environment_map", &env_tex, &sampler);
127         renderer.add_shader_data(shdata);
128         renderer.render(renderable, tag);
129 }
130
131 } // namespace GL
132 } // namespace Msp