色彩类线段生成器
头文件
- #include <agg_span_solid.h>
- #include <agg_span_gradient.h>
- #include <agg_span_gradient_alpha.h>
- #include <agg_span_gouraud_gray.h>
- #include <agg_span_gouraud_rgba.h>
类型
- template<class ColorT>
- class agg::span_solid;
- template<class ColorT, class Interpolator, class GradientF, class ColorF>
- class agg::span_gradient;
- template<class ColorT, class Interpolator, class GradientF, class AlphaF>
- class agg::span_gradient_alpha;
- template<class ColorT>
- class agg::span_gouraud_[gray|rgba];
如果你是从上面的图案类线段生成器看到这里的话,那么色彩类的就相对简单得多了。同样,我们先写一个示例代码,也方便以后做实验。
示例代码
同样基于这个代码(http://www.cppprog.com/2009/0816/146.html),
//Rendering Buffer agg::rendering_buffer &rbuf = rbuf_window(); agg::pixfmt_bgr24 pixf(rbuf);
// Renderers typedef agg::renderer_base<agg::pixfmt_bgr24> renderer_base_type; renderer_base_type renb(pixf);
typedef agg::renderer_scanline_aa_solid<renderer_base_type> renderer_scanline_type; renderer_scanline_type rensl(renb); // Vertex Source agg::ellipse ell(100,100,50,50);
// Scanline Rasterizer agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl;
加入下面的头文件
#include "agg_span_allocator.h"
#include "agg_span_gradient.h"
在on_draw()方法的最后加上下面这些代码
// 色彩类线段生成器demo // 线段分配器 typedef agg::span_allocator<agg::rgba8> 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<agg::rgba8> colorF_type; colorF_type colorF(agg::rgba(1,1,1), agg::rgba(0,0,1));//白色到蓝色 // 线段生成器 typedef agg::span_gradient<agg::rgba8, 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<rgba8>也行哈。
实验代码,使用std::vector<rgba8>实现多颜色渐变
把示例代码的渐变颜色部分改成这样:
... // 渐变颜色 //typedef agg::gradient_linear_color<agg::rgba8> colorF_type; //colorF_type colorF(agg::rgba(1,1,1), agg::rgba(0,0,1));//白色到蓝色 typedef std::vector<agg::rgba8> 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类,用它可以方便很多。
gradient_lut的头文件是#include <agg_gradient_lut.h>
类声明为
template<class ColorInterpolator, unsigned ColorLutSize = 256>
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<agg::rgba8> colorF_type; //colorF_type colorF(agg::rgba(1,1,1), agg::rgba(0,0,1));//白色到蓝色 typedef agg::gradient_lut< agg::color_interpolator<agg::rgba8> > 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 <agg_span_gradient.h>头文件之中。
修改演示代码的渐变方式是很简单的,如:
... // 渐变方式 //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自带渐变方式以及显示效果
gradient_x |
gradient_y |
gradient_diamond |
|
|
|
gradient_xy |
gradient_conic |
gradient_radial |
|
|
|
本节的最后,再介绍一下其它几个色彩类的线段生成器
- span_solid没什么好说的,实色填充而已
- span_gradient_alpha是透明度渐变,参数和span_gradient差不多,区别是ColorF改成了AlphaF,“operator []()”返回值也由颜色结构变为的透明度数值。
- span_gouraud_rgba 高氏三角着色,需指定三角形的三个顶点和三种颜色,用法见下例
// 色彩类线段生成器demo // 线段分配器 typedef agg::span_allocator<agg::rgba8> span_allocator_type;//分配器类型 span_allocator_type span_alloc; // span_allocator
typedef agg::span_gouraud_rgba<agg::rgba8> 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);
显示效果
|