]> git.tdb.fi Git - libs/gl.git/blobdiff - tools/viewer.cpp
Redesign depth and stencil test and blend state management
[libs/gl.git] / tools / viewer.cpp
index d2a384f4e0b2afc112afd7fe3ea62ac3da676237..2c950e18e2acc22714ee9d3030ed7467371a0fe0 100644 (file)
 #include <msp/gl/lighting.h>
 #include <msp/gl/mesh.h>
 #include <msp/gl/object.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>
 
@@ -32,6 +36,17 @@ using namespace Msp;
 class Viewer: public RegisteredApplication<Viewer>
 {
 private:
+       struct Options
+       {
+               list<string> resource_locations;
+               string animation_name;
+               string renderable_name;
+               Graphics::WindowOptions wnd_opts;
+               Graphics::GLOptions gl_opts;
+
+               Options(int, char **);
+       };
+
        class Resources: public GL::Resources
        {
        private:
@@ -45,9 +60,14 @@ private:
                void add_pack(const string &);
        };
 
-       Graphics::SimpleGLWindow window;
+       Options opts;
+       Graphics::Display display;
+       Graphics::Window window;
+       Graphics::GLContext gl_ctx;
        Input::Mouse mouse;
        Resources resources;
+       GL::WindowView view;
+       GL::Sequence *sequence;
        GL::Renderable *renderable;
        GL::AnimatedObject *anim_object;
        GL::AnimationPlayer *anim_player;
@@ -83,9 +103,39 @@ private:
 };
 
 
+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);
+       }
+       gl_opts.gl_version_major = Graphics::GLOptions::LATEST_VERSION;
+       gl_opts.core_profile = true;
+}
+
 Viewer::Viewer(int argc, char **argv):
-       window(1024, 768, false),
+       opts(argc, argv),
+       window(display, opts.wnd_opts),
+       gl_ctx(window, opts.gl_opts),
        mouse(window),
+       view(window, gl_ctx),
+       sequence(0),
        renderable(0),
        anim_object(0),
        anim_player(0),
@@ -96,16 +146,7 @@ Viewer::Viewer(int argc, char **argv):
        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);
@@ -121,18 +162,18 @@ Viewer::Viewer(int argc, char **argv):
 
        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;
@@ -145,22 +186,35 @@ Viewer::Viewer(int argc, char **argv):
                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_scene();
+               }
+               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);
+               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);
@@ -173,10 +227,22 @@ Viewer::Viewer(int argc, char **argv):
        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);
+       lighting.attach(light);
 
        camera.set_up_direction(GL::Vector3(0, 0, 1));
        update_camera();
+
+       if(!sequence)
+       {
+               sequence = new GL::Sequence(view);
+               GL::Sequence::Step &step = sequence->add_step(0, *renderable);
+               step.set_lighting(&lighting);
+               step.set_depth_test(GL::LEQUAL);
+               step.set_blend(GL::Blend(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA));
+       }
+
+       view.set_content(sequence);
+       view.set_camera(&camera);
 }
 
 template<typename T>
@@ -197,6 +263,7 @@ Viewer::~Viewer()
 {
        delete anim_player;
        delete anim_object;
+       delete sequence;
 }
 
 int Viewer::main()
@@ -218,17 +285,8 @@ void Viewer::tick()
                anim_player->tick(dt);
        }
 
-       window.tick();
-
-       GL::Framebuffer::system().clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
-
-       GL::Bind bind_depth(GL::DepthTest::lequal());
-       GL::Bind bind_blend(GL::Blend::alpha());
-       GL::Renderer renderer(&camera);
-       renderer.set_lighting(&lighting);
-       renderable->render(renderer);
-
-       window.swap_buffers();
+       display.tick();
+       view.render();
 }
 
 void Viewer::button_press(unsigned btn)