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_solid、render_scanlines_aa、 render_scanlines_bin_solid、render_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));語句後面加上:
- renb.clear(agg::rgba8(255,255,255));
- 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_gray8pixfmt_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()方法的最後加上:
- //從50,20開始,畫20條長度爲100的堅線,顏色從黑漸變到紅,覆蓋率爲128(半透明)
- for(int i=0; i<20; i++)
- pixf.blend_vline(50+i,20,100,agg::rgba(i/20.0,0,0),128);
得到的圖形是:
作者:毛毛 來源:www.cppprog.com