AGG 顶点源(Vertex Source)

顶点源(Vertex Source)

顶点源是一种可以产生多边形所需要的“带命令的顶点”的对象。比如三角形顶点源,就应该会产生一个带“MoveTo”命令的点,另外二 个带"LineTo"命令的点和最终闭合的“ClosePoly”命令。

头文件
#include <agg_path_storage.h> //path_storage
#include <agg_ellipse.h>  // ellipse
#include <agg_arc.h> // arc
#include <agg_arrowhead.h> // arrowhead
#include <agg_curves.h> // curve3, curve4
#include <agg_gsv_text.h> // gsv_text, gsv_text_outline
#include <agg_rounded_rect.h> // rounded_rect
...
类型
自定义类所有实现了void rewind(unsigned path_id);和unsigned vertex(double* x, double* y);的类。
ellipse圆,输入为中心点坐标和XY轴半径,本文所用的例子就 使用了这个顶点源
arc弧线,输入为中心点坐标和XY轴半径,以及起始和终止角(rad),顺时针/逆时针方向
curve3贝塞尔曲线,输入为起点坐标、第一控制点坐标、终点点坐标
curve4贝塞尔曲线,输入为起点坐标、第一控制点坐标、第二控制点坐标、终点坐标
gsv_text使用AGG自带字模的文字输出(只支持ASCII码),使用start_point方法指定文字位置,text方法指定 文字,flip指定是否上下倒转,size指定文字大小,适合与conv_stroke或gsv_text_outline配合。
gsv_text_outline<>可变换文字,输入为gsv_text和变换矩阵(默认为trans_affine,后文会提到)。width方法设置文 字宽度
rounded_rect圆角方形,输入为左上角右下角坐标和圆角半径
path_storage路径存储器,可以用join_path方法加入多个顶点源。而且path_storage本身支持move_to, line_to,curve和arc_to等画线功能
arrowhead箭头,它是作为标记点来用的

其中的arrowhead颇为特殊,它一般作为线段的标记点,具体用法是这样的:

arrowhead ah;
ah.head(d1,d2,d3,d4); //定义箭头
ah.tail(d1,d2,d3,d4); //定义箭尾
VertexSource VS; //其它顶点源
// 使用顶点转换器,并指定Markers类型为vcgen_markers_term
// 顶点转换器可以是conv_dash、conv_stroke或conv_marker_adaptor,见后文《坐标转换管道》
// vcgen_markers_term:以端点作为标记点
conv_stroke<VertexSource, vcgen_markers_term> csVS(VS);
...draw_term
// 用conv_marker指定ah作为线段marker点的标记
conv_marker<vcgen_markers_term, arrowhead> arrow(csVS.markers(), ah);
ras.add_path(csVS);
ras.add_path(arrow); //marker要紧随其后加入
...render

ah.head()和ah.tail()方法中的d1,d2,d3,d4参数的意义见下图


例,画一条简单的箭头直线(基于此处代码)

在on_draw()方法最后加上下列代码:

  1. agg::arrowhead ah;
  2. ah.head(0,10,5,5);
  3. ah.tail(10,10,5,5);
  4. // 用path_storage生成一条直线
  5. agg::path_storage ps;
  6. ps.move_to(160,60);
  7. ps.line_to(100,100);
  8. // 转换
  9. agg::conv_stroke<agg::path_storage, agg::vcgen_markers_term> csps(ps);
  10. agg::conv_marker<agg::vcgen_markers_term, agg::arrowhead>
  11.       arrow(csps.markers(), ah);
  12. // 画线
  13. ras.add_path(csps);
  14. agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(0,0,0));
  15. // 画箭头
  16. ras.add_path(arrow);
  17. agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(255,0,0));
得到的图形是:

注意要加头文件:

#include "agg_conv_marker.h"
#include "agg_arrowhead.h"
#include "agg_path_storage.h"
#include "agg_vcgen_markers_term.h"
试验代码,自定义一个顶点源(基于此处代码)

为了对顶点源有更深入的了解,我们要自己实现一个顶点源,这个顶点源只是很简单的一个三角形。

前面说过,只要实现了 void rewind(unsigned path_id); 和 unsigned vertex(double* x, double* y); 方法就可以作为顶点源。

rewind方 法指示顶点源回到第一个顶点;vertex方 法取出当前顶点然后把当前顶点下移,返回值是当前顶点所带的命令。所谓的命令是一个enum path_commands_e类 型,定义如下:

  1. enum path_commands_e
  2. {
  3.      path_cmd_stop      = 0,        //----path_cmd_stop   
  4.      path_cmd_move_to   = 1,        //----path_cmd_move_to
  5.      path_cmd_line_to   = 2,        //----path_cmd_line_to
  6.      path_cmd_curve3    = 3,        //----path_cmd_curve3
  7.      path_cmd_curve4    = 4,        //----path_cmd_curve4
  8.      path_cmd_curveN    = 5,        //----path_cmd_curveN
  9.      path_cmd_catrom    = 6,        //----path_cmd_catrom
  10.      path_cmd_ubspline = 7,        //----path_cmd_ubspline
  11.      path_cmd_end_poly = 0x0F,     //----path_cmd_end_poly
  12.      path_cmd_mask      = 0x0F      //----path_cmd_mask   
  13. };

path_commands_e还 能和path_flags_e组 合:

  1. enum path_flags_e
  2. {
  3.      path_flags_none   = 0,         //----path_flags_none
  4.      path_flags_ccw    = 0x10,      //----path_flags_ccw
  5.      path_flags_cw     = 0x20,      //----path_flags_cw  
  6.      path_flags_close = 0x40,      //----path_flags_close
  7.      path_flags_mask   = 0xF0       //----path_flags_mask
  8. };

vertex()返回的命令中含有path_cmd_stop时 表示结束。

  1. // 等边三角形
  2. class triangle{
  3. public:
  4.      triangle(double cx, double cy, double r)//中心点,r为中心点到边的长度
  5.      {
  6.         // 直接准备好三个点
  7.          m_step = 0;
  8.          m_pt[0].x = cx; m_pt[0].y = cy-r;
  9.          m_pt[1].x = cx+r*0.866; m_pt[1].y = cy+r*0.5;
  10.          m_pt[2].x = cx-r*0.866; m_pt[2].y = cy+r*0.5;
  11.         //AGG把方向作为区分多边形内部和外部的依据,可以试试m_pt[1]和m_pt[2]对调
  12.      }
  13.     void rewind(unsigned)
  14.      {
  15.          m_step = 0;
  16.      }
  17.      unsigned vertex(double* x, double* y)
  18.      {
  19.         switch(m_step++)
  20.          {
  21.         case 0:
  22.             //第一步,move_to
  23.              *x = m_pt[0].x;
  24.              *y = m_pt[0].y;
  25.             return agg::path_cmd_move_to;
  26.         case 1:
  27.         case 2:
  28.             //第二、三步,line_to
  29.              *x = m_pt[m_step-1].x;
  30.              *y = m_pt[m_step-1].y;
  31.             return agg::path_cmd_line_to;
  32.         case 3:
  33.             // 第四步,闭合多边形
  34.             return agg::path_cmd_end_poly|agg::path_flags_close;
  35.         default:
  36.             // 第五步,结束
  37.             return agg::path_cmd_stop;
  38.          }
  39.      }
  40. private:
  41.      agg::point_d m_pt[3];
  42.      unsigned m_step;
  43. };

在on_draw()方法里把

    agg::ellipse ell(100,100,50 ,50); 改成 triangle ell(100,100,50);
    typedef agg::conv_contour< agg::ellipse> ell_cc_type;改成typedef agg::conv_contour< triangle> ell_cc_type;
得到的图形是:

除了文字输出功能(gsv_text只能输出ASCII文字),上面这些顶点源提供的图形丰富程度已经超过了系统API。文字输出功能 将以单独的篇幅讲述

作者:毛毛 来源:www.cppprog.com

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1 使用AGG的准备工作 1 2 AGG图形显示原理见下图: 1 3 要理解AGG的工作原理,先看一段代码: 2 4 顶点(Vertex Source) 5 4.1 头文件 5 4.2 类型 5 4.3 画一条简单的箭头直线(基于此处代码) 6 4.4 自定义一个顶点(基于此处代码) 7 5 Coordinate conversion pipeline 坐标转换管道 9 5.1 变换矩阵(trans_affine) 10 5.1.1 头文件 10 5.1.2 类型 10 5.1.3成员变量 10 5.1.4 成员方法 10 5.1.5 实验代码(基于此 处代码) 10 5.2 坐标转换管道 11 5.2.1 头文件 11 5.2.2 类型(演示程序基于基于此处代码) 12 6 Scanline Rasterizer 15 6.1 扫描线Scanline 15 6.1.1 头文件 15 6.1.2 类型 15 6.1.3 成员类型 15 6.1.4 成员方法 16 6.2 Rasterizer 16 6.2.1 头文件 16 6.2.2 类型 16 6.2.3 成员方法 16 7 Renderers 渲染器 17 7.1 Scanline Renderer 17 7.1.1 头文件 17 7.1.2 类型 17 7.1.3 实验代码(基于此 处代码) 18 7.2 Basic Renderers 19 7.2.1头文件 19 7.2.2类型 19 7.2.3 构造函数 19 7.2.4 成员方法 19 7.2.5 实验代码(基于此 处代码) 20 7.3 PixelFormat Renderer 20 7.3.1 头文件 21 7.3.2 类型 21 7.3.3 构造函数 21 7.3.4 类型定义 21 7.3.5 成员方法 21 7.3.6 实验代码(基于此 处代码) 22 8 Rendering Buffer 22 8.1 头文件: 22 8.2 类型: 22 8.3 构造函数: 22 8.4 成员方法: 23 8.5 实验代码(基于此处代码) 23 9 AGG与GDI显示 23 10 使用AGG提供的pixel_map类 26 11 线段生成器(Span Generator) 27 12 图案类线段生成器 28 12.1头文件 28 12.2类型 28 12.3 示例代码,使用span_image_filter_rgb_bilinear_clip 29 13 插值器Interpolator 31 13.1 头文件 31 13.2 类型 31 13.3实验代码,使用span_interpolator_persp_lerp 32 14 变换器Transformer 33 14.1 头文件 33 14.2 类型 33 14.3 实验代码,使用trans_warp_magnifier 33 15 图像访问器Image Accessor 34 15.1 头文件 34 15.2 类型 34 15.3 实验代码 35 16 图像过滤器(Image Filter) 36 16.1 头文件 36 16.2 类型 36 16.3 实验代码 37 17 色彩类线段生成器 37 17.1 头文件 37 17.2 类型 38 17.3 示例代码 38 18 渐变颜色 40 18.1 实验代码,使用std::vector<rgba8>实现多颜色渐变 40 18.2 gradient_lut 41 18.2.1 头文件 41 18.2.2 类声明 41 18.2.3 实验代码,使用gradient_lut实现多颜色渐变 41 19 渐变方式 42 20其它色彩类的线段生成器 43 21 组合类线段生成器 44 21.1 头文件 44 21.2 类型 44 21.3 演示代码 45 22 AGG的字符输出 47 22.1 方式一、使用gsv_text对象 47 22.2 方式二、使用字体引擎(Font Engine) 50 22.2.1 头文件 50 22.2.2 类型 50 22.2.3 成员类型 51 22.2.4 成员属性 51 22.2.5 成员方法 51 22.2.6示例代码1 - 从顶点层输出文字 52 22.2.7 示例代码2 - 从Scanline Rasterizer层输出文字 53 22.3 方式三、使用FreeType 54 22.4 方式四、字体缓存管理器(font_cache_manager) 55 22.4.1 头文件 55 22.4.2 类型 55 22.4.3 成员方法 55 22.4.4 示例代码1-作为Rasterizer渲染: 56 22.4.5 示例代码2-作为顶点渲染: 57 23 小结 58

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值