2 #include <msp/core/application.h>
3 #include <msp/core/getopt.h>
4 #include <msp/fs/utils.h>
5 #include <msp/graphics/simplewindow.h>
6 #include <msp/gl/animatedobject.h>
7 #include <msp/gl/animation.h>
8 #include <msp/gl/animationplayer.h>
9 #include <msp/gl/blend.h>
10 #include <msp/gl/camera.h>
11 #include <msp/gl/framebuffer.h>
12 #include <msp/gl/light.h>
13 #include <msp/gl/lighting.h>
14 #include <msp/gl/mesh.h>
15 #include <msp/gl/object.h>
16 #include <msp/gl/tests.h>
17 #include <msp/input/mouse.h>
18 #include <msp/io/print.h>
19 #include <msp/time/timestamp.h>
20 #include <msp/time/utils.h>
25 class Viewer: public RegisteredApplication<Viewer>
28 Graphics::SimpleGLWindow window;
32 GL::Animation *animation;
33 GL::AnimatedObject *anim_object;
34 GL::AnimationPlayer *anim_player;
36 GL::Lighting lighting;
44 Time::TimeStamp last_tick;
54 void button_press(unsigned);
55 void button_release(unsigned);
56 void axis_motion(unsigned, float, float);
63 Viewer::Viewer(int argc, char **argv):
64 window(1024, 768, false),
79 throw usage_error("Filename must be provided");
81 for(int i=1; i<argc; ++i)
84 string ext = FS::extpart(fn);
89 throw usage_error("Only one mesh or object may be specified");
92 DataFile::load(*mesh, fn);
94 else if(ext==".object")
97 throw usage_error("Only one mesh or object may be specified");
99 object = new GL::Object;
100 DataFile::load(*object, fn);
102 else if(ext==".anim")
105 throw usage_error("An object must be provided for animation");
107 animation = new GL::Animation;
108 DataFile::load(*animation, argv[2]);
109 anim_object = new GL::AnimatedObject(*object);
110 anim_player = new GL::AnimationPlayer;
111 anim_player->play(*anim_object, *animation);
114 throw usage_error("Don't know how to view this file");
117 window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Viewer::exit), 0));
118 mouse.signal_button_press.connect(sigc::mem_fun(this, &Viewer::button_press));
119 mouse.signal_button_release.connect(sigc::mem_fun(this, &Viewer::button_release));
120 mouse.signal_axis_motion.connect(sigc::mem_fun(this, &Viewer::axis_motion));
122 light.set_position(GL::Vector4(0, 0, 1, 0));
123 lighting.attach(0, light);
125 camera.set_up_direction(GL::Vector3(0, 0, 1));
138 return Application::main();
145 Time::TimeStamp t = Time::now();
151 anim_player->tick(dt);
156 GL::Framebuffer::system().clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
160 GL::Bind bind_lighting(lighting);
161 GL::Bind bind_depth(GL::DepthTest::lequal());
162 GL::Bind bind_blend(GL::Blend::alpha());
164 anim_object->render();
170 window.swap_buffers();
173 void Viewer::button_press(unsigned btn)
182 axis_motion(0, 0, 0);
196 void Viewer::button_release(unsigned btn)
202 void Viewer::axis_motion(unsigned axis, float, float delta)
206 float dx = (axis==0 ? delta : 0);
207 float dy = (axis==1 ? delta : 0);
225 float x = mouse.get_axis_value(0);
226 float y = mouse.get_axis_value(1);
228 light_yaw = yaw+x*M_PI;
229 light_pitch = pitch-y*M_PI;
235 void Viewer::update_camera()
239 float cp = cos(pitch);
240 float sp = sin(pitch);
241 camera.set_position(GL::Vector3(-cy*cp*distance, -sy*cp*distance, -sp*distance));
242 camera.set_depth_clip(distance*0.02, distance*50);
243 camera.look_at(GL::Vector3(0, 0, 0));
246 void Viewer::update_light()
248 float cy = cos(light_yaw);
249 float sy = sin(light_yaw);
250 float cp = cos(light_pitch);
251 float sp = sin(light_pitch);
252 light.set_position(GL::Vector4(-cy*cp, -sy*cp, -sp, 0));