void Render(void)
	{
		using namespace oglplus;

		gl.Clear().ColorBuffer().DoIt();

		GLfloat t = GLfloat(FrameTime());

		rndr.Use();

		rndr_time.Set(t);

		text_stream.str(std::string());
		text_stream
			<< "Time: "
			<< std::fixed
			<< std::setw(5)
			<< std::setprecision(3)
			<< t << " [s]";
		if(time_str != text_stream.str())
		{
			time_str = text_stream.str();
			time_layout.Set(time_str);
		}

		rndr_camera_matrix.Set(
			CamMatrixf::Orbiting(
				Vec3f(),
				GLfloat(9.0 + SineWave(t / 7.0)*3.0),
				-FullCircles(t / 17.0),
				Degrees(SineWave(t / 21.0) * 35)
			)
		);

		rndr_layout_matrix.Set(ModelMatrixf::Translation(-3.0f, 0.7f, 0.1f));
		rndr.Render(oglp_layout);

		rndr_layout_matrix.Set(ModelMatrixf::Translation(-8.0f,-0.7f, 0.0f));
		rndr.Render(desc_layout);

		rndr_layout_matrix.Set(
			ModelMatrixf::Translation(-4.0f,-2.0f, 0.0f)*
			ModelMatrixf::Scale(0.7f, 0.7f, 0.5f)
		);
		rndr.Render(time_layout);
	}
	void Reshape(void)
	{
		using namespace oglplus;

		gl.Viewport(Width(), Height());

		rndr_projection_matrix.Set(
			CamMatrixf::PerspectiveX(
				Degrees(60),
				Width()/Height(),
				1, 60
			)
		);
	}
	void LoadNext(void)
	{
		typedef oglplus::text::Direction Dir;
		struct {
			Dir direction;
			const char* text;
		} lines[] = {
			{Dir::LeftToRight, u8"Hello world"},
			{Dir::LeftToRight, u8"Nazdar svet"},
			{Dir::LeftToRight, u8"Γεια σας κόσμο"},
			{Dir::LeftToRight, u8"Привет мир"},
			{Dir::LeftToRight, u8"Witaj świecie"},
			{Dir::LeftToRight, u8"Здравей свят"},
			{Dir::LeftToRight, u8"Ahoj světe"},
			{Dir::LeftToRight, u8"Moi maailma"},
			{Dir::LeftToRight, u8"Bonjour tout le monde"},
			{Dir::LeftToRight, u8"Hallo welt"},
			{Dir::LeftToRight, u8"Բարեւ աշխարհ"},
			{Dir::LeftToRight, u8"Hej världen"},
			{Dir::LeftToRight, u8"Прывітанне свет"},
			{Dir::LeftToRight, u8"Olá mundo"},
			{Dir::LeftToRight, u8"Здраво свете"},
			{Dir::LeftToRight, u8"Zdravo svet"},
			{Dir::LeftToRight, u8"Hola mundo"},
			{Dir::LeftToRight, u8"Merhaba dünya"},
			{Dir::LeftToRight, u8"Привіт світ"},
			{Dir::LeftToRight, u8"Pozdrav svijetu"},
			{Dir::LeftToRight, u8"Hello világ"},
			{Dir::RightToLeft, u8"مرحبا العالم"},
			{Dir::LeftToRight, u8"Ciao mondo"},
			{Dir::LeftToRight, u8"Здраво светот"},
			{Dir::RightToLeft, u8"שלום עולם"},
			{Dir::LeftToRight, u8"Hei verden"}
		};
		const std::size_t line_count = sizeof(lines)/sizeof(lines[0]);

		layout.Set(lines[current_line].text);

		rndr.SetDirection(lines[current_line].direction);
		rndr_color.Set(
			0.1f+GLfloat(0.8f*std::rand())/RAND_MAX,
			0.3f+GLfloat(0.7f*std::rand())/RAND_MAX,
			0.1f+GLfloat(0.8f*std::rand())/RAND_MAX
		);

		if(++current_line >= line_count)
			current_line = 0;
	}
	void Render(void)
	{
		using namespace oglplus;

		GLfloat t = GLfloat(FrameTime());
		GLfloat i = t*0.3f;
		int interval = int(i);
		GLfloat f = i - GLfloat(interval);
		if(prev_interval < interval)
		{
			LoadNext();
			prev_interval = interval;
		}

		gl.Clear().ColorBuffer().DoIt();

		rndr_opacity.Set(SineWave(f*0.5f));

		rndr.SetLayoutTransform(ModelMatrixf::TranslationZ(-20.0f+16.0f*f));
		rndr.Render(layout);
	}