溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

AGG第二十五課 pixel format renderers像素格式渲染器

發布時間:2020-07-13 15:53:01 來源:網絡 閱讀:694 作者:fengyuzaitu 欄目:系統運維

1 聲明

看看這個聲明:

agg::pixfmt_rgb24 pixf(rbuf);

這里我們創建了一個底層的像素渲染對象(pixel renderingobject)并將它附著到渲染內存區(renderingbuffer)上,它是這樣定義的:

typedef pixel_formats_rgb24<order_rgb24>pixfmt_rgb24;

類模板 pixel_formats_rgb24 掌握了內存中具體的像素格式信息。唯一的模板參數可以是 order_rgb24 或是 order_rgb23,它們定義了顏色字節(color channels)的順序。

 rendering buffer 不同的是,這些類使用整型的像素坐標進行操作,因為它們知道怎么計算對于特定點 的偏移。你可能會說,如果在 rendering buffer 中保存像素的寬度值的話會更容易,但是在實踐中會有很多限制。別忘了,像素寬度可能比一個字節還小,比如在打印機渲染高解析度的 B&W 圖像的時候就是這樣。因此,我們需要將這個功能分離出來,rendering_buffer 這個類就用于加速對“行”的訪問,而 pixelformat renderers 就負責如何解析“行”是什么。

pixel_formats_rgb24(rendering_buffer&rb);

像素格式渲染器(pixecl formatrenderers)的構造函數需要一已經創建并良好初始化的rendering_buffer對象的引用。這個構建工作的開銷很小,基本上只是初始化一個指針。

Member Functions

 

像素格式渲染器(pixecl formatrenderers)必須要實現以下這些接口:

 

 

unsigned width()  const { return m_rbuf->width();  }

unsigned height() const { returnm_rbuf->height(); }

返回內存區的寬和高(以像素數來衡量)

 

color_type pixel(int x, int y);

返回(x,y)坐標處的像素的顏色

 

void copy_pixel(int x, int y, constcolor_type& c);

將帶顏色的像素拷入緩存區中。如果是本身 RGB 像素格式,那么它就不考慮 rgba8 拷貝源中的存在的 alpha 通道。如果本身是 RGBA,那么它就簡單地把所有值都拷貝過來,包括 R、G、B,以及 alpha 通道值。

 

void blend_pixel(int x, int y, constcolor_type& c, int8ucover);

這個函數將帶顏色信息的像素 與緩存區(x,y)處的像素進行混合(blending)?,F在我們來解釋一下“混合”的概念?;旌?span >(blending)是抗鋸齒(anti-aliasing)的關鍵特性。在 RGBA 的顏色空間中,我們使用 rgba8 結構體來代表顏色。這個結構體有一個數據成員int8u a ,它就是 alpha 通道。不過,在這個函數里,我們還看到一個參數 cover ,表示像素的覆蓋值大小,比如,這個像素被多邊形所“覆蓋”的部分的大?。ㄗg注:這涉及到亞像素精度,因為一個像素可以分為 256*256 份,所以這個像素并不一定全部被“覆蓋”,詳細可參考AGG 對于亞像素的說明)。其實你可以把它看成是另一個 alpha(或者應該叫它Beta?:))。這么做有兩個原因,首先,顏色類型(color type)不一定非要包含 alpha 值)。就算顏色類型帶有 alpha 值,它的類型也不一定非要與抗鋸齒算法中使用的顏色類型一致。假設你現在使用的是 "Hi-End" RGBA 顏色空間,這種顏色空間使用4個取值范圍是[0,1]浮點型來表示,alpha通道值也使用浮點數————對于這種情況來說,混合時使用一個byte實在太少了,但在去鋸齒時卻非常夠用。所以,cover 值就是為去鋸齒而使用的一個統一的備用 alpha 值。在大部分情況來說,用 cover_type 來定義它,但在光柵化處理器(rasterizers)中是直接顯示地使用 int8u 類型的。這是故意這么定義的,因為如果需要加強 cover_type 的能力時,會使得所有已經存在的像素格式光柵化處理器(pixel formatrasterizres)變得與cover_type 不兼容。它們確實是不兼容的,在進行顏色混合時,如果中間值使用 32-bit 值來暫存的話,那么最大只能使用 8-bit 的覆蓋值(coverage value)和 8-bit  alpha (alpha 。如果使用 16-bit 的值的話,就要用64-bit 的中間值暫存,這對于 32-bit 的平臺來說會有非常昂貴的開銷。

 

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);

 

使用某種顏色描畫一條水平或是垂直的線。

 

void blend_hline(int x, int y, unsignedlen, const color_type&c, int8u cover);

void blend_vline(int x, int y, unsignedlen, const color_type&c, int8u cover);

 

采用混合顏色的模式描畫一帶某種顏色的水平(或垂直線)線。之所以要分開 copy  blend 兩個版本,是因為考慮到效率問題。雖然可以使用一個if/else (其實在 blend 版的描畫函數中就有)來區分,但對于某些場合,比如要描畫很多小型標識(markers)時,這會很影響效率,這種場景在不同的散點圖描畫程序(scatter plotapplicatioin)中常常遇到。

 

void blend_solid_hspan(int x, int y,unsigned len,

                      const color_type& c,const int8u* covers);

void blend_solid_vspan(int x, int y,unsigned len,

                      const color_type& c,const int8u* covers);

 

混合描畫一條水平或是垂直的 solid-color  span, Span hline  vline 幾乎是一樣的,但它擁有一個存有 coveragevalue 的數組。這兩個函數在渲染實心的去鋸齒多邊形時會用到。

 

void blend_color_hspan(int x, int y,unsigned len,

                      const color_type*colors, const int8u* covers);

void blend_color_vspan(int x, int y, unsignedlen,

                      const color_type*colors, const int8u* covers);

 

混合描畫水平或是垂直的顏色 span ,這兩個函數用于不同的 span 產生器中,比如說 gradient,p_w_picpath,patterns,Gouraud interpolation 等等。函數接受一個顏色數組參數,這個顏色數組必須與所使用的像素格式兼容。比如說,所有 AGG 中已經有的 RGB 像素格式都與 rgb8類型是兼容的。 covers 參數是一個 coverage value 的數組,這與 blend_solid_hspan 中的是一樣的。這是參數可選,可以設置為 。

下面這個例子是描畫陽光的光譜。rgba 類包含有 個浮點數的顏色部分(包括alpha),這個類有一個靜態函數 from_wavelength ,以及相應的構造函數。rgba8 可以用 rgba 來構造(在 AGG 中這是一個常見的策略,也就是任何的顏色類型都可以用 rgba 來構造)。

2 學習的要點

該類是從像素的角度,來填充渲染緩存,通過指定rgb8結構體,來填充渲染緩存的像素值。

這里多說一點:rgb8是顏色值是8位的,范圍是(0,255),rgb是顏色值為浮點型(0,1.

3開銷

分析代碼:

   agg::rendering_buffer &rbuf = rbuf_window();

   agg::pixfmt_bgr24 pixf(rbuf);

 

   typedef agg::renderer_base<agg::pixfmt_bgr24> renderer_base_type;

   renderer_base_type renb(pixf);

 

agg::renderer_primitives<renderer_base_type>primitive(renb);

 

像素格式渲染器和基礎渲染器對象的構建開銷是很小的,僅僅是獲取渲染緩存的指針,對渲染緩存進行渲染的操作,沒有任何的內存分配。比如生成像素格式渲染器pixfmt_bgr24,僅僅是將渲染緩存的指針賦值給pixfmt_bgr24的成員變量m_buf.

4 pixfmt_rgb24 PK pixfmt_bgr24

windows平臺下,申請的渲染緩存的顏色分量是排列如下:BGR,而不是平常的RGB。所以采用了pixfmt_bgr24,而不是pixfmt_rgb24, 對于OpenGL設置像素的時候,也是一樣的道理。

查看渲染緩存的顏色序列

   agg::rendering_buffer &rbuf =rbuf_window();

   agg::pixfmt_bgr24 pixf(rbuf);

agg::pixfmt_rgb24pixf1(rbuf);

 for (int i = 20;i<250;i++)

 {//渲染出紅色

     pixf.copy_hline(20,i,300,agg::rgba8(255,0,0));

 }

 

 for (int i = 20;i<250;i++)

 {//渲染出藍色

   pixf1.copy_hline(420,i,300,agg::rgba8(255,0,0));

 }

 

 提供如下的一種方式直接操作渲染緩存,查看是否是顏色序列不一樣導致的??

 agg::rendering_buffer &rbuf =rbuf_window();

   renb.clear(agg::rgba8(255,255,255));

 

    for (int i =0;i < rbuf.height();i++)

    {

      unsigned char* p = rbuf.row_ptr(i);

      for (int j=0;j<rbuf.width();j++)

      {

        *p++ = 255;//顯示結果為藍色

        *p++ = 0;

        *p++ = 0;

      }

    }

 

    for (int i =0;i < rbuf.height();i++)

    {

      unsigned char* p = rbuf.row_ptr(i);

      for (int j=0;j<rbuf.width();j++)

      {

        *p++ = 0;

        *p++ = 0;

        *p++ = 255;

      }

    }


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女