2 #include <msp/core/application.h>
3 #include <msp/fs/utils.h>
4 #include <msp/graphics/simplewindow.h>
5 #include <msp/gl/blend.h>
6 #include <msp/gl/camera.h>
7 #include <msp/gl/framebuffer.h>
8 #include <msp/gl/light.h>
9 #include <msp/gl/lighting.h>
10 #include <msp/gl/mesh.h>
11 #include <msp/gl/object.h>
12 #include <msp/gl/tests.h>
13 #include <msp/io/print.h>
18 class Viewer: public Application
21 Graphics::SimpleGLWindow window;
25 GL::Lighting lighting;
36 static Application::RegApp<Viewer> reg;
46 void button_press(int, int, unsigned, unsigned);
47 void button_release(int, int, unsigned, unsigned);
48 void pointer_motion(int, int);
49 void key_press(unsigned, unsigned, wchar_t);
55 static void usage(const char *, const char *, bool);
59 Application::RegApp<Viewer> Viewer::reg;
61 Viewer::Viewer(int argc, char **argv):
62 window(1024, 768, false),
75 throw UsageError("Filename must be provided");
78 string ext = FS::extpart(fn);
83 DataFile::load(*mesh, fn);
85 else if(ext==".object")
87 object = new GL::Object;
88 DataFile::load(*object, fn);
91 throw UsageError("Don't know how to view this file");
93 window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Viewer::exit), 0));
94 window.signal_button_press.connect(sigc::mem_fun(this, &Viewer::button_press));
95 window.signal_button_release.connect(sigc::mem_fun(this, &Viewer::button_release));
96 window.signal_pointer_motion.connect(sigc::mem_fun(this, &Viewer::pointer_motion));
97 window.signal_key_press.connect(sigc::mem_fun(this, &Viewer::key_press));
99 light.set_position(GL::Vector4(0, 0, 1, 0));
100 lighting.attach(0, light);
102 camera.set_up_direction(GL::Vector3(0, 0, 1));
115 return Application::main();
122 GL::Framebuffer::system().clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
126 GL::Bind bind_lighting(lighting);
127 GL::Bind bind_depth(GL::DepthTest::lequal());
128 GL::Bind bind_blend(GL::Blend::alpha());
134 window.swap_buffers();
137 void Viewer::usage(const char *err, const char *argv0, bool)
140 IO::print("%s\n", err);
141 IO::print("Usage: %s <filename>\n", argv0);
144 void Viewer::button_press(int x, int y, unsigned btn, unsigned)
155 pointer_motion(x, y);
169 void Viewer::button_release(int, int, unsigned btn, unsigned)
175 void Viewer::pointer_motion(int x, int y)
179 int dx = x-pointer_x;
180 int dy = pointer_y-y;
182 yaw -= dx*M_PI*2/window.get_width();
188 pitch += dy*M_PI/window.get_height();
201 int dx = x-window.get_width()/2;
202 int dy = window.get_height()/2-y;
204 light_yaw = yaw+dx*M_PI/window.get_width();
205 light_pitch = pitch-dy*M_PI/window.get_height();
211 void Viewer::key_press(unsigned, unsigned, wchar_t)
215 void Viewer::update_camera()
219 float cp = cos(pitch);
220 float sp = sin(pitch);
221 camera.set_position(GL::Vector3(-cy*cp*distance, -sy*cp*distance, -sp*distance));
222 camera.set_depth_clip(distance*0.02, distance*50);
223 camera.look_at(GL::Vector3(0, 0, 0));
226 void Viewer::update_light()
228 float cy = cos(light_yaw);
229 float sy = sin(light_yaw);
230 float cp = cos(light_pitch);
231 float sp = sin(light_pitch);
232 light.set_position(GL::Vector4(-cy*cp, -sy*cp, -sp, 0));