]> git.tdb.fi Git - r2c2.git/blob - source/engineer/trainview.cpp
dffa04dde651be1768bda8b6ee20ed9cf4840ab6
[r2c2.git] / source / engineer / trainview.cpp
1 #include <msp/gl/tests.h>
2 #include <msp/gltk/button.h>
3 #include <msp/gltk/image.h>
4 #include "libr2c2/vehicle.h"
5 #include "libr2c2/vehicletype.h"
6 #include "engineer.h"
7 #include "trainview.h"
8
9 using namespace Msp;
10 using namespace R2C2;
11
12 TrainView::TrainView(Engineer &e, const Train &t):
13         engineer(e),
14         train(t),
15         mode(SIDE),
16         forward(true),
17         pipeline(280, 280, false),
18         stale(false)
19 {
20         set_size(300, 330);
21
22         tex.set_min_filter(GL::LINEAR);
23         tex.storage(GL::RGB, 280, 280);
24         tex.image(0, GL::RGB, GL::UNSIGNED_BYTE, 0);
25         fbo.attach(GL::COLOR_ATTACHMENT0, tex, 0);
26         depth.storage(GL::DEPTH_COMPONENT, 280, 280);
27         fbo.attach(GL::DEPTH_ATTACHMENT, depth);
28
29         camera.set_up_direction(GL::Vector3(0, 0, 1));
30         camera.set_depth_clip(0.01, 10);
31         camera.set_aspect(1);
32         pipeline.set_camera(&camera);
33
34         pipeline.add_renderable(engineer.get_layout_3d().get_scene());
35
36         GL::Pipeline::Pass *pass = &pipeline.add_pass(0);
37         pass->set_depth_test(&GL::DepthTest::lequal());
38         pass->set_lighting(&engineer.get_lighting());
39
40         GLtk::Image *image;
41         add(*(image = new GLtk::Image(&tex)));
42         image->set_geometry(GLtk::Geometry(10, 40, geom.w-20, geom.h-50));
43
44         GLtk::Button *btn;
45
46         add(*(btn = new GLtk::Button("Roof")));
47         btn->set_geometry(GLtk::Geometry(10, 10, 36, 25));
48         btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(this, &TrainView::set_mode), ROOF));
49
50         add(*(btn = new GLtk::Button("Side")));
51         btn->set_geometry(GLtk::Geometry(46, 10, 36, 25));
52         btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(this, &TrainView::set_mode), SIDE));
53
54         add(*(btn = new GLtk::Button("Head")));
55         btn->set_geometry(GLtk::Geometry(82, 10, 36, 25));
56         btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(this, &TrainView::set_mode), HEAD));
57
58         add(*(tgl_forward = new GLtk::Toggle("Fwd")));
59         tgl_forward->set_geometry(GLtk::Geometry(118, 8, 36, 27));
60         tgl_forward->set_value(true);
61         tgl_forward->signal_toggled.connect(sigc::mem_fun(this, &TrainView::set_forward));
62
63         add(*(btn = new GLtk::Button("Close")));
64         btn->set_geometry(GLtk::Geometry(geom.w-46, 10, 36, 25));
65         btn->signal_clicked.connect(sigc::mem_fun(this, &TrainView::close_clicked));
66
67         engineer.add_train_view(*this);
68 }
69
70 TrainView::~TrainView()
71 {
72         engineer.remove_train_view(*this);
73 }
74
75 void TrainView::set_mode(Mode m)
76 {
77         mode = m;
78 }
79
80 void TrainView::set_forward(bool f)
81 {
82         forward = f;
83 }
84
85 void TrainView::prepare()
86 {
87         const Vehicle &veh = train.get_vehicle(0);
88         const Vector &pos = veh.get_position();
89         Angle angle = veh.get_rotation();
90         if(!forward)
91                 angle += Angle::half_turn();
92         Vector fwd_vec = rotated_vector(Vector(1, 0, 0), angle);
93         Vector side_vec = rotated_vector(Vector(0, -1, 0), angle);
94         float l = veh.get_type().get_length();
95
96         switch(mode)
97         {
98         case ROOF:
99                 camera.set_position(pos-l*fwd_vec+Vector(0, 0, 0.07));
100                 camera.set_look_direction(fwd_vec-Vector(0, 0, -0.2));
101                 break;
102         case SIDE:
103                 camera.set_position(pos-0.8f*fwd_vec+0.05f*side_vec+Vector(0, 0, 0.03));
104                 camera.set_look_direction(fwd_vec-side_vec*0.2f);
105                 break;
106         case HEAD:
107                 camera.set_position(pos+fwd_vec*(l*0.55f)+Vector(0, 0, 0.03));
108                 camera.set_look_direction(fwd_vec);
109                 break;
110         }
111
112         GL::Bind _bind_fbo(fbo);
113         fbo.clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
114         pipeline.render();
115 }
116
117 void TrainView::button_release(int x, int y, unsigned btn)
118 {
119         GLtk::Panel::button_release(x, y, btn);
120         if(stale)
121                 delete this;
122 }
123
124 void TrainView::close_clicked()
125 {
126         stale = true;
127 }