AGG 線段產生器(Span Generator)

來源:互聯網
上載者:User
線段產生器(Span Generator)

我們前面舉的例子使用的都是簡單的單一實色,如藍色的圓、黑色的線等。這是因為在例子裡我們一直使用renderer_scanline_aa_solid或render_scanlines_aa_solid。

在上篇文章(http://www.cppprog.com/2009/0821/150.html)的渲染器一節中除了renderer_scanline_aa_solid外,還提到有一個renderer_scanline_aa,這裡再寫一遍它的聲明:

  1. template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
  2.     class renderer_scanline_aa;

另外,還有一個函數版本:

  1. template<class Rasterizer, class Scanline, class BaseRenderer,
  2.          class SpanAllocator, class SpanGenerator>
  3. void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
  4.                           SpanAllocator& alloc, SpanGenerator& span_gen);

renderer_scanline_aa (還有一個兄弟版本renderer_scanline_bin)可以按指定的圖案或不同的顏色(如漸層)填充頂點源裡的多邊形。其中的模板參數 SpanAllocator用於準備span,我們直接使用agg::span_allocator就行。這裡的SpanGenerator就是本節要說的線段產生器,它決定了最終用什麼東西填到rendering_buffer裡。

線段產生器品種很多,常用的在致可以分成圖案類和色彩類兩大部分:圖案類線段產生器使用已有映像作為span來源;色彩類線段產生器使用指定的顏色作為span來源。

圖案類線段產生器標頭檔
  1. #include <agg_span_image_filter_gray.h>
  2. #include <agg_span_image_filter_rgb.h>
  3. #include <agg_span_image_filter_rgba.h>
  4. #include <agg_span_pattern_gray.h>
  5. #include <agg_span_pattern_rgb.h>
  6. #include <agg_span_pattern_rgba.h>
類型
  1. template<class Source, class Interpolator>
  2.      span_image_filter_[gray|rgb|rgba]
  3. template<class Source, class Interpolator>
  4.      span_image_filter_[gray|rgb|rgba]_2x2
  5. template<class Source, class Interpolator>
  6.      span_image_filter_[gray|rgb|rgba]_bilinear
  7. template<class Source, class Interpolator>
  8.      span_image_filter_[gray|rgb|rgba]_bilinear_clip
  9. template<class Source, class Interpolator>
  10.      span_image_filter_[gray|rgb|rgba]_nn
  11. template<class Source, class Interpolator>
  12.      span_image_resample_[gray|rgb|rgba]
  13. template<class Source>
  14.      span_image_resample_[gray|rgb|rgba]_affine
  15. template<class Source>
  16.     class agg::span_pattern_[gray|rgb|rgba]

上面這些線段產生器類的模板參數都比較相似:Source用於指定映像來源,可以是PixelFormat renderer或agg::image_accessor_clip(由不同的線段產生器類決定);Interpolator是一種插值器,用於填充映像間隙。我們先寫一段範例程式碼,先看一下線段產生器的作用,也為後面的各種實驗做準備。

範例程式碼,使用span_image_filter_rgb_bilinear_clip

還是基於這個代碼(http://www.cppprog.com/2009/0816/146.html),加入下面的標頭檔

  1. #include <platform/win32/agg_win32_bmp.h>
  2. #include "agg_span_allocator.h"
  3. #include "agg_span_image_filter_rgb.h"

在on_draw()方法的最後加上下面這些代碼

  1. ...
  2. // 以映像填充
  3. agg::pixel_map pm_img;
  4. if(pm_img.load_from_bmp("d://spheres.bmp"))
  5. {
  6.     // pm_img裡的圖案作為填充來源
  7.      agg::rendering_buffer rbuf_img(
  8.          pm_img.buf(),
  9.          pm_img.width(), pm_img.height(),
  10.          -pm_img.stride());
  11.      agg::pixfmt_bgr24 pixf_img(rbuf_img);// 我用的bmp是24位的
  12.     // 線段分配器
  13.     typedef agg::span_allocator<agg::rgba8> span_allocator_type;//分配器類型
  14.      span_allocator_type span_alloc; // span_allocator
  15.     // 插值器
  16.     typedef agg::span_interpolator_linear<> interpolator_type; //插值器類型
  17.      agg::trans_affine img_mtx; // 變換矩陣
  18.      interpolator_type ip(img_mtx); // 插值器
  19.     // 線段產生器
  20.     typedef agg::span_image_filter_rgb_bilinear_clip<agg::pixfmt_bgr24,
  21.          interpolator_type > span_gen_type; // 這個就是Span Generator
  22.         
  23.      span_gen_type span_gen(pixf_img, agg::rgba(0,1,0), ip);
  24.     // 組合成渲染器
  25.      agg::renderer_scanline_aa<
  26.          renderer_base_type,
  27.          span_allocator_type,
  28.          span_gen_type
  29.      > my_renderer(renb, span_alloc, span_gen);
  30.     // 插值器的矩陣變換
  31.      img_mtx.scale(0.5);
  32.      img_mtx.translate(40,40);
  33.      img_mtx.invert(); //注意這裡
  34.     // 用我們的渲染器畫圓
  35.      ras.add_path(ell);
  36.      agg::render_scanlines(ras,sl,my_renderer);
  37. }

其中的d://spheres.bmp(下載)是我預先放在D盤裡的24位bmp映像,作為填充的來源。

顯示效果:

  1. 在第19行的span_gen_type之前,所有的事情都在為定義這個線段產生器做準備。
  2. 首先是用pixel_map讀取bmp檔案,然後產生rendering_buffer和pixfmt_bgr24作為這個線段產生器的"Source"。
  3. 然後是線段分配器,這個沒什麼特殊要求的話用span_allocator就可以了。
  4. 接著是插值器類型,插值器也有幾個類型(後面會介紹),它的建構函式需要一個變換矩陣對象,於是我們得為它裝備一個。
  5. 現在,終於可以組合成一個我們的線段產生器了。這裡使用的是span_image_filter_rgb_bilinear_clip,它的Source是PixelFormat Renderer,如本例的pixfmt_bgr24。
  6. span_image_filter_rgb_bilinear_clip的建構函式有三個參數,分別是Source對象,填充來源範圍之外的顏色和插值器對象。
  7. 我們可以改變插值器的矩陣來變換填充映像,象這裡的img_mtx.scale(0.5)和img_mtx.translate(40,40)。要注意的是,插值器的矩陣運算是從目標位置向源位置計算的(即根據目標位置變換得到對應的填充源位置),所以想對源映像變換的話,要記得最後調用矩陣的invert()方法取反。
  8. 最後,畫圓。由於ell是ellipse對象,沒有被conv_stroke轉換的ellipse對象是實心的(多邊形而不是多義線),於是填充之。

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

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.