3 This file is part of libmspgl
4 Copyright © 2010 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
9 #include <msp/core/application.h>
10 #include <msp/fs/utils.h>
11 #include <msp/gbase/simplewindow.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/tests.h>
20 #include <msp/io/print.h>
25 class Viewer: public Application
28 Graphics::SimpleGLWindow window;
32 GL::Lighting lighting;
43 static Application::RegApp<Viewer> reg;
53 void button_press(int, int, unsigned, unsigned);
54 void button_release(int, int, unsigned, unsigned);
55 void pointer_motion(int, int);
56 void key_press(unsigned, unsigned, wchar_t);
62 static void usage(const char *, const char *, bool);
66 Application::RegApp<Viewer> Viewer::reg;
68 Viewer::Viewer(int argc, char **argv):
69 window(1024, 768, false),
82 throw UsageError("Filename must be provided");
85 string ext = FS::extpart(fn);
90 DataFile::load(*mesh, fn);
92 else if(ext==".object")
94 object = new GL::Object;
95 DataFile::load(*object, fn);
98 throw UsageError("Don't know how to view this file");
100 window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Viewer::exit), 0));
101 window.signal_button_press.connect(sigc::mem_fun(this, &Viewer::button_press));
102 window.signal_button_release.connect(sigc::mem_fun(this, &Viewer::button_release));
103 window.signal_pointer_motion.connect(sigc::mem_fun(this, &Viewer::pointer_motion));
104 window.signal_key_press.connect(sigc::mem_fun(this, &Viewer::key_press));
106 light.set_position(GL::Vector4(0, 0, 1, 0));
107 lighting.attach(0, light);
109 camera.set_up_direction(GL::Vector3(0, 0, 1));
122 return Application::main();
129 GL::Framebuffer::system().clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
133 GL::Bind bind_lighting(lighting);
134 GL::Bind bind_depth(GL::DepthTest::lequal());
135 GL::Bind bind_blend(GL::Blend::alpha());
141 window.swap_buffers();
144 void Viewer::usage(const char *err, const char *argv0, bool)
147 IO::print("%s\n", err);
148 IO::print("Usage: %s <filename>\n", argv0);
151 void Viewer::button_press(int x, int y, unsigned btn, unsigned)
162 pointer_motion(x, y);
176 void Viewer::button_release(int, int, unsigned btn, unsigned)
182 void Viewer::pointer_motion(int x, int y)
186 int dx = x-pointer_x;
187 int dy = pointer_y-y;
189 yaw -= dx*M_PI*2/window.get_width();
195 pitch += dy*M_PI/window.get_height();
208 int dx = x-window.get_width()/2;
209 int dy = window.get_height()/2-y;
211 light_yaw = yaw+dx*M_PI/window.get_width();
212 light_pitch = pitch-dy*M_PI/window.get_height();
218 void Viewer::key_press(unsigned, unsigned, wchar_t)
222 void Viewer::update_camera()
226 float cp = cos(pitch);
227 float sp = sin(pitch);
228 camera.set_position(GL::Vector3(-cy*cp*distance, -sy*cp*distance, -sp*distance));
229 camera.set_depth_clip(distance*0.02, distance*50);
230 camera.look_at(GL::Vector3(0, 0, 0));
233 void Viewer::update_light()
235 float cy = cos(light_yaw);
236 float sy = sin(light_yaw);
237 float cp = cos(light_pitch);
238 float sp = sin(light_pitch);
239 light.set_position(GL::Vector4(-cy*cp, -sy*cp, -sp, 0));