AGG 渲染器(Renderers)

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

 

發佈了2 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章