void Render(double time)
	{
		const GLfloat clear_color[4] = {0.8f, 0.8f, 0.7f, 0.0f};
		gl.ClearColorBuffer(0, clear_color);
		gl.ClearDepthBuffer(1.0f);
		//
		// set the matrix for camera orbiting the origin
		camera_matrix.Set(
			CamMatrixf::Orbiting(
				Vec3f(),
				3.5,
				Degrees(time * 15),
				Degrees(SineWave(time / 6.3) * 45)
			)
		);
		model_matrix.Set(
			ModelMatrixf::Translation(-1.0, 0.0, 0.0) *
			ModelMatrixf::RotationZ(Degrees(time * 180))
		);
		cube_instr.Draw(cube_indices);
		model_matrix.Set(
			ModelMatrixf::Translation(+1.0, 0.0, 0.0) *
			ModelMatrixf::RotationY(Degrees(time * 90))
		);
		cube_instr.Draw(cube_indices);
	}
	void RenderFrameShadowMap(
		const Vec3f& light_position,
		const Mat4f& torus_matrix,
		const Mat4f& light_proj_matrix
	)
	{
		frame_shadow_fbo.Bind(Framebuffer::Target::Draw);

		gl.Viewport(shadow_tex_side, shadow_tex_side);
		gl.ClearDepthBuffer(1.0f);
		gl.CullFace(Face::Back);

		transf_prog.camera_matrix.Set(light_proj_matrix);
		transf_prog.camera_position.Set(light_position);

		// Render the torus' frame
		transf_prog.model_matrix.Set(torus_matrix);

		shadow_pp.Bind();

		gl.Enable(Capability::PolygonOffsetFill);
		torus.Draw(
			[](GLuint phase) -> bool
			{
				return (phase <= 3);
			}
		);
		gl.Disable(Capability::PolygonOffsetFill);
	}