齐泰踏步板:AGG 色彩类线段生成器
色彩类线段生成器
头文件
类型
- template
- class agg::span_solid;
- template
- class agg::span_gradient;
- template
- class agg::span_gradient_alpha;
- template
- class agg::span_gouraud_[gray|rgba];
如果你是从上面的图案类线段生成器看到这里的话,那么色彩类的就相对简单得多了。同样,我们先写一个示例代码,也方便以后做实验。
示例代码
同样基于这个代码(http://www.cppprog.com/2009/0816/146.html),加入下面的头文件
- #include "agg_span_allocator.h"
- #include "agg_span_gradient.h"
在on_draw()方法的最后加上下面这些代码
- // 色彩类线段生成器demo
- // 线段分配器
- typedef agg::span_allocator span_allocator_type;//分配器类型
- span_allocator_type span_alloc; // span_allocator
- // 插值器
- typedef agg::span_interpolator_linear<> interpolator_type; //插值器类型
- agg::trans_affine img_mtx; // 变换矩阵
- interpolator_type ip(img_mtx); // 插值器
- // 渐变方式
- typedef agg::gradient_radial_focus gradientF_type;
- gradientF_type grF(1, 0.1, 0.5);
- // 渐变颜色
- typedef agg::gradient_linear_color colorF_type;
- colorF_type colorF(agg::rgba(1,1,1), agg::rgba(0,0,1));//白色到蓝色
- // 线段生成器
- typedef agg::span_gradient interpolator_type,
- gradientF_type,
- colorF_type> span_gen_type;
- span_gen_type span_gen(ip,grF,colorF,0,50);
- // 组合成渲染器
- agg::renderer_scanline_aa<
- renderer_base_type,
- span_allocator_type,
- span_gen_type
- > my_renderer(renb, span_alloc, span_gen);
- // 矩阵变换
- img_mtx.translate(100,100);
- img_mtx.invert(); //注意这里
- // 使用我们的渲染器画圆
- ras.add_path(ell);
- agg::render_scanlines(ras,sl,my_renderer);
显示效果
- span_gradient是一个模板类(费话,AGG的大部分类都是),前两个模板参数ColorT和Interpolator一个是颜色类型一个是插值器没什么好说的了。关键是后面两个:GradientF用于指定渐变的方式,如水平渐变、垂直渐变、圆形渐变等;ColorF指定渐变的颜色。
- 渐变方式选择了agg::gradient_radial_focus,这是一个可指定焦点的圆形渐变方式。
- 渐变色使用agg::gradient_linear_color设置起始颜色和终止颜色。
- span_gradient的构造函数前三个分别是插值器、渐变方式、渐变颜色,后面两个数字表示渐变的起始和终止位置。不同的渐变方式起始和终止位置的意义是不同的,如在圆形填充里起始和终止表示中心和边缘;水平渐变则表示从左到右。
- 插值器的矩阵变换把这个渐变中心移到(100,100)点上,同样要记得调用invert()方法反转。
渐变颜色
前面说到span_gradient的模板参数ColorF指定渐变的颜色,我们使用的是gradient_linear_color,那么有哪些类可以作为ColorF呢?
AGG文档里说只要实现了“operator []()”和“size()”的类就可以作为ColorF,嗯,std::vector
实验代码,使用std::vector实现多颜色渐变
把示例代码的渐变颜色部分改成这样:
- ...
- // 渐变颜色
- //typedef agg::gradient_linear_color colorF_type;
- //colorF_type colorF(agg::rgba(1,1,1), agg::rgba(0,0,1));//白色到蓝色
- typedef std::vector colorF_type;
- colorF_type colorF(256);
- agg::rgba begin_color(1,1,1), mid_color(1,0,0), end_color(0,0,1);
- for(int i=0; i<128; i++) //前128从白到红
- colorF[i] = begin_color.gradient(mid_color,i/128.0);
- for(int i=0; i<128; i++) //后128从红到蓝
- colorF[i+128] = mid_color.gradient(end_color,i/128.0);
显示效果
这里指定的vector容量256指的是用于的颜色,想要更平滑过渡的话可以使用更多的颜色数。
除了用vector实现多种颜色的渐变外,我们还可以用AGG提供的一个gradient_lut类,用它可以方便很多。
类声明为
- template
- class agg::gradient_lut
其中的ColorInterpolator负责生成两种颜色的中间色,直接使用AGG自带的agg::color_interpolator就行。
通过gradient_lut的add_color(double offset, color_type color)方法添加多种颜色,其中的offset表示添加的颜色所处的偏移位置,取值为0~1之间。
添加完所有颜色后调用build_lut()方法让gradient_lut内部生成颜色数组。
实验代码,使用gradient_lut实现多颜色渐变
把示例代码的渐变颜色部分改成这样:
- ...
- // 渐变颜色
- //typedef agg::gradient_linear_color colorF_type;
- //colorF_type colorF(agg::rgba(1,1,1), agg::rgba(0,0,1));//白色到蓝色
- typedef agg::gradient_lut<
- agg::color_interpolator
- > colorF_type;
- colorF_type colorF;
- colorF.add_color(0, agg::rgba(1,1,1));
- colorF.add_color(0.2, agg::rgba(1,0,0));
- colorF.add_color(0.4, agg::rgba(0,1,0));
- colorF.add_color(0.8, agg::rgba(0,0,1));
- colorF.build_lut();
- ...
显示效果
渐变方式
除本例中的gradient_radial_focus以外,AGG还提供了很多渐变方式,它们都定义在#include 头文件之中。
修改演示代码的渐变方式是很简单的,如:
- ...
- // 渐变方式
- //typedef agg::gradient_radial_focus gradientF_type;
- //gradientF_type grF(1, 0.1, 0.5);
- typedef agg::gradient_x gradientF_type;
- gradientF_type grF;
- ...
这里是其中的一部分AGG自带渐变方式以及显示效果
本节的最后,再介绍一下其它几个色彩类的线段生成器
- span_solid没什么好说的,实色填充而已
- span_gradient_alpha是透明度渐变,参数和span_gradient差不多,区别是ColorF改成了AlphaF,“operator []()”返回值也由颜色结构变为的透明度数值。
- span_gouraud_rgba 高氏三角着色,需指定三角形的三个顶点和三种颜色,用法见下例
- // 色彩类线段生成器demo
- // 线段分配器
- typedef agg::span_allocator span_allocator_type;//分配器类型
- span_allocator_type span_alloc; // span_allocator
- typedef agg::span_gouraud_rgba span_gen_type;
- span_gen_type span_gen;
- //三种颜色
- span_gen.colors(
- agg::rgba(1,0,0),
- agg::rgba(0,1,0),
- agg::rgba(0,0,1)
- );
- //三角形三个顶点
- span_gen.triangle(
- 100,50,
- 130,125,
- 70,125,0
- );
- agg::renderer_scanline_aa<
- renderer_base_type,
- span_allocator_type,
- span_gen_type
- > my_renderer(renb, span_alloc, span_gen);
- ras.add_path(ell);
- agg::render_scanlines(ras,sl,my_renderer);