void add_passes(iterator begin, iterator end) { for (; begin != end; ++begin) { add_pass(*begin); } }
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; }
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; }
int main(int argc, char** argv) { // initialize guacamole gua::init(argc, argv); ///////////////////////////////////////////////////////////////////////////// // create a set of materials ///////////////////////////////////////////////////////////////////////////// // create simple untextured material shader auto pbr_keep_input_desc = std::make_shared<gua::MaterialShaderDescription>("./data/materials/PBR_use_input_color.gmd"); auto pbr_uniform_color_desc = std::make_shared<gua::MaterialShaderDescription>("./data/materials/PBR_uniform_color.gmd"); //use this material for models where shading does not make sense auto pbr_keep_color_shader(std::make_shared<gua::MaterialShader>("PBR_pass_input_color", pbr_keep_input_desc)); auto pbr_overwrite_color_shader(std::make_shared<gua::MaterialShader>("PBR_overwrite_input_color", pbr_uniform_color_desc)); gua::MaterialShaderDatabase::instance()->add(pbr_keep_color_shader); gua::MaterialShaderDatabase::instance()->add(pbr_overwrite_color_shader); // create different materials for point-based input auto plod_glossy = pbr_keep_color_shader->make_new_material(); auto plod_rough = pbr_keep_color_shader->make_new_material(); auto plod_passthrough = pbr_keep_color_shader->make_new_material(); // glossy has high metalness, low roughness and no emissivity (=no passthrough) plod_glossy->set_uniform("metalness", 1.0f); plod_glossy->set_uniform("roughness", 0.3f); plod_glossy->set_uniform("emissivity", 0.0f); // rough has no metalness, high roughness and no emissivity (=no passthrough) plod_rough->set_uniform("metalness", 0.0f); plod_rough->set_uniform("roughness", 0.8f); plod_rough->set_uniform("emissivity", 1.0f); // passthrough has emissivity of 1.0 plod_passthrough->set_uniform("emissivity", 1.0f); auto rough_white = pbr_overwrite_color_shader->make_new_material(); rough_white->set_uniform("color", gua::math::vec3f(1.0f, 1.0f, 1.0f)); rough_white->set_uniform("metalness", 0.0f); rough_white->set_uniform("roughness", 0.8f); rough_white->set_uniform("emissivity", 0.0f); auto rough_red = pbr_overwrite_color_shader->make_new_material(); rough_red->set_uniform("color", gua::math::vec3f(0.8f, 0.0f, 0.0f)); rough_red->set_uniform("metalness", 0.0f); rough_red->set_uniform("roughness", 0.8f); rough_red->set_uniform("emissivity", 0.0f); // setup scene gua::SceneGraph graph("main_scenegraph"); gua::LodLoader plodLoader; plodLoader.set_upload_budget_in_mb(32); plodLoader.set_render_budget_in_mb(2048); plodLoader.set_out_of_core_budget_in_mb(4096); auto transform = graph.add_node<gua::node::TransformNode>("/", "transform"); auto model_xf = graph.add_node<gua::node::TransformNode>("/transform", "model_xf"); auto setup_plod_node = [](std::shared_ptr<gua::node::PLodNode> const& node) { node->set_radius_scale(1.0f); node->set_enable_backface_culling_by_normal(false); node->set_draw_bounding_box(true); }; #if WIN32 auto plod_pig_node = plodLoader.load_lod_pointcloud("plod_pig", "data/objects/Area_4_hunter_with_bow_knn.bvh", plod_rough, gua::LodLoader::NORMALIZE_POSITION | gua::LodLoader::NORMALIZE_SCALE | gua::LodLoader::MAKE_PICKABLE); #else auto plod_pig_node = plodLoader.load_lod_pointcloud("plod_pig", "/mnt/pitoti/3d_pitoti/groundtruth_data/rocks/seradina12c/areas/objects/Area_4_hunter_with_bow_knn.bvh", plod_rough, gua::LodLoader::NORMALIZE_POSITION | gua::LodLoader::NORMALIZE_SCALE | gua::LodLoader::MAKE_PICKABLE); #endif plod_pig_node->scale(5.0, 5.0, 5.0); plod_pig_node->rotate(269, gua::math::vec3(0.0, 0.0, 1.0)); gua::TriMeshLoader loader; auto root_plod_pig_model = graph.add_node("/", plod_pig_node); auto nav = graph.add_node<gua::node::TransformNode>("/", "nav"); nav->translate(0.0, 0.0, 1.0); #if WIN32 auto window = std::make_shared<gua::OculusWindow>(":0.0"); gua::WindowDatabase::instance()->add("main_window", window); window->config.set_enable_vsync(false); window->config.set_fullscreen_mode(false); window->open(); #else auto window = std::make_shared<gua::OculusWindow>(":0.0"); gua::WindowDatabase::instance()->add("main_window", window); window->config.set_enable_vsync(false); window->config.set_fullscreen_mode(true); window->config.set_size(window->get_window_resolution()); window->config.set_resolution(window->get_window_resolution()); window->open(); #endif //get the resolution from the oculus window gua::math::vec2ui res(window->get_window_resolution()); auto resolve_pass = std::make_shared<gua::ResolvePassDescription>(); resolve_pass->background_mode(gua::ResolvePassDescription::BackgroundMode::QUAD_TEXTURE); resolve_pass->tone_mapping_exposure(1.0f); auto neck = graph.add_node<gua::node::TransformNode>("/nav", "neck"); auto camera = graph.add_node<gua::node::CameraNode>("/nav/neck", "cam"); float camera_trans_y = 0.0; float camera_trans_z = 0.0; camera->translate(0.0, camera_trans_y, camera_trans_z); camera->config.set_resolution( res ); camera->config.set_left_screen_path("/nav/neck/cam/left_screen"); camera->config.set_right_screen_path("/nav/neck/cam/right_screen"); camera->config.set_scene_graph_name("main_scenegraph"); camera->config.set_output_window_name("main_window"); camera->config.set_enable_stereo(true); camera->config.set_eye_dist(window->get_IPD()); auto pipe = std::make_shared<gua::PipelineDescription>(); pipe->add_pass(std::make_shared<gua::PLodPassDescription>()); pipe->add_pass(std::make_shared<gua::LightVisibilityPassDescription>()); pipe->add_pass(std::make_shared<gua::ResolvePassDescription>()); camera->set_pipeline_description(pipe); // retreive the complete viewing setup from the oculus window //************** auto left_screen = graph.add_node<gua::node::ScreenNode>("/nav/neck/cam", "left_screen"); left_screen->data.set_size(window->get_left_screen_size()); left_screen->translate(window->get_left_screen_translation()); auto right_screen = graph.add_node<gua::node::ScreenNode>("/nav/neck/cam", "right_screen"); right_screen->data.set_size(window->get_right_screen_size()); right_screen->translate(window->get_right_screen_translation()); //****************/ gua::Renderer renderer; gua::Timer timer; timer.start(); double time(0); float desired_frame_time(1.0 / 60.0); gua::events::MainLoop loop; // application loop gua::events::Ticker ticker(loop, desired_frame_time); ticker.on_tick.connect([&]() { double frame_time(timer.get_elapsed()); time += frame_time; timer.reset(); window->process_events(); std::function<void (std::shared_ptr<gua::node::Node>, int)> rotate; rotate = [&](std::shared_ptr<gua::node::Node> node, int depth) { node->rotate(frame_time * (1+depth) * 0.5, 1, 1, 0); for (auto child: node->get_children()) { rotate(child, ++depth); } }; float frame_offset = 1.0 * frame_time; camera->set_transform(window->get_oculus_sensor_orientation()); //neck->set_transform(window->get_oculus_sensor_orientation()); renderer.queue_draw({&graph}); }); loop.start(); return 0; }
int main(int argc, char** argv) { //auto resolution = gua::math::vec2ui(800, 600); auto resolution = gua::math::vec2ui(3840, 2160); // initialize guacamole int argc_d = 0; char** argv_d = {}; gua::init(argc_d, argv_d); // setup scene gua::SceneGraph graph("main_scenegraph"); auto desc(std::make_shared<gua::MaterialShaderDescription>()); desc->load_from_file("data/materials/SimpleMaterial.gmd"); auto shader(std::make_shared<gua::MaterialShader>("simple_mat", desc)); gua::MaterialShaderDatabase::instance()->add(shader); auto mat(shader->make_new_material()); gua::TriMeshLoader trimeshloader; auto teapot_geode( trimeshloader.create_geometry_from_file("teapot_geode", "data/objects/teapot.obj", mat, gua::TriMeshLoader::DEFAULTS)); auto plate_geode( trimeshloader.create_geometry_from_file("plate_geode", "data/objects/plate.obj", mat, gua::TriMeshLoader::DEFAULTS)); auto head = graph.add_node<gua::node::TransformNode>("/", "head"); head->translate(0.0, 0.0, 8.0); auto teapot = graph.add_node<gua::node::TransformNode>("/", "teapot"); teapot->scale(2.0f); auto plate = graph.add_node<gua::node::TransformNode>("/", "plate"); graph.add_node("/teapot", teapot_geode); graph.add_node("/plate", plate_geode); const float aspect = resolution.x * 1.0f / resolution.y; auto pipe = std::make_shared<gua::PipelineDescription>(); pipe->add_pass(std::make_shared<gua::TriMeshPassDescription>()); pipe->add_pass(std::make_shared<gua::TexturedQuadPassDescription>()); //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::SSAAPassDescription>()); //pipe->add_pass(std::make_shared<gua::DebugViewPassDescription>()); auto camera_tl = graph.add_node<gua::node::CameraNode>("/head", "camera_tl"); camera_tl->config.set_output_window_name("window_tl"); camera_tl->config.set_screen_path("/head/camera_tl/screen_tl"); camera_tl->config.set_scene_graph_name("main_scenegraph"); camera_tl->config.set_resolution(resolution); camera_tl->config.set_view_id(1); camera_tl->set_pipeline_description(pipe); auto screen_tl = graph.add_node<gua::node::ScreenNode>("/head/camera_tl", "screen_tl"); screen_tl->data.set_size(gua::math::vec2(1.6, 0.9)); screen_tl->translate(-0.8, 0.45, -2.5); auto camera_tr = graph.add_node<gua::node::CameraNode>("/head", "camera_tr"); camera_tr->config.set_output_window_name("window_tr"); camera_tr->config.set_screen_path("/head/camera_tr/screen_tr"); camera_tr->config.set_scene_graph_name("main_scenegraph"); camera_tr->config.set_resolution(resolution); camera_tr->config.set_view_id(2); camera_tr->set_pipeline_description(pipe); auto screen_tr = graph.add_node<gua::node::ScreenNode>("/head/camera_tr", "screen_tr"); screen_tr->data.set_size(gua::math::vec2(1.6, 0.9)); screen_tr->translate( 0.8f, 0.45, -2.5f); auto camera_bl = graph.add_node<gua::node::CameraNode>("/head", "camera_bl"); camera_bl->config.set_output_window_name("window_bl"); camera_bl->config.set_screen_path("/head/camera_bl/screen_bl"); camera_bl->config.set_scene_graph_name("main_scenegraph"); camera_bl->config.set_resolution(resolution); //camera_bl->config.set_view_id(2); camera_bl->set_pipeline_description(pipe); auto screen_bl = graph.add_node<gua::node::ScreenNode>("/head/camera_bl", "screen_bl"); screen_bl->data.set_size(gua::math::vec2(1.6, 0.9)); screen_bl->translate(-0.8, -0.45, -2.5f); auto camera_br = graph.add_node<gua::node::CameraNode>("/head", "camera_br"); camera_br->config.set_output_window_name("window_br"); camera_br->config.set_screen_path("/head/camera_br/screen_br"); camera_br->config.set_scene_graph_name("main_scenegraph"); camera_br->config.set_resolution(resolution); camera_br->set_pipeline_description(pipe); auto screen_br = graph.add_node<gua::node::ScreenNode>("/head/camera_br", "screen_br"); screen_br->data.set_size(gua::math::vec2(1.6, 0.9)); screen_br->translate( 0.8, -0.45, -2.5f); auto pointlight = graph.add_node<gua::node::LightNode>("/", "pointlight"); pointlight->data.set_type(gua::node::LightNode::Type::POINT); pointlight->scale(30.0f); pointlight->rotate(-90, 1, 0, 0); pointlight->translate(1.0, 18.0, 1.0); pointlight->data.set_falloff(0.1f); pointlight->data.set_color({ 1.0f, 1.0f, 1.0f }); pointlight->data.set_enable_specular_shading(true); pointlight->data.set_enable_diffuse_shading(true); auto add_window = [](std::string const & window_name, std::string const & display, std::shared_ptr<gua::node::CameraNode> const & cam_node) { auto window = std::make_shared<gua::Window>(); window->config.set_display_name(display); window->join_swap_group(1); window->bind_swap_barrier(1); gua::WindowDatabase::instance()->add(window_name, window); set_window_default(window, cam_node->config.get_resolution()); cam_node->config.set_output_window_name(window_name); }; add_window("window_tl", ":0.0", camera_tl); gua::Renderer renderer; // application loop gua::events::MainLoop loop; gua::events::Ticker ticker(loop, 1.0 / 500.0); //gua::Timer frame_timer; //frame_timer.start(); float time_value = 0; // application loop std::size_t cnt = 0; //while (true) { //std::this_thread::sleep_for(std::chrono::milliseconds(10)); ticker.on_tick.connect([&]() { teapot_geode->rotate(0.3, 0, 1, 0); ++cnt; if (cnt == 10) { //add_window("window_tr", ":0.0", camera_tr); add_window("window_tr", ":0.1", camera_tr); } if (cnt == 20) { //add_window("window_bl", ":0.0", camera_bl); add_window("window_bl", ":0.2", camera_bl); } if (cnt == 30) { //add_window("window_br", ":0.0", camera_br); add_window("window_br", ":0.3", camera_br); } // GLFW only allows event processing from main thread if (gua::WindowDatabase::instance()->lookup("window_tl")) { gua::WindowDatabase::instance()->lookup("window_tl")->process_events(); } if (gua::WindowDatabase::instance()->lookup("window_tr")) { gua::WindowDatabase::instance()->lookup("window_tr")->process_events(); } if (gua::WindowDatabase::instance()->lookup("window_bl")) { gua::WindowDatabase::instance()->lookup("window_bl")->process_events(); } if (gua::WindowDatabase::instance()->lookup("window_br")) { gua::WindowDatabase::instance()->lookup("window_br")->process_events(); } plate->translate(-plate->get_bounding_box().center()); plate->rotate(0.04f, 0, 1, 0); plate->translate(plate->get_bounding_box().center()); renderer.queue_draw({ &graph }); }); //} loop.start(); renderer.stop(); return 0; }