コード例 #1
0
ファイル: simple.cpp プロジェクト: freundlich/spacegameengine
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();
}
コード例 #2
0
ファイル: slang_link.c プロジェクト: CPFDSoftware-Tony/gmv
/**
 * Shader linker.  Currently:
 *
 * 1. The last attached vertex shader and fragment shader are linked.
 * 2. Varying vars in the two shaders are combined so their locations
 *    agree between the vertex and fragment stages.  They're treated as
 *    vertex program output attribs and as fragment program input attribs.
 * 3. The vertex and fragment programs are cloned and modified to update
 *    src/dst register references so they use the new, linked varying
 *    storage locations.
 */
void
_slang_link(GLcontext *ctx,
            GLhandleARB programObj,
            struct gl_shader_program *shProg)
{
   const struct gl_vertex_program *vertProg = NULL;
   const struct gl_fragment_program *fragProg = NULL;
   GLboolean vertNotify = GL_TRUE, fragNotify = GL_TRUE;
   GLuint numSamplers = 0;
   GLuint i;

   _mesa_clear_shader_program_data(ctx, shProg);

   /* Initialize LinkStatus to "success".  Will be cleared if error. */
   shProg->LinkStatus = GL_TRUE;

   /* check that all programs compiled successfully */
   for (i = 0; i < shProg->NumShaders; i++) {
      if (!shProg->Shaders[i]->CompileStatus) {
         link_error(shProg, "linking with uncompiled shader\n");
         return;
      }
   }

   shProg->Uniforms = _mesa_new_uniform_list();
   shProg->Varying = _mesa_new_parameter_list();

   /*
    * Find the vertex and fragment shaders which define main()
    */
   {
      struct gl_shader *vertShader, *fragShader;
      vertShader = get_main_shader(ctx, shProg, GL_VERTEX_SHADER);
      fragShader = get_main_shader(ctx, shProg, GL_FRAGMENT_SHADER);
      if (vertShader)
         vertProg = vertex_program(vertShader->Program);
      if (fragShader)
         fragProg = fragment_program(fragShader->Program);
      if (!shProg->LinkStatus)
         return;
   }

#if FEATURE_es2_glsl
   /* must have both a vertex and fragment program for ES2 */
   if (!vertProg) {
      link_error(shProg, "missing vertex shader\n");
      return;
   }
   if (!fragProg) {
      link_error(shProg, "missing fragment shader\n");
      return;
   }
#endif

   /*
    * Make copies of the vertex/fragment programs now since we'll be
    * changing src/dst registers after merging the uniforms and varying vars.
    */
   _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
   if (vertProg) {
      struct gl_vertex_program *linked_vprog =
         _mesa_clone_vertex_program(ctx, vertProg);
      shProg->VertexProgram = linked_vprog; /* refcount OK */
      /* vertex program ID not significant; just set Id for debugging purposes */
      shProg->VertexProgram->Base.Id = shProg->Name;
      ASSERT(shProg->VertexProgram->Base.RefCount == 1);
   }

   _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
   if (fragProg) {
      struct gl_fragment_program *linked_fprog = 
         _mesa_clone_fragment_program(ctx, fragProg);
      shProg->FragmentProgram = linked_fprog; /* refcount OK */
      /* vertex program ID not significant; just set Id for debugging purposes */
      shProg->FragmentProgram->Base.Id = shProg->Name;
      ASSERT(shProg->FragmentProgram->Base.RefCount == 1);
   }

   /* link varying vars */
   if (shProg->VertexProgram) {
      if (!link_varying_vars(ctx, shProg, &shProg->VertexProgram->Base))
         return;
   }
   if (shProg->FragmentProgram) {
      if (!link_varying_vars(ctx, shProg, &shProg->FragmentProgram->Base))
         return;
   }

   /* link uniform vars */
   if (shProg->VertexProgram) {
      if (!link_uniform_vars(ctx, shProg, &shProg->VertexProgram->Base,
                             &numSamplers)) {
         return;
      }
   }
   if (shProg->FragmentProgram) {
      if (!link_uniform_vars(ctx, shProg, &shProg->FragmentProgram->Base,
                             &numSamplers)) {
         return;
      }
   }

   /*_mesa_print_uniforms(shProg->Uniforms);*/

   if (shProg->VertexProgram) {
      if (!_slang_resolve_attributes(shProg, &vertProg->Base,
                                     &shProg->VertexProgram->Base)) {
         return;
      }
   }

   if (shProg->VertexProgram) {
      _slang_update_inputs_outputs(&shProg->VertexProgram->Base);
      _slang_count_temporaries(&shProg->VertexProgram->Base);
      if (!(shProg->VertexProgram->Base.OutputsWritten
	    & BITFIELD64_BIT(VERT_RESULT_HPOS))) {
         /* the vertex program did not compute a vertex position */
         link_error(shProg,
                    "gl_Position was not written by vertex shader\n");
         return;
      }
   }
   if (shProg->FragmentProgram) {
      _slang_count_temporaries(&shProg->FragmentProgram->Base);
      _slang_update_inputs_outputs(&shProg->FragmentProgram->Base);
   }

   /* Check that all the varying vars needed by the fragment shader are
    * actually produced by the vertex shader.
    */
   if (shProg->FragmentProgram) {
      const GLbitfield varyingRead
         = shProg->FragmentProgram->Base.InputsRead >> FRAG_ATTRIB_VAR0;
      const GLbitfield64 varyingWritten = shProg->VertexProgram ?
         shProg->VertexProgram->Base.OutputsWritten >> VERT_RESULT_VAR0 : 0x0;
      if ((varyingRead & varyingWritten) != varyingRead) {
         link_error(shProg,
          "Fragment program using varying vars not written by vertex shader\n");
         return;
      }         
   }

   /* check that gl_FragColor and gl_FragData are not both written to */
   if (shProg->FragmentProgram) {
      const GLbitfield64 outputsWritten =
	 shProg->FragmentProgram->Base.OutputsWritten;
      if ((outputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) &&
          (outputsWritten >= BITFIELD64_BIT(FRAG_RESULT_DATA0))) {
         link_error(shProg, "Fragment program cannot write both gl_FragColor"
                    " and gl_FragData[].\n");
         return;
      }         
   }


   if (fragProg && shProg->FragmentProgram) {
      /* Compute initial program's TexturesUsed info */
      _mesa_update_shader_textures_used(&shProg->FragmentProgram->Base);

      /* notify driver that a new fragment program has been compiled/linked */
      vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
                                                 &shProg->FragmentProgram->Base);
      if (ctx->Shader.Flags & GLSL_DUMP) {
         printf("Mesa pre-link fragment program:\n");
         _mesa_print_program(&fragProg->Base);
         _mesa_print_program_parameters(ctx, &fragProg->Base);

         printf("Mesa post-link fragment program:\n");
         _mesa_print_program(&shProg->FragmentProgram->Base);
         _mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base);
      }
   }

   if (vertProg && shProg->VertexProgram) {
      /* Compute initial program's TexturesUsed info */
      _mesa_update_shader_textures_used(&shProg->VertexProgram->Base);

      /* notify driver that a new vertex program has been compiled/linked */
      fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
                                                   &shProg->VertexProgram->Base);
      if (ctx->Shader.Flags & GLSL_DUMP) {
         printf("Mesa pre-link vertex program:\n");
         _mesa_print_program(&vertProg->Base);
         _mesa_print_program_parameters(ctx, &vertProg->Base);

         printf("Mesa post-link vertex program:\n");
         _mesa_print_program(&shProg->VertexProgram->Base);
         _mesa_print_program_parameters(ctx, &shProg->VertexProgram->Base);
      }
   }

   /* Debug: */
   if (0) {
      if (shProg->VertexProgram)
         _mesa_postprocess_program(ctx, &shProg->VertexProgram->Base);
      if (shProg->FragmentProgram)
         _mesa_postprocess_program(ctx, &shProg->FragmentProgram->Base);
   }

   if (ctx->Shader.Flags & GLSL_DUMP) {
      printf("Varying vars:\n");
      _mesa_print_parameter_list(shProg->Varying);
      if (shProg->InfoLog) {
         printf("Info Log: %s\n", shProg->InfoLog);
      }
   }

   if (!vertNotify || !fragNotify) {
      /* driver rejected one/both of the vertex/fragment programs */
      if (!shProg->InfoLog) {
	 link_error(shProg,
		    "Vertex and/or fragment program rejected by driver\n");
      }
   }
   else {
      shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);
   }
}
コード例 #3
0
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();
}