AGG 渲染器(Renderers)

本文详细介绍了AGG图形库中的渲染器组件,包括渲染器的基本概念、不同类型的渲染器及其实现原理。还探讨了ScanlineRenderer的工作流程,并通过实验代码展示了如何使用不同类型的渲染器来实现图形绘制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Renderers 渲染器

渲染器负责表现扫描线Scanline中的每个线段(span)。在渲染器之前,AGG图形中的线段是没有颜色值的,只是位置、长度和 覆盖率(透明度)。渲染器赋于线段色彩,最终成为一幅完整的图像。

渲 染器被分成底中高三层。其中底层负责像素包装,由PixelFormat Renderer实现;中层是基础层,在PixelFormat Renderer的基础上提供更多方法,是所有高层渲染器依赖的基础,由Base Renderer实现;高层负责渲染Scanline中的线段,由Scanline Renderer等实现。

Scanline Renderer

头文件
#include <agg_renderer_scanline.h>
类型
template<class BaseRenderer> class renderer_scanline_aa_solid; //实色AA渲染
template<class BaseRenderer> class renderer_scanline_bin_solid; //实色原始渲染
template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
 class renderer_scanline_aa; // 自定义AA渲染
template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
 class renderer_scanline_bin; // 自定义原始渲染

以及自己写的实现了void prepare() 和 template<class Scanline> void render(const Scanline& sl) 方法的类

另外,头文件agg_renderer_scanline.h中 的render_scanlines函 数很重要,它是AGG显示流程的实现。

void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren);

从Rasterizer生成逐行的Scanline,然后交给Scanline Renderer渲染。

这 里还要提一下render_scanlines_aa_solidrender_scanlines_aarender_scanlines_bin_solidrender_scanlines_bin这 几个函数。它们的作用和 render_scanlines一 样,只是跳过了Scanline Renderer环节,直接向Base Renderer渲染。

void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl,
 BaseRenderer& ren, const ColorT& color)
template<class Rasterizer, class Scanline, class BaseRenderer,
 class SpanAllocator, class SpanGenerator>
void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
 SpanAllocator& alloc, SpanGenerator& span_gen);
实验代码(基于此 处代码)

把on_draw()方法里原

typedef agg::renderer_scanline_aa_solid<renderer_base_type> renderer_scanline_type;

改成

typedef agg::renderer_scanline_bin_solid<renderer_base_type> renderer_scanline_type;
得到的图形是:

去掉renderer_scanline_type以及所有的rensl相关语句,把

agg::render_scanlines(ras,sl,rensl);

改成

agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(0,0,i*50));

同样可以得到我们想要的图形

Basic Renderers

头文件
#include <agg_renderer_base.h>
#include <agg_renderer_mclip.h>
类型
template<class PixelFormat> class renderer_base;
template<class PixelFormat> class renderer_mclip;
构造函数
renderer_base(pixfmt_type& ren);
参数ren指定底层的PixelFormat Renderer
成员方法
pixfmt_type& ren();返回底层的PixelFormat Renderer
unsigned width() const;
unsigned height() const;
宽高
void reset_clipping(bool visibility);设置是否可见
clipping box=visibility?(0,0,width-1,height-1):(1,1,0,0)
bool clip_box(int x1, int y1, int x2, int y2);设置clipping box,renderer_base专有
void add_clip_box(int x1, int y1, int x2, int y2);添加clipping box,renderer_mclip专有
bool inbox(int x, int y) const;x,y点是否在clipping box内,renderer_base专有
void first_clip_box();
bool next_clip_box();
切换clipping box,renderer_mclip专用
const rect& clip_box() const;
int         xmin()     const;
int         ymin()     const;
int         xmax()     const;
int         ymax()     const;
const rect& bounding_clip_box() const;
int         bounding_xmin()     const;
int         bounding_ymin()     const;
int         bounding_xmax()     const;
int         bounding_ymax()     const;  
返回clipping box大小
void clear(const color_type& c);以颜色c填充所有区域
void copy_pixel(int x, int y, const color_type& c);
void blend_pixel(int x, int y, const color_type& c, cover_type cover);
color_type pixel(int x, int y) const;
void copy_h(v)line(int x1, int y, int x2, const color_type& c);
void blend_h(v)line(int x1, int y, int x2,
                 const color_type& c, cover_type cover);
void blend_solid_h(v)span(int x, int y, int len,
                       const color_type& c, const cover_type* covers);
void blend_color_h(v)span(_no_slip)(int x, int y, int len,
                       const color_type* colors, const cover_type* covers);
见后文的PixelFormat Renderer
void copy_from(const rendering_buffer& from,
           const rect* rc=0,
           int x_to=0,
           int y_to=0);
从from复制一个矩形区域过来,rc指定源区域,x_to,y_to指定目标位置
实验代码(基于此 处代码)

在on_draw()方法的renb.clear(agg::rgba8(255,255,255));语句后面加上:

  1. renb.clear(agg::rgba8(255,255,255));
  2. renb.clip_box(30,30,160,160); // 设置可写区域
得到的图形是:

PixelFormat Renderer

PixelFormat Renderer的作用是以指定的颜色空间来包装原始的Rendering Buffer(见后文),AGG把它归类于底层Renderer。
Rendering Buffer是以字节为单位的,而PixelFormat Renderer则是以像素为单位的。

头文件
#include "agg_pixfmt_rgb.h
#include "agg_pixfmt_gray.h"
类型
pixfmt_gray8
pixfmt_rgb24
pixfmt_bgr24
pixfmt_rgba32
pixfmt_bgr24_gamma
...
构造函数
pixfmt_base(rbuf_type& rb);

rb参数为Rendering Buffer类型

类型定义
typedef color_type;像素类型
需要了解的是在AGG中像素也是一个功能完善的类,常用的有rgba、rgba8、gray8。
rgba里每个颜色分量用double表示,范围从0~1。其它像素类后面的数字代表每个颜色分量占用的位数。大部分像素类都可以从rgba构造。
同时, 像素类还有gradient等牛X的颜色计算方法。
typedef value_type;单个颜色分量的类型
typedef order_type;颜色排序方式,我们可以通过里面的枚举值R G B A得到各颜色分量所在位置,常用的有order_rgb,order_bgr,order_rgba。
这是order_rgb的定义: struct order_rgb { enum rgb_e { R=0, G=1, B=2, rgb_tag }; };
成员方法
unsigned width()
unsigned height()
宽高
color_type pixel(int x, int y);
void copy_pixel(int x, int y, const color_type& c);
取得、设置指定点的颜色
void blend_pixel(int x, int y, const color_type& c, int8u cover);设置指定点颜色,与原颜色有混合效果,强度由cover指定
void copy_hline(int x, int y, unsigned len, const color_type& c);
void copy_vline(int x, int y, unsigned len, const color_type& c);
从x,y开始画一条长度为len的线,颜色为c,同样有blend_版本
void blend_solid_h(v)span(int x, int y, unsigned len,
                   const color_type& c, const int8u* covers);
void blend_color_h(v)span(int x, int y, unsigned len,
                   const color_type* colors, const int8u* covers);
类似hline和vline版本,color版指定一组颜色,依次着色。covers指定覆盖率
实验代码(基于此 处代码)

在on_draw()方法的最后加上:

  1. //从50,20开始,画20条长度为100的坚线,颜色从黑渐变到红,覆盖率为128(半透明)
  2. for(int i=0; i<20; i++)
  3.      pixf.blend_vline(50+i,20,100,agg::rgba(i/20.0,0,0),128);
得到的图形是:

 

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值