]> git.tdb.fi Git - libs/gl.git/blob - demos/desertpillars/source/desertpillars.cpp
Check the flat qualifier from the correct member
[libs/gl.git] / demos / desertpillars / source / desertpillars.cpp
1 #include <msp/fs/dir.h>
2 #include <msp/gl/directionallight.h>
3 #include <msp/gl/lighting.h>
4 #include <msp/gl/sequencebuilder.h>
5 #include <msp/gl/pointlight.h>
6 #include <msp/gl/renderer.h>
7 #include <msp/input/keys.h>
8 #include <msp/time/utils.h>
9 #include "desertpillars.h"
10
11 using namespace std;
12 using namespace Msp;
13
14 DesertPillars::Options::Options()
15 {
16         wnd_opts.width = 1920;
17         wnd_opts.height = 1080;
18 }
19
20
21 DesertPillars::DesertPillars(int, char **):
22         window(display, opts.wnd_opts),
23         gl_device(window),
24         keyboard(window),
25         resources(&res_mgr),
26         view(window),
27         lighting(resources.get<GL::Lighting>("Desert.lightn")),
28         sphere(resources.get<GL::Object>("Sphere.object")),
29         sphere_morph(0.0f),
30         sphere_frozen(false),
31         sphere_stopped(false),
32         sun(resources.get<GL::DirectionalLight>("Sun.light")),
33         sun_angle(Geometry::Angle<float>::from_turns(0.1f)),
34         wisp(resources.get<GL::PointLight>("Wisp.light")),
35         flare(resources.get<GL::Object>("Flare.object"), lighting.find_light_index(wisp)),
36         camera_stopped(false)
37 {
38         window.set_title("Desert Pillars");
39         window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &DesertPillars::exit), 0));
40         keyboard.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &DesertPillars::key_press), false));
41
42         GL::SequenceBuilder seq_bld(resources.get<GL::SequenceTemplate>("Desert.seq"));
43         seq_bld.set_renderable("content", content);
44         seq_bld.set_debug_name("Main sequence");
45         sequence.reset(seq_bld.build(view));
46
47         GL::SequenceBuilder env_bld(resources.get<GL::SequenceTemplate>("Desert_environment.seq"));
48         env_bld.set_renderable("content", *sequence->get_steps().front().get_renderable());
49         env_bld.set_debug_name("Environment sequence");
50         env_seq.reset(env_bld.build());
51
52         env_map = make_unique<GL::EnvironmentMap>(256, GL::RGBA16F, 7, sphere, *env_seq);
53         env_map->set_debug_name("Environment map");
54         sphere.set_matrix(GL::Matrix::translation(GL::Vector3(0.0f, 0.0f, 3.3f)));
55
56         content.add(resources.get<GL::Scene>("Background.scene"));
57         content.add(*env_map);
58         content.add(flare);
59
60         camera.copy_parameters(resources.get<GL::Camera>("Camera.camera"));
61         camera.set_debug_name("Main camera");
62
63         view.set_content(sequence.get());
64         view.set_camera(&camera);
65
66         const GL::Vector3 &sun_direction = sun.get_direction();
67         sun_node = normalize(GL::Vector3(sun_direction.y, -sun_direction.x, 0.0f));
68         sun_axis = normalize(cross(sun_direction, sun_node));
69
70         wisp_base_color = wisp.get_color();
71
72         const GL::Vector3 &cam_pos = camera.get_position();
73         camera_distance = cam_pos.norm();
74         camera_angle = Geometry::atan2(cam_pos.y, cam_pos.x);
75         camera_base_height = Geometry::atan2(cam_pos.z, cam_pos.slice<2>(0).norm());
76 }
77
78 int DesertPillars::main()
79 {
80         window.show();
81         return Application::main();
82 }
83
84 void DesertPillars::tick()
85 {
86         Time::TimeStamp t = Time::now();
87         Time::TimeDelta dt = (last_tick ? t-last_tick : Time::zero);
88         last_tick = t;
89
90         if(!sphere_frozen)
91         {
92                 sphere_morph += dt/Time::sec;
93                 sphere.set_morph(sphere_morph);
94         }
95
96         if(!sphere_stopped)
97         {
98                 sphere_angle += Geometry::Angle<float>::from_degrees(36*dt/Time::sec);
99                 sphere.set_matrix(GL::Matrix().translate(GL::Vector3(0.0f, 0.0f, 3.3f))
100                         .rotate(sphere_angle, GL::Vector3(0.0f, 0.0f, 1.0f)).rotate(sphere_angle*0.5f, GL::Vector3(1.0f, 0.0f, 0.0f)));
101         }
102
103         if(!camera_stopped)
104         {
105                 camera_angle += Geometry::Angle<float>::from_degrees(12*dt/Time::sec);
106                 Geometry::Angle<float> cam_height = camera_base_height+Geometry::Angle<float>::from_degrees(15.0f*cos(camera_angle*1.5f));
107                 GL::Vector3 cam_dir(cos(camera_angle)*cos(cam_height), sin(camera_angle)*cos(cam_height), sin(cam_height));
108                 camera.set_position(GL::Vector3(0.0f, 0.0f, 2.0f)+cam_dir*camera_distance);
109                 camera.set_look_direction(-cam_dir);
110         }
111
112         sun_angle += Geometry::Angle<float>::from_degrees(4*dt/Time::sec);
113         sun.set_direction(GL::Matrix::rotation(sun_angle, sun_axis)*-sun_node);
114
115         wisp_angle += Geometry::Angle<float>::from_degrees(6*dt/Time::sec);
116         float r = 3.1f+1.1f*cos(4.0f*wisp_angle);
117         GL::Vector3 p(cos(wisp_angle)*r, sin(wisp_angle)*r, 3.6f+0.4f*sin(1.6f*wisp_angle));
118         wisp.set_position(p);
119         float twilight = 0.8f-min(max(sin(sun_angle), -0.05f), 0.2f)*4.0f;
120         wisp.set_color(wisp_base_color*((3.0f-2.0f*twilight)*twilight*twilight));
121         flare.set_matrix(GL::Matrix::translation(p));
122
123         display.tick();
124         res_mgr.tick();
125         view.render();
126 }
127
128 void DesertPillars::key_press(unsigned key)
129 {
130         if(key==Input::KEY_ESC)
131                 exit(0);
132         else if(key==Input::KEY_SPACE)
133                 camera_stopped = !camera_stopped;
134         else if(key==Input::KEY_F)
135                 sphere_frozen = !sphere_frozen;
136         else if(key==Input::KEY_S)
137                 sphere_stopped = !sphere_stopped;
138 }
139
140
141 DesertPillars::Resources::Resources(GL::ResourceManager *rm)
142 {
143         FS::Path base_dir = FS::get_sys_data_dir()/"demos"/"desertpillars"/"data";
144         source.add_directory(base_dir);
145         source.add_directory(base_dir/"textures");
146         source.add_directory(base_dir/"exported");
147         add_source(source);
148
149         set_resource_manager(rm);
150 }
151
152
153 void DesertPillars::MorphSphere::set_morph(float m)
154 {
155         shdata.uniform("morph", m);
156 }
157
158 void DesertPillars::MorphSphere::setup_render(GL::Renderer &renderer, GL::Tag tag) const
159 {
160         ObjectInstance::setup_render(renderer, tag);
161         renderer.add_shader_data(shdata);
162 }
163
164
165 DesertPillars::LightFlare::LightFlare(const GL::Object &o, unsigned i):
166         ObjectInstance(o)
167 {
168         shdata.uniform("flare_light_index", static_cast<int>(i));
169 }
170
171 void DesertPillars::LightFlare::setup_render(GL::Renderer &renderer, GL::Tag tag) const
172 {
173         ObjectInstance::setup_render(renderer, tag);
174         renderer.add_shader_data(shdata);
175 }