]> git.tdb.fi Git - libs/gl.git/blob - demos/desertpillars/source/desertpillars.cpp
Set shadowmap darkness to 1.0 by default
[libs/gl.git] / demos / desertpillars / source / desertpillars.cpp
1 #include <msp/fs/dir.h>
2 #include <msp/gl/sequencebuilder.h>
3 #include <msp/gl/renderer.h>
4 #include <msp/gl/tests.h>
5 #include <msp/input/keys.h>
6 #include <msp/time/utils.h>
7 #include "desertpillars.h"
8
9 using namespace std;
10 using namespace Msp;
11
12 DesertPillars::Options::Options()
13 {
14         wnd_opts.width = 1920;
15         wnd_opts.height = 1080;
16         gl_opts.gl_version_major = Graphics::GLOptions::LATEST_VERSION;
17         gl_opts.core_profile = true;
18 }
19
20
21 DesertPillars::DesertPillars(int, char **):
22         window(display, opts.wnd_opts),
23         gl_ctx(window, opts.gl_opts),
24         keyboard(window),
25         view(window, gl_ctx),
26         camera(resources.get<GL::Camera>("Camera.camera")),
27         sphere(resources.get<GL::Object>("sphere_phong.object")),
28         sphere_morph(0.0f),
29         sphere_frozen(false),
30         sphere_stopped(false),
31         camera_stopped(false)
32 {
33         window.set_title("Desert Pillars");
34         window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &DesertPillars::exit), 0));
35         keyboard.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &DesertPillars::key_press), false));
36
37         const GL::Light &sun = resources.get<GL::Light>("Sun.light");
38         sky = make_unique<GL::Sky>(content, sun);
39
40         unsigned shadow_size = 8192;
41         shadow_seq = make_unique<GL::Sequence>(shadow_size, shadow_size);
42         GL::Sequence::Step *step = &shadow_seq->add_step("shadow", content);
43         step->set_depth_test(&GL::DepthTest::lequal());
44
45         shadow_map = make_unique<GL::ShadowMap>(shadow_size, *sky, sun, *shadow_seq);
46         shadow_map->set_darkness(0.9f);
47         shadow_map->set_target(GL::Vector3(0.0f, 0.0f, 0.0f), 20.0f);
48
49         GL::SequenceBuilder seq_bld(resources.get<GL::SequenceTemplate>("Desert.seq"));
50         seq_bld.set_renderable("content", *shadow_map);
51         sequence.reset(seq_bld.build(view));
52
53         unsigned env_size = 256;
54         env_seq = make_unique<GL::Sequence>(env_size, env_size);
55         step = &env_seq->add_step("", *shadow_map);
56         step->set_lighting(&resources.get<GL::Lighting>("Desert.lightn"));
57         step->set_depth_test(&GL::DepthTest::lequal());
58
59         env_map = make_unique<GL::EnvironmentMap>(256, GL::RGB16F, sphere, *env_seq);
60         sphere.set_matrix(GL::Matrix::translation(GL::Vector3(0.0f, 0.0f, 3.3f)));
61
62         content.add(resources.get<GL::Scene>("Background.scene"));
63         content.add(*env_map);
64
65         view.set_content(sequence.get());
66         view.set_camera(&camera);
67
68         const GL::Vector3 &cam_pos = camera.get_position();
69         camera_distance = cam_pos.norm();
70         camera_angle = Geometry::atan2(cam_pos.y, cam_pos.x);
71         camera_base_height = Geometry::atan2(cam_pos.z, cam_pos.slice<2>(0).norm());
72 }
73
74 int DesertPillars::main()
75 {
76         window.show();
77         return Application::main();
78 }
79
80 void DesertPillars::tick()
81 {
82         Time::TimeStamp t = Time::now();
83         Time::TimeDelta dt = (last_tick ? t-last_tick : Time::zero);
84         last_tick = t;
85
86         if(!sphere_frozen)
87         {
88                 sphere_morph += dt/Time::sec;
89                 sphere.set_morph(sphere_morph);
90         }
91
92         if(!sphere_stopped)
93         {
94                 sphere_angle += Geometry::Angle<float>::from_degrees(36*dt/Time::sec);
95                 sphere.set_matrix(GL::Matrix().translate(GL::Vector3(0.0f, 0.0f, 3.3f))
96                         .rotate(sphere_angle, GL::Vector3(0.0f, 0.0f, 1.0f)).rotate(sphere_angle*0.5f, GL::Vector3(1.0f, 0.0f, 0.0f)));
97         }
98
99         if(!camera_stopped)
100         {
101                 camera_angle += Geometry::Angle<float>::from_degrees(12*dt/Time::sec);
102                 Geometry::Angle<float> cam_height = camera_base_height+Geometry::Angle<float>::from_degrees(15.0f*cos(camera_angle*1.5f));
103                 GL::Vector3 cam_dir(cos(camera_angle)*cos(cam_height), sin(camera_angle)*cos(cam_height), sin(cam_height));
104                 camera.set_position(GL::Vector3(0.0f, 0.0f, 2.0f)+cam_dir*camera_distance);
105                 camera.set_look_direction(-cam_dir);
106         }
107
108         display.tick();
109         view.render();
110 }
111
112 void DesertPillars::key_press(unsigned key)
113 {
114         if(key==Input::KEY_ESC)
115                 exit(0);
116         else if(key==Input::KEY_SPACE)
117                 camera_stopped = !camera_stopped;
118         else if(key==Input::KEY_F)
119                 sphere_frozen = !sphere_frozen;
120         else if(key==Input::KEY_S)
121                 sphere_stopped = !sphere_stopped;
122 }
123
124
125 DesertPillars::Resources::Resources()
126 {
127         FS::Path base_dir = FS::get_sys_data_dir()/"demos"/"desertpillars"/"data";
128         source.add_directory(base_dir);
129         source.add_directory(base_dir/"textures");
130         source.add_directory(base_dir/"exported");
131         add_source(source);
132 }
133
134
135 void DesertPillars::MorphSphere::set_morph(float m)
136 {
137         shdata.uniform("morph", m);
138 }
139
140 void DesertPillars::MorphSphere::setup_render(GL::Renderer &renderer, GL::Tag tag) const
141 {
142         ObjectInstance::setup_render(renderer, tag);
143         renderer.add_shader_data(shdata);
144 }