sge::renderer::vertex::buffer_unique_ptr sge::renderer::vertex::create_buffer_from_view( sge::renderer::device::core &_device, sge::renderer::vertex::declaration &_vertex_declaration, sge::renderer::vf::dynamic::const_view const &_view, sge::renderer::resource_flags_field const &_resource_flags ) { sge::renderer::vertex::buffer_unique_ptr buffer( _device.create_vertex_buffer( sge::renderer::vertex::buffer_parameters( _vertex_declaration, _view.part_index(), sge::renderer::vertex::count( _view.size() ), _resource_flags ) ) ); sge::renderer::vertex::scoped_lock const lock( *buffer, sge::renderer::lock_mode::writeonly ); std::memcpy( lock.value().data(), _view.data(), _view.part().stride().get() * _view.size().get() ); return buffer; }
int main() try { sge::opencl::system opencl_system; fcppt::io::cout() << FCPPT_TEXT("Querying the number of available platforms...\n"); sge::opencl::platform::object_sequence &platforms( opencl_system.platforms()); if(platforms.empty()) { fcppt::io::cerr() << FCPPT_TEXT("Couldn't find any OpenCL platforms on your system.\n"); return EXIT_FAILURE; } fcppt::io::cout() << FCPPT_TEXT("Number of OpenCL platforms: ") << platforms.size() << FCPPT_TEXT("\n") << FCPPT_TEXT("Platform listing begin:\n") << FCPPT_TEXT("-----------------------\n"); sge::opencl::platform::object_sequence::size_type platform_index = 0; for( sge::opencl::platform::object const ¤t_platform : platforms ) { fcppt::io::cout() << FCPPT_TEXT("\tPlatform ") << platform_index++ << FCPPT_TEXT(":\n") << FCPPT_TEXT("\tName: ") << fcppt::from_std_string( current_platform.name() ) << FCPPT_TEXT("\n") << FCPPT_TEXT("\tVendor: ") << fcppt::from_std_string( current_platform.vendor() ) << FCPPT_TEXT("\n") << FCPPT_TEXT("Profile type: ") << (current_platform.profile() == sge::opencl::platform::profile_type::full ? fcppt::string(FCPPT_TEXT("full")) : fcppt::string(FCPPT_TEXT("embedded"))) << FCPPT_TEXT("\n") << FCPPT_TEXT("\tVersion: ") << current_platform.version().major_part() << FCPPT_TEXT(".") << current_platform.version().minor_part() << FCPPT_TEXT("\n"); if(!current_platform.version().platform_specific().empty()) fcppt::io::cout() << FCPPT_TEXT("\tPlatform specific version info: ") << fcppt::from_std_string(current_platform.version().platform_specific()) << FCPPT_TEXT("\n"); fcppt::io::cout() << FCPPT_TEXT("\tExtension list begin:\n") << FCPPT_TEXT("\t*********************\n") << FCPPT_TEXT("\t\t") << fcppt::from_std_string( boost::algorithm::join( current_platform.extensions(), std::string("\n\t\t"))) << FCPPT_TEXT("\r\t*********************\n") << FCPPT_TEXT("-----------------------\n"); } fcppt::io::cout() << FCPPT_TEXT("Platform listing end\n"); sge::opencl::platform::object_sequence::size_type chosen_platform_index; if(platforms.size() == 1) { chosen_platform_index = 0; } else { fcppt::io::cout() << FCPPT_TEXT("Your choice: "); do chosen_platform_index = query_value_from_user<sge::opencl::platform::object_sequence::size_type>( fcppt::io::cin()); while(chosen_platform_index >= platforms.size()); } fcppt::io::cout() << FCPPT_TEXT("List devices with properties? [y/n] "); fcppt::char_type list_devices; do list_devices = query_value_from_user<fcppt::char_type>( fcppt::io::cin()); while(list_devices != FCPPT_TEXT('y') && list_devices != FCPPT_TEXT('n')); sge::opencl::platform::object &chosen_platform = platforms[chosen_platform_index]; if(list_devices == FCPPT_TEXT('y')) { fcppt::io::cout() << FCPPT_TEXT("Number of devices on this platform: ") << chosen_platform.devices().size() << FCPPT_TEXT('\n') << FCPPT_TEXT("Device listing begin:\n") << FCPPT_TEXT("-----------------------\n"); for( sge::opencl::device::object const ¤t_device : chosen_platform.devices() ) { current_device.output_info( std::cout); fcppt::io::cout() << FCPPT_TEXT("-----------------------\n"); } fcppt::io::cout() << FCPPT_TEXT("-----------------------\n") << FCPPT_TEXT("Device listing end\n"); } fcppt::io::cout() << FCPPT_TEXT("Creating sge::systems object...\n"); sge::window::dim const window_dim{ 1024u, 768u }; sge::systems::instance< brigand::list< sge::systems::with_window, sge::systems::with_renderer< sge::systems::renderer_caps::core > > > const sys( sge::systems::make_list ( // FIXME: Move this higher? sge::systems::config() .log_settings( sge::systems::log_settings{ sge::log::option_container{ sge::log::option{ sge::opencl::log_location(), fcppt::log::level::verbose } } } ) ) ( sge::systems::window( sge::systems::window_source( sge::systems::original_window( sge::window::title( FCPPT_TEXT("Simple OpenCL example") ) ) ) ) .dont_show() ) ( sge::systems::renderer( sge::renderer::pixel_format::object( sge::renderer::pixel_format::color::depth32, sge::renderer::pixel_format::depth_stencil::off, sge::renderer::pixel_format::optional_multi_samples(), sge::renderer::pixel_format::srgb::no ), sge::renderer::display_mode::parameters( sge::renderer::display_mode::vsync::on, sge::renderer::display_mode::optional_object() ), sge::viewport::optional_resize_callback{ sge::viewport::center_on_resize( window_dim ) } ) ) ); fcppt::io::cout() << FCPPT_TEXT("Done. Creating a context with all devices on this platform...\n"); sge::opencl::device::object_ref_sequence const device_refs( fcppt::algorithm::map< sge::opencl::device::object_ref_sequence >( chosen_platform.devices(), []( sge::opencl::device::object &_device ) { return fcppt::make_ref( _device ); } ) ); sge::opencl::context::object main_context( sge::opencl::context::parameters( chosen_platform, device_refs ) .share_with( sys.renderer_device_core()) .error_callback( sge::opencl::context::error_callback{ &opencl_error_callback } ) ); fcppt::io::cout() << FCPPT_TEXT("Context created, listing available planar image formats (read/write)\n"); sge::opencl::memory_object::image::format_sequence const planar_image_formats = main_context.supported_planar_image_formats( CL_MEM_READ_WRITE); for( auto const format : planar_image_formats ) { sge::opencl::memory_object::image::format_output( std::cout, format ); std::cout << '\n'; } fcppt::io::cout() << FCPPT_TEXT("Listing available volume image formats (read/write)...\n"); sge::opencl::memory_object::image::format_sequence const volume_image_formats = main_context.supported_volume_image_formats( CL_MEM_READ_WRITE); for( auto const format : volume_image_formats ) { sge::opencl::memory_object::image::format_output( std::cout, format ); std::cout << '\n'; } fcppt::io::cout() << FCPPT_TEXT("Done, now creating a program..."); sge::opencl::program::object main_program( sys.log_context(), main_context, sge::opencl::program::source_string_sequence{ std::string( "__kernel void hello_kernel(" "float const multiplier," "__global float *input)" "{" "int gid = get_global_id(0);" "int lid = get_local_id(0);" "input[gid] = lid * multiplier;" "}" ) }, sge::opencl::program::optional_build_parameters()); fcppt::io::cout() << FCPPT_TEXT("Program created, building the program...\n"); volatile bool build_finished = false; main_program.build( sge::opencl::program::build_parameters() .notification_callback( sge::opencl::program::notification_callback{ std::bind( &program_build_finished, std::ref( build_finished ) ) } ) ); std::cout << "Waiting for build completion\n"; while(!build_finished) std::cout << "Build not finished yet\n"; fcppt::io::cout() << FCPPT_TEXT("Program built, now creating a kernel...\n"); sge::opencl::kernel::object main_kernel( main_program, sge::opencl::kernel::name( "hello_kernel")); fcppt::io::cout() << FCPPT_TEXT("Kernel created, now creating a vertex buffer...\n"); sge::renderer::vertex::declaration_unique_ptr const vertex_declaration( sys.renderer_device_core().create_vertex_declaration( sge::renderer::vertex::declaration_parameters( sge::renderer::vf::dynamic::make_format<vf::format>()))); sge::renderer::vertex::buffer_unique_ptr const vb( sys.renderer_device_core().create_vertex_buffer( sge::renderer::vertex::buffer_parameters( *vertex_declaration, sge::renderer::vf::dynamic::make_part_index< vf::format, vf::part >(), sge::renderer::vertex::count( 6u), sge::renderer::resource_flags_field{ sge::renderer::resource_flags::readable}))); fcppt::io::cout() << FCPPT_TEXT("Done, now creating OpenCL buffer from it\n"); sge::opencl::memory_object::buffer cl_vb( main_context, *vb, sge::opencl::memory_object::renderer_buffer_lock_mode::write_only); main_kernel.argument( sge::opencl::kernel::argument_index( 1u), cl_vb); main_kernel.argument( sge::opencl::kernel::argument_index( 0u), sge::opencl::kernel::numeric_type( static_cast<cl_float>( 2.0 ) ) ); fcppt::io::cout() << FCPPT_TEXT("Done, now creating a command queue\n"); sge::opencl::command_queue::object main_queue( device_refs[0].get(), main_context, sge::opencl::command_queue::execution_mode::out_of_order, sge::opencl::command_queue::profiling_mode::disabled); fcppt::io::cout() << FCPPT_TEXT("Done, now enqueueing kernel and running it\n"); { sge::opencl::memory_object::scoped_objects scoped_vb( main_queue, sge::opencl::memory_object::base_ref_sequence{ fcppt::reference_to_base< sge::opencl::memory_object::base >( fcppt::make_ref( cl_vb ) ) } ); sge::opencl::command_queue::enqueue_kernel( main_queue, main_kernel, sge::opencl::command_queue::global_dim1( sge::opencl::dim1( vb->linear_size() * 2u ) ), sge::opencl::command_queue::local_dim1( sge::opencl::dim1( 2u ) ), sge::opencl::event::sequence() ); } fcppt::io::cout() << FCPPT_TEXT("Now locking the vb for reading and printing the values\n"); { sge::renderer::vertex::scoped_lock const scoped_vb( *vb, sge::renderer::lock_mode::readwrite); typedef sge::renderer::vf::view<vf::part> vertex_view; vertex_view const vertices( scoped_vb.value()); for( auto const vertex : vertices ) { fcppt::io::cout() << vertex.get<vf::scalar_quantity>() << FCPPT_TEXT('\n'); } } fcppt::io::cout() << FCPPT_TEXT("Done\n"); } catch( fcppt::exception const &_error ) { fcppt::io::cerr() << _error.string() << FCPPT_TEXT('\n'); return EXIT_FAILURE; } catch( std::exception const &_error ) { std::cerr << _error.what() << '\n'; return EXIT_FAILURE; }
awl::main::exit_code const example_main( awl::main::function_context const & ) try { sge::systems::instance< brigand::list< sge::systems::with_window, sge::systems::with_renderer< sge::systems::renderer_caps::core >, sge::systems::with_input > > const sys( sge::systems::make_list ( sge::systems::window( sge::systems::window_source( sge::systems::original_window( sge::window::title( FCPPT_TEXT("sge cg simple test") ) ) ) ) ) ( sge::systems::renderer( sge::renderer::pixel_format::object( sge::renderer::pixel_format::color::depth32, sge::renderer::pixel_format::depth_stencil::off, sge::renderer::pixel_format::optional_multi_samples(), sge::renderer::pixel_format::srgb::no ), sge::renderer::display_mode::parameters( sge::renderer::display_mode::vsync::on, sge::renderer::display_mode::optional_object() ), sge::viewport::optional_resize_callback{ sge::viewport::fill_on_resize() } ) ) ( sge::systems::input( sge::systems::cursor_option_field::null() ) ) ); sge::cg::context::object const cg_context{}; sge::cg::profile::object const vertex_profile( sys.renderer_device_core().create_cg_profile( sge::cg::profile::shader_type::vertex ) ); sge::cg::string const vertex_shader_source( "// This is C2E1v_green from \"The Cg Tutorial\" (Addison-Wesley, ISBN\n" "// 0321194969) by Randima Fernando and Mark J. Kilgard. See page 38.\n" "\n" "struct C2E1v_Output {\n" " float4 position : POSITION;\n" "};\n" "\n" "C2E1v_Output C2E1v_green(float2 position : POSITION)\n" "{\n" " C2E1v_Output OUT;\n" "\n" " OUT.position = float4(position,0,1);\n" "\n" " return OUT;\n" "}\n" ); sge::cg::program::object vertex_program( sge::cg::program::from_string_parameters( cg_context, sge::cg::program::source_type::text, vertex_profile, sge::cg::program::source( vertex_shader_source ), sge::cg::program::main_function( "C2E1v_green" ), sys.renderer_device_core().cg_compile_options( cg_context, vertex_profile ) ) ); sge::renderer::cg::loaded_program_unique_ptr const loaded_vertex_program( sys.renderer_device_core().load_cg_program( vertex_program ) ); sge::cg::profile::object const pixel_profile( sys.renderer_device_core().create_cg_profile( sge::cg::profile::shader_type::pixel ) ); sge::cg::string const pixel_shader_source( "struct C3E3f_Output {\n" " float4 color : COLOR;\n" "};\n" "C3E3f_Output\n" "C3E3f_simple()\n" "{\n" " C3E3f_Output OUT;\n" "\n" " OUT.color = float4(0,1,0,1);\n" " return OUT;\n" "}\n" ); sge::cg::program::object pixel_program( sge::cg::program::from_string_parameters( cg_context, sge::cg::program::source_type::text, pixel_profile, sge::cg::program::source( pixel_shader_source ), sge::cg::program::main_function( "C3E3f_simple" ), sys.renderer_device_core().cg_compile_options( cg_context, pixel_profile ) ) ); sge::renderer::cg::loaded_program_unique_ptr const loaded_pixel_program( sys.renderer_device_core().load_cg_program( pixel_program ) ); typedef sge::renderer::vf::pos< float, 3 > pos3_type; typedef sge::renderer::vf::part< brigand::list< pos3_type > > format_part; typedef sge::renderer::vf::format< brigand::list< format_part > > format; sge::renderer::vertex::declaration_unique_ptr const vertex_declaration( sys.renderer_device_core().create_vertex_declaration( sge::renderer::vertex::declaration_parameters( sge::renderer::vf::dynamic::make_format< format >() ) ) ); sge::renderer::vertex::buffer_unique_ptr const vertex_buffer( sys.renderer_device_core().create_vertex_buffer( sge::renderer::vertex::buffer_parameters( *vertex_declaration, sge::renderer::vf::dynamic::make_part_index< format, format_part >(), sge::renderer::vertex::count( 3u ), sge::renderer::resource_flags_field::null() ) ) ); { sge::renderer::vertex::scoped_lock const vblock( *vertex_buffer, sge::renderer::lock_mode::writeonly ); typedef sge::renderer::vf::view< format_part > vertex_view; vertex_view const vertices( vblock.value() ); vertex_view::iterator vb_it( vertices.begin() ); typedef pos3_type::packed_type vec3; (*vb_it).set< pos3_type >( vec3( -1.f, 1.f, 0.f ) ); ++vb_it; (*vb_it).set< pos3_type >( vec3( -1.f, -1.f, 0.f ) ); ++vb_it; (*vb_it).set< pos3_type >( vec3( 1.f, 1.f, 0.f ) ); } auto const draw( [ &loaded_pixel_program, &loaded_vertex_program, &sys, &vertex_buffer, &vertex_declaration ]{ sge::renderer::context::scoped_core const scoped_block( sys.renderer_device_core(), sys.renderer_device_core().onscreen_target() ); scoped_block.get().clear( sge::renderer::clear::parameters() .back_buffer( sge::image::color::any::object{ sge::image::color::predef::black() } ) ); sge::renderer::vertex::scoped_declaration_and_buffers const vb_context( scoped_block.get(), *vertex_declaration, sge::renderer::vertex::const_buffer_ref_container{ fcppt::make_cref( *vertex_buffer ) } ); sge::renderer::cg::scoped_program const scoped_vertex_program( scoped_block.get(), *loaded_vertex_program ); sge::renderer::cg::scoped_program const scoped_pixel_program( scoped_block.get(), *loaded_pixel_program ); scoped_block.get().render_nonindexed( sge::renderer::vertex::first( 0u ), sge::renderer::vertex::count( 3u ), sge::renderer::primitive_type::triangle_list ); } ); return sge::window::loop( sys.window_system(), sge::window::loop_function{ [ &sys, &draw ]( awl::event::base const &_event ) { sge::systems::quit_on_escape( sys, _event ); fcppt::optional::maybe_void( fcppt::cast::dynamic< sge::renderer::event::render const >( _event ), [ &draw ]( fcppt::reference< sge::renderer::event::render const > ) { draw(); } ); } } ); } catch( fcppt::exception const &_error ) { awl::show_error( _error.string() ); return awl::main::exit_failure(); } catch( std::exception const &_error ) { awl::show_error_narrow( _error.what() ); return awl::main::exit_failure(); }
awl::main::exit_code const example_main( awl::main::function_context const & ) try { sge::systems::instance< brigand::list< sge::systems::with_window, sge::systems::with_renderer< sge::systems::renderer_caps::ffp >, sge::systems::with_input, sge::systems::with_image2d > > const sys( sge::systems::make_list ( sge::systems::window( sge::systems::window_source( sge::systems::original_window( sge::window::title( FCPPT_TEXT("sge cg point sprites test") ) ) ) ) ) ( sge::systems::renderer( sge::renderer::pixel_format::object( sge::renderer::pixel_format::color::depth32, sge::renderer::pixel_format::depth_stencil::off, sge::renderer::pixel_format::optional_multi_samples(), sge::renderer::pixel_format::srgb::no ), sge::renderer::display_mode::parameters( sge::renderer::display_mode::vsync::on, sge::renderer::display_mode::optional_object() ), sge::viewport::optional_resize_callback{ sge::viewport::fill_on_resize() } ) ) ( sge::systems::image2d( sge::media::optional_extension_set( sge::media::extension_set{ sge::media::extension( FCPPT_TEXT("png") ) } ) ) ) ( sge::systems::input( sge::systems::cursor_option_field::null() ) ) ); typedef sge::renderer::vf::pos< float, 3 > pos3_type; typedef sge::renderer::vf::texpos< float, 2, sge::renderer::vf::index< 0u > > texpos_type; typedef sge::renderer::vf::extra< sge::renderer::vf::vector< float, 1u >, sge::renderer::vf::index< 0u > > point_size_type; typedef sge::renderer::vf::part< brigand::list< pos3_type, texpos_type, point_size_type > > format_part; typedef sge::renderer::vf::format< brigand::list< format_part > > format; sge::renderer::vertex::declaration_unique_ptr const vertex_declaration( sys.renderer_device_core().create_vertex_declaration( sge::renderer::vertex::declaration_parameters( sge::renderer::vf::dynamic::make_format< format >() ) ) ); sge::cg::context::object const cg_context; sge::cg::profile::object const vertex_profile( sys.renderer_device_core().create_cg_profile( sge::cg::profile::shader_type::vertex ) ); sge::cg::string const vertex_shader_source( "struct vertex_outputs\n" "{\n" " float2 position : POSITION;\n" " float point_size : PSIZE;\n" " float2 external_texpos : COLOR0;\n" "};\n" "vertex_outputs\n" "vertex_main(\n" " float2 position : POSITION,\n" " float2 texpos : TEXCOORD0,\n" " float point_size : $0$\n" ")\n" "{\n" " vertex_outputs outs;\n" " outs.position = float4(position,0.0,1.0);\n" " outs.point_size = point_size;\n" " outs.external_texpos = texpos;\n" " return outs;\n" "}\n" ); sge::cg::string const pixel_shader_source( "float4\n" "pixel_main(\n" " float2 external_texpos : COLOR0,\n" " float2 texCoord : TEXCOORD0,\n" " uniform sampler2D decal : TEX0\n" ") : COLOR\n" "{\n" " return tex2D(decal,external_texpos.xy + texCoord.xy / 2.0);\n" "}\n" ); sge::cg::program::object vertex_program( sge::cg::program::from_string_parameters( cg_context, sge::cg::program::source_type::text, vertex_profile, sys.renderer_device_core().transform_cg_vertex_program( *vertex_declaration, sge::cg::program::source( vertex_shader_source ) ), sge::cg::program::main_function( "vertex_main" ), sys.renderer_device_core().cg_compile_options( cg_context, vertex_profile ) ) ); sge::renderer::cg::loaded_program_unique_ptr const loaded_vertex_program( sys.renderer_device_core().load_cg_program( vertex_program ) ); sge::cg::profile::object const pixel_profile( sys.renderer_device_core().create_cg_profile( sge::cg::profile::shader_type::pixel ) ); sge::cg::program::object pixel_program( sge::cg::program::from_string_parameters( cg_context, sge::cg::program::source_type::text, pixel_profile, sge::cg::program::source( pixel_shader_source ), sge::cg::program::main_function( "pixel_main" ), sys.renderer_device_core().cg_compile_options( cg_context, pixel_profile ) ) ); sge::renderer::cg::loaded_program_unique_ptr const loaded_pixel_program( sys.renderer_device_core().load_cg_program( pixel_program ) ); sge::renderer::vertex::buffer_unique_ptr const vertex_buffer( sys.renderer_device_core().create_vertex_buffer( sge::renderer::vertex::buffer_parameters( *vertex_declaration, sge::renderer::vf::dynamic::make_part_index< format, format_part >(), sge::renderer::vertex::count( 1u ), sge::renderer::resource_flags_field::null() ) ) ); { sge::renderer::vertex::scoped_lock const vblock( *vertex_buffer, sge::renderer::lock_mode::writeonly ); typedef sge::renderer::vf::view< format_part > vertex_view; vertex_view const vertices( vblock.value() ); vertex_view::iterator vb_it( vertices.begin() ); typedef pos3_type::packed_type pos3; typedef texpos_type::packed_type texpos; typedef point_size_type::packed_type point_size; (*vb_it).set< pos3_type >( pos3( 0.f, 0.f, 0.f ) ); (*vb_it).set< texpos_type >( texpos( 0.5f, 0.5f ) ); (*vb_it).set< point_size_type >( point_size( 200.0f ) ); } sge::renderer::texture::planar_unique_ptr const texture( sge::renderer::texture::create_planar_from_path( sge::config::media_path() / FCPPT_TEXT("images") / FCPPT_TEXT("uvtestgrid.png"), sys.renderer_device_core(), sys.image_system(), sge::renderer::texture::mipmap::off(), sge::renderer::resource_flags_field::null(), sge::renderer::texture::emulate_srgb_from_caps( sys.renderer_device_ffp().caps() ) ) ); sge::renderer::cg::loaded_texture_unique_ptr const loaded_texture( sys.renderer_device_core().load_cg_texture( pixel_program.parameter( "decal" ).object(), *texture ) ); sge::renderer::state::ffp::misc::object_unique_ptr const misc_state( sys.renderer_device_ffp().create_misc_state( sge::renderer::state::ffp::misc::parameters( sge::renderer::state::ffp::misc::enable_point_sprites( true ), sge::renderer::state::ffp::misc::local_viewer( false ), sge::renderer::state::ffp::misc::normalize_normals( false ) ) ) ); auto const draw( [ &loaded_pixel_program, &loaded_texture, &loaded_vertex_program, &misc_state, &sys, &vertex_buffer, &vertex_declaration ]{ sge::renderer::context::scoped_ffp const scoped_block( sys.renderer_device_ffp(), sys.renderer_device_ffp().onscreen_target() ); scoped_block.get().clear( sge::renderer::clear::parameters() .back_buffer( sge::image::color::any::object{ sge::image::color::predef::blue() } ) ); sge::renderer::state::ffp::misc::scoped const scoped_misc( scoped_block.get(), *misc_state ); sge::renderer::vertex::scoped_declaration_and_buffers const vb_context( scoped_block.get(), *vertex_declaration, sge::renderer::vertex::const_buffer_ref_container{ fcppt::make_cref( *vertex_buffer ) } ); sge::renderer::cg::scoped_program const scoped_vertex_program( scoped_block.get(), *loaded_vertex_program ); sge::renderer::cg::scoped_program const scoped_pixel_program( scoped_block.get(), *loaded_pixel_program ); sge::renderer::cg::scoped_texture const scoped_texture( scoped_block.get(), *loaded_texture ); scoped_block.get().render_nonindexed( sge::renderer::vertex::first( 0u ), sge::renderer::vertex::count{ vertex_buffer->linear_size() }, sge::renderer::primitive_type::point_list ); } ); return sge::window::loop( sys.window_system(), sge::window::loop_function{ [ &sys, &draw ]( awl::event::base const &_event ) { sge::systems::quit_on_escape( sys, _event ); fcppt::optional::maybe_void( fcppt::cast::dynamic< sge::renderer::event::render const >( _event ), [ &draw ]( fcppt::reference< sge::renderer::event::render const > ) { draw(); } ); } } ); } catch( fcppt::exception const &_error ) { awl::show_error( _error.string() ); return awl::main::exit_failure(); } catch( std::exception const &_error ) { awl::show_error_narrow( _error.what() ); return awl::main::exit_failure(); }