用AGG實現高品質圖形輸出(二)

來源:互聯網
上載者:User

來自http://www.cppprog.com/2009/0821/150.html

上次講了AGG的顯示原理並舉了一個簡單的例子,這一篇文章開始講AGG工作流程裡的每個環節。為了方便對照,再放一次AGG顯示流程 圖

 

 

另外,上 一篇文章裡的例 程也 很重要,後面的例子都將基於這個代碼。

下面,我們來考察AGG顯示流程中的每個環節。理解每個環節最好的方法是編寫實驗代碼,建議先參照這裡建 立一個可以啟動並執行AGG實驗環境。

頂點源(Vertex Source)

<!--基本屬性-->

頂點源(Vertex Source)

頂點源是一種可以產生多邊形所需要的“帶命令的頂點”的對象。比如三角形頂點源,就應該會產生一個帶“MoveTo”命令的點,另外二 個帶"LineTo"命令的點和最終閉合的“ClosePoly”命令。

標頭檔
#include <agg_path_storage.h> //path_storage#include <agg_ellipse.h>  // ellipse#include <agg_arc.h> // arc#include <agg_arrowhead.h> // arrowhead#include <agg_curves.h> // curve3, curve4#include <agg_gsv_text.h> // gsv_text, gsv_text_outline#include <agg_rounded_rect.h> // rounded_rect...
類型
自訂類 所有實現了void rewind(unsigned path_id);和unsigned vertex(double* x, double* y);的類。
ellipse 圓,輸入為中心點座標和XY軸半徑,本文所用的例子就 使用了這個頂點源
arc 弧線,輸入為中心點座標和XY軸半徑,以及起始和終止角(rad),順時針/逆時針方向
curve3 貝茲路徑,輸入為起點座標、第一控制點座標、終點點座標
curve4 貝茲路徑,輸入為起點座標、第一控制點座標、第二控制點座標、終點座標
gsv_text 使用AGG內建字模的文字輸出(只支援ASCII碼),使用start_point方法指定文字位置,text方法指定 文字,flip指定是否上下倒轉,size指定文字大小,適合與conv_stroke或gsv_text_outline配合。
gsv_text_outline<> 可變換文字,輸入為gsv_text和變換矩陣(預設為trans_affine,後文會提到)。width方法設定文 字寬度
rounded_rect 圓角方形,輸入為左上方右下角座標和圓角半徑
path_storage 路徑儲存空間,可以用join_path方法加入多個頂點源。而且path_storage本身支援move_to, line_to,curve和arc_to等畫線功能
arrowhead 箭頭,它是作為標記點來用的

其中的arrowhead頗為特殊,它一般作為線段的標記點,具體用法是這樣的:

arrowhead ah;ah.head(d1,d2,d3,d4); //定義箭頭ah.tail(d1,d2,d3,d4); //定義箭尾VertexSource VS; //其它頂點源// 使用頂點轉換器,並指定Markers類型為vcgen_markers_term// 頂點轉換器可以是conv_dash、conv_stroke或conv_marker_adaptor,見後文《座標轉換管道》// vcgen_markers_term:以端點作為標記點conv_stroke<VertexSource, vcgen_markers_term> csVS(VS);...draw_term// 用conv_marker指定ah作為線段marker點的標記conv_marker<vcgen_markers_term, arrowhead> arrow(csVS.markers(), ah);ras.add_path(csVS);ras.add_path(arrow); //marker要緊隨其後加入...render

ah.head()和ah.tail()方法中的d1,d2,d3,d4參數的意義見


例,畫一條簡單的箭頭直線(基於此處代碼)

在on_draw()方法最後加上下列代碼:

  1. agg::arrowhead ah;
  2.  ah.head(0,10,5,5);
  3.  ah.tail(10,10,5,5);
  4.  // 用path_storage產生一條直線
  5.  agg::path_storage ps;
  6.  ps.move_to(160,60);
  7.  ps.line_to(100,100);
  8.  // 轉換
  9.  agg::conv_stroke<agg::path_storage, agg::vcgen_markers_term> csps(ps);
  10.  agg::conv_marker<agg::vcgen_markers_term, agg::arrowhead>
  11.      arrow(csps.markers(), ah);
  12.  // 畫線
  13.  ras.add_path(csps);
  14.  agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(0,0,0));
  15.  // 畫箭頭
  16.  ras.add_path(arrow);
  17.  agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(255,0,0));
得到的圖形是:

注意要加標頭檔:

#include "agg_conv_marker.h"#include "agg_arrowhead.h"#include "agg_path_storage.h"#include "agg_vcgen_markers_term.h"
實驗代碼,自訂一個頂點源(基於此處代碼)

為了對頂點源有更深入的瞭解,我們要自己實現一個頂點源,這個頂點源只是很簡單的一個三角形。

前面說過,只要實現了 void rewind(unsigned path_id); 和 unsigned vertex(double* x, double* y); 方法就可以作為頂點源。

rewind方 法指示頂點源回到第一個頂點;vertex方 法取出當前頂點然後把當前頂點下移,傳回值是當前頂點所帶的命令。所謂的命令是一個enum path_commands_e類 型,定義如下:

  1. enum path_commands_e
  2. {
  3.     path_cmd_stop     = 0,        //----path_cmd_stop   
  4.     path_cmd_move_to  = 1,        //----path_cmd_move_to
  5.     path_cmd_line_to  = 2,        //----path_cmd_line_to
  6.     path_cmd_curve3   = 3,        //----path_cmd_curve3 
  7.     path_cmd_curve4   = 4,        //----path_cmd_curve4 
  8.     path_cmd_curveN   = 5,        //----path_cmd_curveN
  9.     path_cmd_catrom   = 6,        //----path_cmd_catrom
  10.     path_cmd_ubspline = 7,        //----path_cmd_ubspline
  11.     path_cmd_end_poly = 0x0F,     //----path_cmd_end_poly
  12.     path_cmd_mask     = 0x0F      //----path_cmd_mask   
  13. };

path_commands_e還 能和path_flags_e組 合:

  1. enum path_flags_e
  2. {
  3.     path_flags_none  = 0,         //----path_flags_none
  4.     path_flags_ccw   = 0x10,      //----path_flags_ccw 
  5.     path_flags_cw    = 0x20,      //----path_flags_cw  
  6.     path_flags_close = 0x40,      //----path_flags_close
  7.     path_flags_mask  = 0xF0       //----path_flags_mask
  8. }; 

vertex()返回的命令中含有path_cmd_stop時 表示結束。

  1. // 等邊三角形
  2. class triangle{
  3. public:
  4.     triangle(double cx, double cy, double r)//中心點,r為中心點到邊的長度
  5.     {
  6.         // 直接準備好三個點
  7.         m_step = 0;
  8.         m_pt[0].x = cx; m_pt[0].y = cy-r;
  9.         m_pt[1].x = cx+r*0.866; m_pt[1].y = cy+r*0.5;
  10.         m_pt[2].x = cx-r*0.866; m_pt[2].y = cy+r*0.5;
  11.         //AGG把方向作為區分多邊形內部和外部的依據,可以試試m_pt[1]和m_pt[2]對調
  12.     }
  13.     void rewind(unsigned)
  14.     {
  15.         m_step = 0;
  16.     }
  17.     unsigned vertex(double* x, double* y)
  18.     {
  19.         switch(m_step++)
  20.         {
  21.         case 0:
  22.             //第一步,move_to
  23.             *x = m_pt[0].x;
  24.             *y = m_pt[0].y;
  25.             return agg::path_cmd_move_to;
  26.         case 1:
  27.         case 2:
  28.             //第二、三步,line_to
  29.             *x = m_pt[m_step-1].x;
  30.             *y = m_pt[m_step-1].y;
  31.             return agg::path_cmd_line_to;
  32.         case 3:
  33.             // 第四步,閉合多邊形
  34.             return agg::path_cmd_end_poly|agg::path_flags_close;
  35.         default:
  36.             // 第五步,結束
  37.             return agg::path_cmd_stop;
  38.         }
  39.     }
  40. private:
  41.     agg::point_d m_pt[3];
  42.     unsigned m_step;
  43. };

在on_draw()方法裡把

    agg::ellipse ell(100,100,50,50); 改成triangle ell(100,100,50);
    typedef agg::conv_contour<agg::ellipse> ell_cc_type;改成typedef agg::conv_contour<triangle> ell_cc_type;
得到的圖形是:

除了文字輸出功能(gsv_text只能輸出ASCII文字),上面這些頂點源提供的圖形豐富程度已經超過了系統API。文字輸出功能 將以單獨的篇幅講述。

  • 大小: 5.4 KB
  • 大小: 2.5 KB
  • 大小: 11.3 KB
  • 大小: 9.4 KB

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.