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