2 #include <msp/core/application.h>
3 #include <msp/core/getopt.h>
4 #include <msp/datafile/directorysource.h>
5 #include <msp/datafile/packsource.h>
6 #include <msp/fs/stat.h>
7 #include <msp/fs/utils.h>
8 #include <msp/graphics/simplewindow.h>
9 #include <msp/gl/animatedobject.h>
10 #include <msp/gl/animation.h>
11 #include <msp/gl/animationplayer.h>
12 #include <msp/gl/blend.h>
13 #include <msp/gl/camera.h>
14 #include <msp/gl/framebuffer.h>
15 #include <msp/gl/light.h>
16 #include <msp/gl/lighting.h>
17 #include <msp/gl/mesh.h>
18 #include <msp/gl/object.h>
19 #include <msp/gl/renderer.h>
20 #include <msp/gl/resources.h>
21 #include <msp/gl/technique.h>
22 #include <msp/gl/tests.h>
23 #include <msp/input/mouse.h>
24 #include <msp/io/print.h>
25 #include <msp/time/timestamp.h>
26 #include <msp/time/utils.h>
31 class Viewer: public RegisteredApplication<Viewer>
34 class Resources: public GL::Resources
37 DataFile::DirectorySource dir_source;
38 DataFile::PackSource pack_source;
43 void add_directory(const string &);
44 void add_pack(const string &);
47 Graphics::SimpleGLWindow window;
50 GL::Renderable *renderable;
51 GL::AnimatedObject *anim_object;
52 GL::AnimationPlayer *anim_player;
54 GL::Lighting lighting;
62 Time::TimeStamp last_tick;
68 T *load(const string &);
76 void button_press(unsigned);
77 void button_release(unsigned);
78 void axis_motion(unsigned, float, float);
85 Viewer::Viewer(int argc, char **argv):
86 window(1024, 768, false),
98 list<string> resource_locations;
99 string animation_name;
100 string renderable_name;
102 getopt.add_option('r', "resources", resource_locations, GetOpt::REQUIRED_ARG);
103 getopt.add_option('a', "animation", animation_name, GetOpt::REQUIRED_ARG);
104 getopt.add_argument("renderable", renderable_name);
107 for(list<string>::const_iterator i=resource_locations.begin(); i!=resource_locations.end(); ++i)
110 resources.add_directory(*i);
113 string ext = FS::extpart(*i);
115 resources.add_pack(*i);
117 DataFile::load(resources, *i);
121 GL::Object *object = 0;
123 string ext = FS::extpart(renderable_name);
127 if(FS::exists(renderable_name))
130 DataFile::load(*mesh, renderable_name);
131 resources.add("__"+renderable_name, mesh);
134 mesh = &resources.get<GL::Mesh>(renderable_name);
136 object = new GL::Object;
137 GL::Technique *tech = new GL::Technique;
139 object->set_mesh(mesh);
140 object->set_technique(tech);
143 resources.add("__.tech", tech);
144 resources.add("__.object", object);
146 else if(ext==".object")
148 object = load<GL::Object>(renderable_name);
152 throw usage_error("Unknown renderable type");
154 if(!animation_name.empty())
157 throw usage_error("Must have an object to animate");
159 GL::Animation *anim = load<GL::Animation>(animation_name);
160 anim_player = new GL::AnimationPlayer;
161 anim_object = new GL::AnimatedObject(*object);
162 anim_player->play(*anim_object, *anim);
163 renderable = anim_object;
166 window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Viewer::exit), 0));
167 mouse.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &Viewer::button_press), false));
168 mouse.signal_button_release.connect(sigc::bind_return(sigc::mem_fun(this, &Viewer::button_release), false));
169 mouse.signal_axis_motion.connect(sigc::bind_return(sigc::mem_fun(this, &Viewer::axis_motion), false));
171 light.set_position(GL::Vector4(0, 0, 1, 0));
172 lighting.attach(0, light);
174 camera.set_up_direction(GL::Vector3(0, 0, 1));
179 T *Viewer::load(const string &name)
184 DataFile::load(*thing, name, resources);
185 resources.add("__"+name, thing);
189 return &resources.get<T>(name);
201 return Application::main();
208 Time::TimeStamp t = Time::now();
214 anim_player->tick(dt);
219 GL::Framebuffer::system().clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
221 GL::Bind bind_depth(GL::DepthTest::lequal());
222 GL::Bind bind_blend(GL::Blend::alpha());
223 GL::Renderer renderer(&camera);
224 renderer.set_lighting(&lighting);
225 renderable->render(renderer);
227 window.swap_buffers();
230 void Viewer::button_press(unsigned btn)
239 axis_motion(0, 0, 0);
253 void Viewer::button_release(unsigned btn)
259 void Viewer::axis_motion(unsigned axis, float, float delta)
263 float dx = (axis==0 ? delta : 0);
264 float dy = (axis==1 ? delta : 0);
282 float x = mouse.get_axis_value(0);
283 float y = mouse.get_axis_value(1);
285 light_yaw = yaw+x*M_PI;
286 light_pitch = pitch-y*M_PI;
292 void Viewer::update_camera()
296 float cp = cos(pitch);
297 float sp = sin(pitch);
298 camera.set_position(GL::Vector3(-cy*cp*distance, -sy*cp*distance, -sp*distance));
299 camera.set_depth_clip(distance*0.02, distance*50);
300 camera.look_at(GL::Vector3(0, 0, 0));
303 void Viewer::update_light()
305 float cy = cos(light_yaw);
306 float sy = sin(light_yaw);
307 float cp = cos(light_pitch);
308 float sp = sin(light_pitch);
309 light.set_position(GL::Vector4(-cy*cp, -sy*cp, -sp, 0));
313 Viewer::Resources::Resources()
315 add_source(dir_source);
316 add_source(pack_source);
319 void Viewer::Resources::add_directory(const string &dir)
321 dir_source.add_directory(dir);
324 void Viewer::Resources::add_pack(const string &pack)
326 pack_source.add_pack_file(pack);