#include <msp/datafile/packsource.h>
#include <msp/fs/stat.h>
#include <msp/fs/utils.h>
-#include <msp/graphics/simplewindow.h>
+#include <msp/graphics/display.h>
+#include <msp/graphics/window.h>
#include <msp/gl/animatedobject.h>
#include <msp/gl/animation.h>
#include <msp/gl/animationplayer.h>
#include <msp/gl/blend.h>
#include <msp/gl/camera.h>
+#include <msp/gl/device.h>
+#include <msp/gl/directionallight.h>
#include <msp/gl/framebuffer.h>
-#include <msp/gl/light.h>
#include <msp/gl/lighting.h>
#include <msp/gl/mesh.h>
#include <msp/gl/object.h>
-#include <msp/gl/pipeline.h>
+#include <msp/gl/sequence.h>
+#include <msp/gl/sequencebuilder.h>
+#include <msp/gl/sequencetemplate.h>
#include <msp/gl/renderer.h>
#include <msp/gl/resources.h>
#include <msp/gl/simplescene.h>
#include <msp/gl/technique.h>
-#include <msp/gl/tests.h>
#include <msp/gl/windowview.h>
#include <msp/input/mouse.h>
#include <msp/io/print.h>
+#include <msp/strings/regex.h>
#include <msp/time/timestamp.h>
#include <msp/time/utils.h>
class Viewer: public RegisteredApplication<Viewer>
{
private:
+ struct Options
+ {
+ list<string> resource_locations;
+ string animation_name;
+ string renderable_name;
+ Graphics::WindowOptions wnd_opts;
+
+ Options(int, char **);
+ };
+
class Resources: public GL::Resources
{
private:
void add_pack(const string &);
};
- Graphics::SimpleGLWindow window;
+ Options opts;
+ Graphics::Display display;
+ Graphics::Window window;
+ GL::Device gl_device;
Input::Mouse mouse;
Resources resources;
GL::WindowView view;
- GL::Pipeline pipeline;
+ GL::Sequence *sequence;
GL::Renderable *renderable;
GL::AnimatedObject *anim_object;
GL::AnimationPlayer *anim_player;
- GL::Light light;
+ GL::DirectionalLight light;
GL::Lighting lighting;
GL::Camera camera;
float yaw;
};
+Viewer::Options::Options(int argc, char **argv)
+{
+ string window_size;
+
+ GetOpt getopt;
+ getopt.add_option('r', "resources", resource_locations, GetOpt::REQUIRED_ARG);
+ getopt.add_option('a', "animation", animation_name, GetOpt::REQUIRED_ARG);
+ getopt.add_option('w', "window-size", window_size, GetOpt::REQUIRED_ARG);
+ getopt.add_argument("renderable", renderable_name);
+ getopt(argc, argv);
+
+ wnd_opts.width = 1024;
+ wnd_opts.height = 768;
+ if (!window_size.empty())
+ {
+ RegMatch m = Regex("^([1-9][0-9]*)x([1-9][0-9]*)$").match(window_size);
+ if(!m)
+ throw usage_error("Invalid window size");
+
+ wnd_opts.width = lexical_cast<unsigned>(m[1].str);
+ wnd_opts.height = lexical_cast<unsigned>(m[2].str);
+ }
+}
+
Viewer::Viewer(int argc, char **argv):
- window(1024, 768, false),
+ opts(argc, argv),
+ window(display, opts.wnd_opts),
+ gl_device(window),
mouse(window),
- view(window, window.get_gl_context()),
- pipeline(view),
+ view(window),
+ sequence(0),
renderable(0),
anim_object(0),
anim_player(0),
light_pitch(0),
dragging(0)
{
- list<string> resource_locations;
- string animation_name;
- string renderable_name;
- GetOpt getopt;
- getopt.add_option('r', "resources", resource_locations, GetOpt::REQUIRED_ARG);
- getopt.add_option('a', "animation", animation_name, GetOpt::REQUIRED_ARG);
- getopt.add_argument("renderable", renderable_name);
- getopt(argc, argv);
-
- for(list<string>::const_iterator i=resource_locations.begin(); i!=resource_locations.end(); ++i)
+ for(list<string>::const_iterator i=opts.resource_locations.begin(); i!=opts.resource_locations.end(); ++i)
{
if(FS::is_dir(*i))
resources.add_directory(*i);
GL::Object *object = 0;
- string ext = FS::extpart(renderable_name);
+ string ext = FS::extpart(opts.renderable_name);
if(ext==".mesh")
{
GL::Mesh *mesh = 0;
- if(FS::exists(renderable_name))
+ if(FS::exists(opts.renderable_name))
{
mesh = new GL::Mesh;
- DataFile::load(*mesh, renderable_name);
- resources.add("__"+renderable_name, mesh);
+ DataFile::load(*mesh, opts.renderable_name);
+ resources.add("__"+opts.renderable_name, mesh);
}
else
- mesh = &resources.get<GL::Mesh>(renderable_name);
+ mesh = &resources.get<GL::Mesh>(opts.renderable_name);
object = new GL::Object;
GL::Technique *tech = new GL::Technique;
- tech->add_pass(0);
+ tech->add_method(0);
object->set_mesh(mesh);
object->set_technique(tech);
renderable = object;
resources.add("__.object", object);
}
else if(ext==".object")
- renderable = load<GL::Object>(renderable_name);
+ renderable = load<GL::Object>(opts.renderable_name);
else if(ext==".scene")
{
- GL::SimpleScene *scene = new GL::SimpleScene;
- DataFile::load(*scene, renderable_name, resources);
- renderable = scene;
+ if(FS::exists(opts.renderable_name))
+ {
+ GL::Scene::GenericLoader ldr(resources);
+ IO::BufferedFile in(opts.renderable_name);
+ DataFile::Parser parser(in, opts.renderable_name);
+ ldr.load(parser);
+ renderable = ldr.get_object();
+ }
+ else
+ renderable = &resources.get<GL::Scene>(opts.renderable_name);
+ }
+ else if(ext==".seq")
+ {
+ GL::SequenceTemplate *tmpl = load<GL::SequenceTemplate>(opts.renderable_name);
+ GL::SequenceBuilder bld(*tmpl);
+ bld.set_debug_name(FS::basename(opts.renderable_name));
+ sequence = bld.build(view);
}
else
throw usage_error("Unknown renderable type");
- if(!animation_name.empty())
+ if(!opts.animation_name.empty())
{
if(!object)
throw usage_error("Must have an object to animate");
- GL::Animation *anim = load<GL::Animation>(animation_name);
+ GL::Animation *anim = load<GL::Animation>(opts.animation_name);
anim_player = new GL::AnimationPlayer;
anim_object = new GL::AnimatedObject(*object);
anim_player->play(*anim_object, *anim);
mouse.signal_button_release.connect(sigc::bind_return(sigc::mem_fun(this, &Viewer::button_release), false));
mouse.signal_axis_motion.connect(sigc::bind_return(sigc::mem_fun(this, &Viewer::axis_motion), false));
- light.set_position(GL::Vector4(0, 0, 1, 0));
- lighting.attach(0, light);
+ light.set_direction(GL::Vector3(0, 0, -1));
+ lighting.attach(light);
+ camera.set_debug_name("Camera");
camera.set_up_direction(GL::Vector3(0, 0, 1));
update_camera();
- GL::Pipeline::Pass &pass = pipeline.add_pass(0, *renderable);
- pass.set_lighting(&lighting);
- pass.set_depth_test(&GL::DepthTest::lequal());
- pass.set_blend(&GL::Blend::alpha());
+ if(!sequence)
+ {
+ sequence = new GL::Sequence();
+ sequence->set_debug_name("Sequence");
+ sequence->set_clear_enabled(true);
+ GL::Sequence::Step &step = sequence->add_step(0, *renderable);
+ step.set_lighting(&lighting);
+ step.set_depth_test(GL::LEQUAL);
+ }
- view.set_content(&pipeline);
+ view.set_content(sequence);
view.set_camera(&camera);
}
{
delete anim_player;
delete anim_object;
+ delete sequence;
}
int Viewer::main()
anim_player->tick(dt);
}
- window.tick();
+ display.tick();
view.render();
}
float sy = sin(light_yaw);
float cp = cos(light_pitch);
float sp = sin(light_pitch);
- light.set_position(GL::Vector4(-cy*cp, -sy*cp, -sp, 0));
+ light.set_direction(GL::Vector3(cy*cp, sy*cp, sp));
}