void RenderText(GLfloat x, GLfloat y, const oglplus::String& text)
	{
		using namespace oglplus;

		glyph_spacings.resize(text.size()+1);
		text_glyphs.GetSpacing(
			PathNVListMode::AccumAdjacentPairs,
			text,
			1.0f, 1.0f,
			PathNVTransformType::TranslateX,
			glyph_spacings
		);
		glyph_spacings.insert(glyph_spacings.begin(), 0);

		dsa.ModelviewMatrix()
			.LoadIdentity()
			.Translate(x, y, 0);

		text_glyphs.StencilFillInstanced(
			text,
			PathNVFillMode::CountUp,
			0xFF,
			PathNVTransformType::TranslateX,
			glyph_spacings
		);
		text_glyphs.CoverFillInstanced(
			text,
			PathNVFillCoverMode::BoundingBoxOfBoundingBoxes,
			PathNVTransformType::TranslateX,
			glyph_spacings
		);
	}
    void Render() {
        using namespace oglplus;

        gl.Clear().ColorBuffer().StencilBuffer();

        glc.Color(0.2, 0.2, 1.0);

        text_path.StencilFillInstanced(
          glyph_indices,
          PathNVFillMode::CountUp,
          0xFF,
          PathNVTransformType::TranslateX,
          glyph_spacings);
        text_path.CoverFillInstanced(
          glyph_indices,
          PathNVFillCoverMode::BoundingBoxOfBoundingBoxes,
          PathNVTransformType::TranslateX,
          glyph_spacings);

        glc.Color(0.0, 0.0, 0.0);

        text_path.StencilStrokeInstanced(
          glyph_indices,
          1,
          ~0,
          PathNVTransformType::TranslateX,
          glyph_spacings);
        text_path.CoverStrokeInstanced(
          glyph_indices,
          PathNVStrokeCoverMode::ConvexHull,
          PathNVTransformType::TranslateX,
          glyph_spacings);
    }
	TextExample(int /*argc*/, const char** /*argv*/)
	 : text_glyphs(128)
	{
		using namespace oglplus;

		GLfloat font_scale = 48;

		text_glyphs.GlyphRange(
			PathNVFontTarget::Standard,
			"Sans",
			PathNVFontStyle::Bold,
			0, 128,
			PathNVMissingGlyph::Use,
			~0,
			font_scale
		);

		GLfloat color_gen_coeffs[9] = {
			-0.6f, 0.0f, 0.8f,
			 0.0f, 0.0f, 0.0f,
			 0.5f, 0.0f, 0.5f
		};
		npr.ColorGen(
			PathNVColor::Primary,
			PathNVGenMode::ObjectBoundingBox,
			PathNVColorFormat::RGB,
			color_gen_coeffs
		);

		gl.ClearColor(1.0f, 1.0f, 1.0f, 0.0f);
		gl.ClearStencil(0);
		gl.StencilMask(~0);
		gl.StencilFunc(CompareFunction::NotEqual, 0, 0xFF);
		gl.StencilOp(
			StencilOperation::Keep,
			StencilOperation::Keep,
			StencilOperation::Zero
		);

		gl.Enable(Capability::StencilTest);
	}
	void Reshape(void)
	{
		using namespace oglplus;

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

		dsa.ProjectionMatrix()
			.LoadIdentity()
			.Ortho(0, Width(), 0, Height(), -1, 1);

		GLfloat font_min_max[2];
		text_glyphs.GetMetricRange(
			PathNVMetricQuery::FontYMinBounds|
			PathNVMetricQuery::FontYMaxBounds,
			1, 0,
			font_min_max
		);
		font_y_min = font_min_max[0];
		font_y_max = font_min_max[1];
		font_height = font_y_max - font_y_min;
	}
    TextExample(int /*argc*/, const char** /*argv*/)
      : text("OpenGL")
      , text_path(text.size())
      , glyph_indices(make_glyph_indices())
      , glyph_spacings(glyph_indices.size()) {
        using namespace oglplus;

        GLfloat font_scale = 64;

        text_path.Glyphs(
          PathNVFontTarget::Standard,
          "Sans",
          PathNVFontStyle::Bold,
          text,
          PathNVMissingGlyph::Use,
          ~0,
          font_scale);

        text_path.GetSpacing(
          PathNVListMode::AccumAdjacentPairs,
          glyph_indices,
          1.0f,
          1.0f,
          PathNVTransformType::TranslateX,
          glyph_spacings);

        glyph_spacings.insert(glyph_spacings.begin(), 0);
        glyph_spacings.pop_back();
        glyph_indices.pop_back();

        GLfloat text_left = glyph_spacings.front();
        GLfloat text_right = glyph_spacings.back();

        GLfloat font_min_max[2];

        text_path.GetMetricRange(
          PathNVMetricQuery::FontYMinBounds | PathNVMetricQuery::FontYMaxBounds,
          1,
          0,
          font_min_max);

        projection.Ortho(
          text_left - 10,
          text_right + 10,
          font_min_max[0],
          font_min_max[1],
          -1.0,
          +1.0);
        modelview.LoadIdentity();

        gl.ClearColor(1.0f, 1.0f, 1.0f, 0.0f);
        gl.ClearStencil(0);
        gl.StencilMask(~0);
        gl.StencilFunc(CompareFunction::NotEqual, 0, 0xFF);
        gl.StencilOp(
          StencilOperation::Keep,
          StencilOperation::Keep,
          StencilOperation::Zero);

        gl.Enable(Capability::StencilTest);
    }