现在的位置: 首页 > 综合 > 正文

AGG 色彩类线段生成器

2013年08月06日 ⁄ 综合 ⁄ 共 5123字 ⁄ 字号 评论关闭
文章目录

色彩类线段生成器

头文件

  1. #include <agg_span_solid.h>
  2. #include <agg_span_gradient.h>
  3. #include <agg_span_gradient_alpha.h>
  4. #include <agg_span_gouraud_gray.h>
  5. #include <agg_span_gouraud_rgba.h>

类型

  1. template<class ColorT>
  2.     class agg::span_solid;
  3. template<class ColorT, class Interpolator, class GradientF, class ColorF>
  4.     class agg::span_gradient;
  5. template<class ColorT, class Interpolator, class GradientF, class AlphaF>
  6.     class agg::span_gradient_alpha;
  7. template<class ColorT>
  8.     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);

 

显示效果

  1. span_gradient是一个模板类(费话,AGG的大部分类都是),前两个模板参数ColorTInterpolator一个是颜色类型一个是插值器没什么好说的了。关键是后面两个:GradientF用于指定渐变的方式,如水平渐变、垂直渐变、圆形渐变等;ColorF指定渐变的颜色。
  2. 渐变方式选择了agg::gradient_radial_focus,这是一个可指定焦点的圆形渐变方式。
  3. 渐变色使用agg::gradient_linear_color设置起始颜色和终止颜色。
  4. span_gradient的构造函数前三个分别是插值器、渐变方式、渐变颜色,后面两个数字表示渐变的起始和终止位置。不同的渐变方式起始和终止位置的意义是不同的,如在圆形填充里起始和终止表示中心和边缘;水平渐变则表示从左到右。
  5. 插值器的矩阵变换把这个渐变中心移到(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);

显示效果

www.cppprog.com

http://hi.baidu.com/%E5%D4%E5%C6%B6%C0%D0%D0/blog/item/8b82c4f867a070d3b58f31f1.html

抱歉!评论已关闭.