Пример #1
0
int main(int argc, char** argv) {

  gua::init(argc, argv);


  //create simple untextured material shader
  auto lod_keep_input_desc = std::make_shared<gua::MaterialShaderDescription>("./data/materials/PLOD_use_input_color.gmd");
  auto lod_keep_color_shader(std::make_shared<gua::MaterialShader>("PLOD_pass_input_color", lod_keep_input_desc));
  gua::MaterialShaderDatabase::instance()->add(lod_keep_color_shader);


  //create material for pointcloud
  auto lod_rough = lod_keep_color_shader->make_new_material();
  lod_rough->set_uniform("metalness", 0.2f);
  lod_rough->set_uniform("roughness", 0.4f);
  lod_rough->set_uniform("emissivity", 0.8f);


  //configure lod backend
  gua::LodLoader lod_loader;
  lod_loader.set_out_of_core_budget_in_mb(512);
  lod_loader.set_render_budget_in_mb(512);
  lod_loader.set_upload_budget_in_mb(20);

  //load a sample pointcloud
  auto plod_node = lod_loader.load_lod_pointcloud(
    "pointcloud",
    "/opt/3d_models/lamure/plod/pig_pr.bvh",
    lod_rough,
    gua::LodLoader::NORMALIZE_POSITION | gua::LodLoader::NORMALIZE_SCALE | gua::LodLoader::MAKE_PICKABLE);

  //load a sample mesh-based lod model 
  auto mlod_node = lod_loader.load_lod_trimesh(
    //"tri_mesh", 
    "/opt/3d_models/lamure/mlod/xyzrgb_dragon_7219k.bvh", 
    //plod_rough,
    gua::LodLoader::NORMALIZE_POSITION | gua::LodLoader::NORMALIZE_SCALE/* | gua::LodLoader::MAKE_PICKABLE*/
  );

  mlod_node->set_error_threshold(0.25);

  //setup scenegraph
  gua::SceneGraph graph("main_scenegraph");
  auto scene_transform = graph.add_node<gua::node::TransformNode>("/", "transform");
  auto mlod_transform = graph.add_node<gua::node::TransformNode>("/transform", "mlod_transform");

  auto plod_transform = graph.add_node<gua::node::TransformNode>("/transform", "plod_transform");

  graph.add_node("/transform/mlod_transform", mlod_node);

  graph.add_node("/transform/plod_transform", plod_node);

  mlod_transform->translate(-0.4, 0.0, 0.0);

  plod_transform->rotate(180.0, 0.0, 1.0, 0.0);
  plod_transform->translate(0.3, 0.08, 0.0);

  //create a lightsource
  auto light_transform = graph.add_node<gua::node::TransformNode>("/transform", "light_transform");
  auto light = graph.add_node<gua::node::LightNode>("/transform/light_transform", "light");
  light->data.set_type(gua::node::LightNode::Type::POINT);
  light->data.set_enable_shadows(false);

  light->data.set_shadow_map_size(4096);
  light->data.brightness = 5.0f;
  light->translate(0.f, 0.2f, 0.f);
  light->scale(4.f);
  light->translate(0.f, 0.f, 1.f);


  auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen");
  screen->data.set_size(gua::math::vec2(1.92f, 1.08f));
  screen->translate(0, 0, 1.0);

  //add mouse interaction
  scm::gl::trackball_manipulator trackball;
  trackball.transform_matrix()*scm::math::make_translation(0.01f, 0.002f, 0.2f);
  trackball.dolly(0.2f);
  float dolly_sens = 1.5f;
  gua::math::vec2 trackball_init_pos(0.f);
  gua::math::vec2 last_mouse_pos(0.f);
  int button_state = -1;

  //setup rendering pipeline and window
  auto resolution = gua::math::vec2ui(1920, 1080);

  auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam");
  camera->translate(0.0f, 0, 2.5f);
  camera->config.set_resolution(resolution);
  
  //use close near plane to allow inspection of details
  //camera->config.set_near_clip(0.01f);
  //camera->config.set_far_clip(200.0f);
  camera->config.set_screen_path("/screen");
  camera->config.set_scene_graph_name("main_scenegraph");
  camera->config.set_output_window_name("main_window");
  camera->config.set_enable_stereo(true);

  auto PLod_Pass = std::make_shared<gua::PLodPassDescription>();

  auto pipe = std::make_shared<gua::PipelineDescription>();
  pipe->add_pass(std::make_shared<gua::MLodPassDescription>());
  pipe->add_pass(PLod_Pass);
  pipe->add_pass(std::make_shared<gua::BBoxPassDescription>());
  pipe->add_pass(std::make_shared<gua::LightVisibilityPassDescription>());
  pipe->add_pass(std::make_shared<gua::ResolvePassDescription>());
  pipe->add_pass(std::make_shared<gua::DebugViewPassDescription>());
  camera->set_pipeline_description(pipe);

  pipe->get_resolve_pass()->tone_mapping_exposure(1.f);
  pipe->get_resolve_pass()->tone_mapping_method(gua::ResolvePassDescription::ToneMappingMethod::UNCHARTED);

  pipe->get_resolve_pass()->background_mode(gua::ResolvePassDescription::BackgroundMode::SKYMAP_TEXTURE);
  pipe->get_resolve_pass()->background_texture("data/textures/envlightmap.jpg");

  //init window and window behaviour
  auto window = std::make_shared<gua::GlfwWindow>();
  gua::WindowDatabase::instance()->add("main_window", window);
  window->config.set_enable_vsync(false);
  window->config.set_size(resolution);
  window->config.set_resolution(resolution);
  window->config.set_stereo_mode(gua::StereoMode::MONO);

  window->on_resize.connect([&](gua::math::vec2ui const& new_size) {
    window->config.set_resolution(new_size);
    camera->config.set_resolution(new_size);
    screen->data.set_size(gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y));
  });

  //trackball controls
  bool drag_mode = false;
  window->on_move_cursor.connect([&](gua::math::vec2 const& pos) {
    float nx = 2.f * float(pos.x - (resolution.x/2))/float(resolution.x);
    float ny = -2.f * float(resolution.y - pos.y - (resolution.y/2))/float(resolution.y);
    if (button_state != -1) {
      if (drag_mode) {
        auto ssize = screen->data.get_size();
        gua::math::vec3 trans = gua::math::vec3(ssize.x *(nx - last_mouse_pos.x), ssize.y * (ny - last_mouse_pos.y), 0.f);
        auto object_trans = scm::math::inverse(screen->get_world_transform()) * mlod_transform->get_world_transform();
        mlod_transform->set_world_transform(screen->get_world_transform() * scm::math::make_translation(trans) * object_trans);
      }
      else {
        if (button_state == 0) { // left
          trackball.rotation(trackball_init_pos.x, trackball_init_pos.y, nx, ny);
        }
        if (button_state == 1) { // right
          trackball.dolly(dolly_sens*0.5f * (ny - trackball_init_pos.y));
        }
        if (button_state == 2) { // middle
          float f = dolly_sens < 1.0f ? 0.02f : 0.3f;
          trackball.translation(f*(nx - trackball_init_pos.x), f*(ny - trackball_init_pos.y));
        }
        trackball_init_pos.x = nx;
        trackball_init_pos.y = ny;
      }
    }
    last_mouse_pos.x = nx;
    last_mouse_pos.y = ny;
  });

  window->on_button_press.connect([&](int mousebutton, int action, int mods) {
    if (action == 1) {
      drag_mode = mods == 1;
      trackball_init_pos = last_mouse_pos;
      button_state = mousebutton;
    } else
      button_state = -1;
  });


  window->on_key_press.connect(std::bind([&](gua::PipelineDescription& pipe, gua::SceneGraph& graph, int key, int scancode, int action, int mods) {
    if (action == 0) return;
    switch (std::tolower(key)) {

      case '1':
        PLod_Pass->mode(gua::PLodPassDescription::SurfelRenderMode::HQ_TWO_PASS);
        PLod_Pass->touch();
        break;
      case '2':
        PLod_Pass->mode(gua::PLodPassDescription::SurfelRenderMode::HQ_LINKED_LIST);
        PLod_Pass->touch();
        break;

      default:
        break;
    }
  },
  std::ref(*(camera->get_pipeline_description())),
  std::ref(graph),
  std::placeholders::_1,
  std::placeholders::_2,
  std::placeholders::_3,
  std::placeholders::_4));

  window->open();

  gua::Renderer renderer;

  //application loop
  gua::events::MainLoop loop;
  gua::events::Ticker ticker(loop, 1.0 / 500.0);
  ticker.on_tick.connect([&]() {
    screen->set_transform(scm::math::inverse(gua::math::mat4(trackball.transform_matrix())));

    light->rotate(0.1, 0.f, 1.f, 0.f);
    window->process_events();
    if (window->should_close()) {
      renderer.stop();
      window->close();
      loop.stop();
    }
    else {


      renderer.queue_draw({ &graph });
      std::cout << "FPS: " << window->get_rendering_fps() << "  Frametime: " << 1000.f / window->get_rendering_fps() << std::endl;
    }
  });

  loop.start();

  return 0;
}
Пример #2
0
int main(int argc, char** argv) {
  // initialize guacamole
  gua::init(argc, argv);

  // setup scene
  gua::SceneGraph graph("main_scenegraph");

  gua::TriMeshLoader loader;

  auto teapot_mat(gua::MaterialShaderDatabase::instance()
                  ->lookup("gua_default_material")
                  ->make_new_material());

  teapot_mat->set_render_wireframe(false);
  teapot_mat->set_show_back_faces(false);

  auto transform = graph.add_node<gua::node::TransformNode>("/", "transform");
  auto teapot(loader.create_geometry_from_file(
      "teapot", "data/objects/teapot.obj",
      teapot_mat,
      gua::TriMeshLoader::NORMALIZE_POSITION |
      gua::TriMeshLoader::NORMALIZE_SCALE) );

  graph.add_node("/transform", teapot);
  teapot->set_draw_bounding_box(true);

  auto portal = graph.add_node<gua::node::TexturedQuadNode>("/", "portal");
  portal->data.set_size(gua::math::vec2(1.2f, 0.8f));
  portal->data.set_texture("portal");
  portal->translate(0.5f, 0.f, -0.2f);
  portal->rotate(-30, 0.f, 1.f, 0.f);

  auto light2 = graph.add_node<gua::node::LightNode>("/", "light2");
  light2->data.set_type(gua::node::LightNode::Type::POINT);
  light2->data.brightness = 150.0f;
  light2->scale(12.f);
  light2->translate(-3.f, 5.f, 5.f);

  auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen");
  screen->data.set_size(gua::math::vec2(1.92f, 1.08f));
  screen->translate(0, 0, 1.0);

  auto portal_screen =
      graph.add_node<gua::node::ScreenNode>("/", "portal_screen");
  portal_screen->translate(0.0, 0.0, 5.0);
  portal_screen->rotate(90, 0.0, 1.0, 0.0);
  portal_screen->data.set_size(gua::math::vec2(1.2f, 0.8f));

  // add mouse interaction
  gua::utils::Trackball trackball(0.01, 0.002, 0.2);

  // setup rendering pipeline and window
  auto resolution = gua::math::vec2ui(1920, 1080);

  auto portal_camera =
      graph.add_node<gua::node::CameraNode>("/portal_screen", "portal_cam");
  portal_camera->translate(0, 0, 2.0);
  portal_camera->config.set_resolution(gua::math::vec2ui(1200, 800));
  portal_camera->config.set_screen_path("/portal_screen");
  portal_camera->config.set_scene_graph_name("main_scenegraph");
  portal_camera->config.set_output_texture_name("portal");
  portal_camera->config.set_enable_stereo(false);

  auto portal_pipe = std::make_shared<gua::PipelineDescription>();
  portal_pipe->add_pass(std::make_shared<gua::TriMeshPassDescription>());
  portal_pipe->add_pass(
      std::make_shared<gua::LightVisibilityPassDescription>());

  auto resolve_pass = std::make_shared<gua::ResolvePassDescription>();
  resolve_pass->background_mode(
      gua::ResolvePassDescription::BackgroundMode::QUAD_TEXTURE);
  resolve_pass->tone_mapping_exposure(1.0f);

  portal_pipe->add_pass(resolve_pass);
  portal_pipe->add_pass(std::make_shared<gua::DebugViewPassDescription>());

  portal_camera->set_pipeline_description(portal_pipe);

  auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam");
  camera->translate(0, 0, 2.0);
  camera->config.set_resolution(resolution);
  camera->config.set_screen_path("/screen");
  camera->config.set_scene_graph_name("main_scenegraph");
  camera->config.set_output_window_name("main_window");
  camera->config.set_enable_stereo(false);
  camera->set_pre_render_cameras({portal_camera});

  camera->get_pipeline_description()->get_resolve_pass()->tone_mapping_exposure(
    1.0f);
  camera->get_pipeline_description()->add_pass(
    std::make_shared<gua::DebugViewPassDescription>());

  auto window = std::make_shared<gua::GlfwWindow>();
  gua::WindowDatabase::instance()->add("main_window", window);

  window->config.set_enable_vsync(false);
  window->config.set_size(resolution);
  window->config.set_resolution(resolution);
  window->config.set_stereo_mode(gua::StereoMode::MONO);

  window->on_resize.connect([&](gua::math::vec2ui const& new_size) {
    window->config.set_resolution(new_size);
    camera->config.set_resolution(new_size);
    screen->data.set_size(
        gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y));
  });
  window->on_move_cursor.connect(
      [&](gua::math::vec2 const& pos) { trackball.motion(pos.x, pos.y); });
  window->on_button_press.connect(
      std::bind(mouse_button, std::ref(trackball), std::placeholders::_1,
                std::placeholders::_2, std::placeholders::_3));

  gua::Renderer renderer;

  // application loop
  gua::events::MainLoop loop;
  gua::events::Ticker ticker(loop, 1.0 / 500.0);

  ticker.on_tick.connect([&]() {

    // apply trackball matrix to object
    gua::math::mat4 modelmatrix =
        scm::math::make_translation(trackball.shiftx(), trackball.shifty(),
                                    trackball.distance()) *
        gua::math::mat4(trackball.rotation());

    transform->set_transform(modelmatrix);

    if (window->should_close()) {
      renderer.stop();
      window->close();
      loop.stop();
    } else {
      renderer.queue_draw({&graph});
    }
  });

  loop.start();

  return 0;
}
Пример #3
0
int main(int argc, char** argv) {
  // initialize guacamole
  gua::init(argc, argv);

  // setup scene
  gua::SceneGraph graph("main_scenegraph");

  gua::TriMeshLoader loader;

  auto transform = graph.add_node<gua::node::TransformNode>("/", "transform");
  auto cube(loader.create_geometry_from_file(
      "cube", "data/objects/cube.obj",
      gua::TriMeshLoader::NORMALIZE_POSITION |
      gua::TriMeshLoader::NORMALIZE_SCALE |  
      gua::TriMeshLoader::MAKE_PICKABLE)  );
  graph.add_node("/transform", cube);

  scm::math::vec3d cube_translation(0.0, 0.0, -3.0);

  cube->set_draw_bounding_box(true);

  auto ray_geometry(loader.create_geometry_from_file(
      "ray_geometry", "data/objects/cylinder.obj",
      gua::TriMeshLoader::NORMALIZE_POSITION |
      gua::TriMeshLoader::NORMALIZE_SCALE)  );
  graph.add_node("/", ray_geometry);

  ray_geometry->scale(0.02, 0.02, 0.1);


  auto light2 = graph.add_node<gua::node::LightNode>("/", "light2");
  light2->data.set_type(gua::node::LightNode::Type::POINT);
  light2->data.brightness = 150.0f;
  light2->scale(12.f);
  light2->translate(-3.f, 5.f, 5.f);

  auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen");
  screen->data.set_size(gua::math::vec2(1.92f, 1.08f));
  screen->translate(0, 0, 1.0);


  // add mouse interaction
  gua::utils::Trackball trackball(0.01, 0.002, 0.2);

  // setup rendering pipeline and window
  auto resolution = gua::math::vec2ui(1920, 1080);

  auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam");
  camera->translate(0, 0, 2.0);
  camera->config.set_resolution(resolution);
  camera->config.set_screen_path("/screen");
  camera->config.set_scene_graph_name("main_scenegraph");
  camera->config.set_output_window_name("Picking Example");
  camera->config.set_enable_stereo(false);

  camera->get_pipeline_description()->get_resolve_pass()->tone_mapping_exposure(
    1.0f);
  camera->get_pipeline_description()->add_pass(
    std::make_shared<gua::DebugViewPassDescription>());

  auto window = std::make_shared<gua::GlfwWindow>();
  gua::WindowDatabase::instance()->add("Picking Example", window);

  window->config.set_enable_vsync(false);
  window->config.set_size(resolution);
  window->config.set_resolution(resolution);
  window->config.set_stereo_mode(gua::StereoMode::MONO);

  window->on_resize.connect([&](gua::math::vec2ui const& new_size) {
    window->config.set_resolution(new_size);
    camera->config.set_resolution(new_size);
    screen->data.set_size(
        gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y));
  });
  window->on_move_cursor.connect(
      [&](gua::math::vec2 const& pos) { trackball.motion(pos.x, pos.y); });
  window->on_button_press.connect(
      std::bind(mouse_button, std::ref(trackball), std::placeholders::_1,
                std::placeholders::_2, std::placeholders::_3));

  gua::Renderer renderer;

  // application loop
  gua::events::MainLoop loop;
  gua::events::Ticker ticker(loop, 1.0 / 500.0);

  scm::math::vec3d camera_positon(0.0, 0.0, 2.0);
  scm::math::vec3d negative_z_viewing_direction(0.0, 0.0, -100.0);
  scm::math::vec3d::value_type t_max(200.0);

  //create ray that is located in the origin of the current screen and looks along the negative z-axis (pick ray is seen as circle)
  gua::Ray ray_from_camera_position(camera_positon, negative_z_viewing_direction, t_max);

  size_t frame_count = 0;

  ticker.on_tick.connect([&]() {

    // apply trackball matrix to object
    gua::math::mat4 modelmatrix =
        scm::math::make_translation(cube_translation[0], cube_translation[1], cube_translation[2]) * 
        scm::math::make_translation(trackball.shiftx(), trackball.shifty(),
                                    trackball.distance()) *
        gua::math::mat4(trackball.rotation());

    transform->set_transform(modelmatrix);

    if (window->should_close()) {
      renderer.stop();
      window->close();
      loop.stop();
    } else {

      //std::set<gua::PickResult> pick_results;
      //cube->ray_test_impl(ray_from_camera_position, gua::PickResult::Options::PICK_ONLY_FIRST_FACE, gua::Mask(), pick_results);

      auto pick_results = graph.ray_test(ray_from_camera_position, gua::PickResult::Options::PICK_ONLY_FIRST_FACE | gua::PickResult::Options::GET_WORLD_POSITIONS);


      if(0 == (++frame_count) % 100) {
        if(pick_results.size()) {
          //print first picked face world position result
          std::cout << "World space intersection position: " << pick_results.begin()->world_position << "\n";
        }
      }
      
      renderer.queue_draw({&graph});
    }
  });

  loop.start();

  return 0;
}
Пример #4
0
int main(int argc, char** argv)
{
    // initialize guacamole
    gua::init(argc, argv);

    // setup scene
    gua::SceneGraph graph("main_scenegraph");

    gua::TriMeshLoader loader;
    auto add_mesh = [&](int x, int y, int z) {
        auto t = graph.add_node<gua::node::TransformNode>("/", "mesh_" + std::to_string(x) + "_" + std::to_string(y));
        t->scale(0.5);
        t->translate((x - COUNT * 0.5 + 0.5) / 2, (y - COUNT * 0.5 + 0.5) / 2, (z - COUNT * 0.5 + 0.5) / 2);

        auto mesh(loader.create_geometry_from_file("teapot", "data/objects/teapot.obj", gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE));
        t->add_child(mesh);
    };

    for(int x(0); x < COUNT; ++x)
    {
        for(int y(0); y < COUNT; ++y)
        {
            for(int z(0); z < COUNT; ++z)
            {
                add_mesh(x, y, z);
            }
        }
    }

    auto resolution = gua::math::vec2ui(1920, 1080);

    auto light = graph.add_node<gua::node::LightNode>("/", "light");
    light->data.set_type(gua::node::LightNode::Type::POINT);
    light->scale(4.4f);
    light->translate(1.f, 0.f, 2.f);

    auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen");
    screen->data.set_size(gua::math::vec2(0.001 * resolution.x, 0.001 * resolution.y));
    screen->translate(0, 0, 1.0);

    auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam");
    camera->translate(0, 0, 2.0);
    camera->config.set_resolution(resolution);
    camera->config.set_screen_path("/screen");
    camera->config.set_scene_graph_name("main_scenegraph");
    camera->config.set_output_window_name("main_window");
    camera->get_pipeline_description()->get_resolve_pass()->tone_mapping_exposure(0.8f);

    auto plane_transform = graph.add_node<gua::node::TransformNode>("/", "plane_transform");

    auto add_clipping_plane = [&](gua::math::vec3 const& pos, gua::math::vec4 const& rot) {
        auto clipping_plane = graph.add_node<gua::node::ClippingPlaneNode>("/plane_transform", "clipping_plane");
        clipping_plane->rotate(rot.x, rot.y, rot.z, rot.w);
        clipping_plane->translate(pos);
        auto plane(loader.create_geometry_from_file("plane", "data/objects/plane.obj", gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE));
        plane->rotate(-90, 1, 0, 0);
        // clipping_plane->add_child(plane);
    };

    add_clipping_plane(gua::math::vec3(0, 0, -0.5), gua::math::vec4(180, 1, 0, 0));
    add_clipping_plane(gua::math::vec3(0, 0, 0.5), gua::math::vec4(0, 0, 0, 0));
    add_clipping_plane(gua::math::vec3(0, 0.5, 0), gua::math::vec4(-90, 1, 0, 0));
    add_clipping_plane(gua::math::vec3(0, -0.5, 0), gua::math::vec4(90, 1, 0, 0));
    add_clipping_plane(gua::math::vec3(-0.5, 0, 0), gua::math::vec4(-90, 0, 1, 0));
    add_clipping_plane(gua::math::vec3(0.5, 0, 0), gua::math::vec4(90, 0, 1, 0));

    // auto clipping_plane_2 = graph.add_node<gua::node::ClippingPlaneNode>("/plane_transform", "clipping_plane_2");
    // clipping_plane_2->rotate(90, 1, 0, 0);
    // clipping_plane_2->translate(0, 0.5, 0);

    // add mouse interaction
    gua::utils::Trackball trackball(0.01, 0.002, 0.2);

    auto window = std::make_shared<gua::GlfwWindow>();
    gua::WindowDatabase::instance()->add("main_window", window);
    window->config.set_enable_vsync(true);
    window->config.set_size(resolution);
    window->config.set_resolution(resolution);

    window->on_resize.connect([&](gua::math::vec2ui const& new_size) {
        window->config.set_resolution(new_size);
        camera->config.set_resolution(new_size);
        screen->data.set_size(gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y));
    });

    window->on_move_cursor.connect([&](gua::math::vec2 const& pos) { trackball.motion(pos.x, pos.y); });
    window->on_button_press.connect(std::bind(mouse_button, std::ref(trackball), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));

    window->open();

    gua::Renderer renderer;

    // application loop
    gua::events::MainLoop loop;
    gua::events::Ticker ticker(loop, 1.0 / 500.0);

    ticker.on_tick.connect([&]() {
        // apply trackball matrix to object
        gua::math::mat4 modelmatrix = scm::math::make_translation(gua::math::float_t(trackball.shiftx()), gua::math::float_t(trackball.shifty()), gua::math::float_t(trackball.distance())) *
                                      gua::math::mat4(trackball.rotation());

        plane_transform->set_transform(modelmatrix);

        window->process_events();
        if(window->should_close())
        {
            renderer.stop();
            window->close();
            loop.stop();
        }
        else
        {
            renderer.queue_draw({&graph});
        }
    });

    loop.start();

    return 0;
}
Пример #5
0
int main(int argc, char** argv) {

  // initialize guacamole
  gua::init(argc, argv);

  auto load_mat = [](std::string const& file){
    gua::MaterialShaderDescription desc;
    desc.load_from_file(file);
    auto shader(std::make_shared<gua::MaterialShader>(file, std::make_shared<gua::MaterialShaderDescription>(desc)));
    gua::MaterialShaderDatabase::instance()->add(shader);
    return shader->make_new_material();
  };

  // setup scene
  gua::SceneGraph graph("main_scenegraph");

  gua::TriMeshLoader loader;

  auto transform = graph.add_node<gua::node::TransformNode>("/", "transform");

  // load material and create monkey geometry
  auto projective_material(load_mat("data/materials/Projective_Texture_Material.gmd"));
  projective_material->set_uniform("projective_texture", std::string("data/textures/smiley.jpg"));

  auto monkey(loader.create_geometry_from_file("monkey", "data/objects/monkey.obj", projective_material, gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE));
  monkey->scale(3);
  monkey->translate(0.0, 0.0, -1.0);
  graph.add_node("/transform", monkey);

  auto light2 = graph.add_node<gua::node::LightNode>("/", "light2");
  light2->data.set_type(gua::node::LightNode::Type::POINT);
  light2->data.brightness = 150.0f;
  light2->scale(12.f);
  light2->translate(-3.f, 5.f, 5.f);

  auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen");
  screen->data.set_size(gua::math::vec2(1.92f, 1.08f));
  screen->translate(0, 0, 1.0);

  // add mouse interaction
  gua::utils::Trackball trackball(0.01, 0.002, 0.2);

  // setup rendering pipeline and window
  auto resolution = gua::math::vec2ui(1920, 1080);

  auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam");
  camera->translate(0, 0, 2.0);
  camera->config.set_resolution(resolution);
  camera->config.set_screen_path("/screen");
  camera->config.set_scene_graph_name("main_scenegraph");
  camera->config.set_output_window_name("main_window");
  camera->config.set_enable_stereo(false);
  camera->get_pipeline_description()->add_pass(std::make_shared<gua::DebugViewPassDescription>());

  // projector transform node, screen and transform node
  auto projector_transform = graph.add_node<gua::node::TransformNode>("/", "projector_transform");
  projector_transform->translate(0.7, 0.0, 0.7);
  projector_transform->rotate(45.0, 0.0, 1.0, 0.0);
  graph.add_node("/", projector_transform);

  auto projector_screen = graph.add_node<gua::node::ScreenNode>("/projector_transform", "projector_screen");
  projector_screen->data.set_size(gua::math::vec2(0.5f, 0.5f));
  projector_screen->translate(0.0, 0.0, -1.0);
  graph.add_node("/projector_transform", projector_screen);

  auto projector_geometry(loader.create_geometry_from_file("projector_geometry", "data/objects/projector.obj", gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::LOAD_MATERIALS));
  projector_geometry->scale(0.1);
  graph.add_node("/projector_transform", projector_geometry);


  auto window = std::make_shared<gua::GlfwWindow>();
  gua::WindowDatabase::instance()->add("main_window", window);
  window->config.set_enable_vsync(false);
  window->config.set_size(resolution);
  window->config.set_resolution(resolution);
  window->config.set_stereo_mode(gua::StereoMode::MONO);
  window->on_resize.connect([&](gua::math::vec2ui const& new_size) {
    window->config.set_resolution(new_size);
    camera->config.set_resolution(new_size);
    screen->data.set_size(gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y));
  });
  window->on_move_cursor.connect([&](gua::math::vec2 const& pos) {
    trackball.motion(pos.x, pos.y);
  });
  window->on_button_press.connect(std::bind(mouse_button, std::ref(trackball), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));

  window->open();

  gua::Renderer renderer;

  // application loop
  gua::events::MainLoop loop;
  gua::events::Ticker ticker(loop, 1.0/500.0);

  ticker.on_tick.connect([&]() {

    // apply trackball matrix to object
    gua::math::mat4 modelmatrix = scm::math::make_translation(gua::math::float_t(trackball.shiftx()),
      gua::math::float_t(trackball.shifty()),
      gua::math::float_t(trackball.distance())) * gua::math::mat4(trackball.rotation());

    projector_transform->set_transform(modelmatrix);

    // use the guacamole frustum to calculate a view mat and projection mat for the projection
    auto projection_frustum = gua::Frustum::perspective(projector_transform->get_world_transform(),
                                                   projector_screen->get_scaled_world_transform(),
                                                   0.1f, 1000.0f);

    auto projection_mat = projection_frustum.get_projection();
    auto view_mat = projection_frustum.get_view();

    // set these matrices as uniforms for the projection material
    projective_material->set_uniform("projective_texture_matrix", gua::math::mat4f(projection_mat * view_mat));
    projective_material->set_uniform("view_texture_matrix", gua::math::mat4f(view_mat));

    window->process_events();
    if (window->should_close()) {
      renderer.stop();
      window->close();
      loop.stop();
    } else {
      renderer.queue_draw({&graph});
    }
  });

  loop.start();

  return 0;
}