AGG 文檔翻譯 - alpha mask adapter

Alpah-mask Adapteralpha-mask 適配器)

Alpha-mask 是一個常用於在低層次(像素層次)上實現任意形狀裁剪的獨立buffer,它有一個專用的adapter類(alpha-mask adapter),通過使用alpha-mash過濾器來調用真實的像素渲染器。通常,alpha-mask是一個和主渲染buffer分辨率一樣大的灰度buffer(每個像素一個字節),每個alpha-mask中的像素都是一個額外的像素覆蓋值,用於和主像素混合。像copy_hline()這樣沒有覆蓋值參數的函數調用,被轉換成相應的帶覆蓋值參數的函數調用。比如說,copy_hline會取alpha-mask中的水平線段,然後調用blend_solid_hspan()

以下是怎樣聲明帶alpha-mask adapter的像素渲染器的例子:

#include "agg_pixfmt_rgb24.h"

#include "agg_pixfmt_amask_adaptor.h"

#include "agg_alpha_mask_u8.h"

 

//. . .

 

    // Allocate the alpha-mask buffer, create the rendering buffer object

    // and create the alpha-mask object.

    //--------------------------------

    agg::int8u* amask_buf = new agg::int8u[frame_width * frame_height];

    agg::rendering_buffer amask_rbuf(amask_buf, 

                                     frame_width, 

                                     frame_height, 

                                     frame_width);

    agg::amask_no_clip_gray8 amask(amask_rbuf);

 

    // Create the alpha-mask adaptor attached to the alpha-mask object

    // and the pixel format renderer. Here pixf is a previously

    // created pixel format renderer of type agg::pixfmt_rgb24.

    agg::pixfmt_amask_adaptor<agg::pixfmt_rgb24

                              agg::amask_no_clip_gray8> pixf_amask(pixf, amask);

請注意這裏我們使用了沒有裁剪功能的amask_no_clip_gray8,這是因爲我們使用的主渲染bufferalpha-mask buffer分辨率是一樣的,所以如果我們沒有對主渲染buffer內存做違規操作(如內存越界),那麼我們也不會對alpha-mask buffer做內存違規操作。在這種情況下,裁剪是在更高的層面上實現的。如果你的alpha mask buffer分辨率小於主渲染buffer,那麼你必須得用alpha_mask_gray8

以下是完整的例子:

#include <stdio.h>

#include <string.h>

#include "agg_pixfmt_rgb24.h"

#include "agg_pixfmt_amask_adaptor.h"

#include "agg_alpha_mask_u8.h"

 

enum

{

    frame_width = 320,

    frame_height = 200

};

 

// [...write_ppm is skipped...]

 

int main()

{

    // Allocate the main rendering buffer and clear it, for now "manually",

    // and create the rendering_buffer object and the pixel format renderer

    //--------------------------------

    agg::int8u* buffer = new agg::int8u[frame_width * frame_height * 3];

    memset(buffer, 255, frame_width * frame_height * 3);

    agg::rendering_buffer rbuf(buffer, 

                               frame_width, 

                               frame_height, 

                               frame_width * 3);

    agg::pixfmt_rgb24 pixf(rbuf);

 

 

    // Allocate the alpha-mask buffer, create the rendering buffer object

    // and create the alpha-mask object.

    //--------------------------------

    agg::int8u* amask_buf = new agg::int8u[frame_width * frame_height];

    agg::rendering_buffer amask_rbuf(amask_buf, 

                                     frame_width, 

                                     frame_height, 

                                     frame_width);

    agg::amask_no_clip_gray8 amask(amask_rbuf);

 

    // Create the alpha-mask adaptor attached to the alpha-mask object

    // and the pixel format renderer

    agg::pixfmt_amask_adaptor<agg::pixfmt_rgb24

                              agg::amask_no_clip_gray8> pixf_amask(pixf, amask);

 

 

    // Draw something in the alpha-mask buffer. 

    // In this case we fill the buffer with a simple verical gradient

    unsigned i;

    for(i = 0; i < frame_height; ++i)

    {

        unsigned val = 255 * i / frame_height;

        memset(amask_rbuf.row_ptr(i), val, frame_width);

    }

 

 

    // Draw the spectrum, write a .ppm and free memory

    //----------------------

    agg::rgba8 span[frame_width];

 

    for(i = 0; i < frame_width; ++i)

    {

        agg::rgba c(380.0 + 400.0 * i / frame_width, 0.8);

        span[i] = agg::rgba8(c);

    }

 

    for(i = 0; i < frame_height; ++i)

    {

        pixf_amask.blend_color_hspan(0, i, frame_width, span, 0);

    }

 

    write_ppm(buffer, frame_width, frame_height, "agg_test.ppm");

 

    delete [] amask_buf;

    delete [] buffer;

    return 0;

}

下面是程序運行的結果:

 

請注意我們之前用白色來初始化了主渲染buffer,現在把這行代碼

memset(buffer, 255, frame_width * frame_height * 3);

替換成

memset(buffer, 0, frame_width * frame_height * 3);

那麼結果變成

 

也就是說alpha-mask作爲一個獨立的alpha通道與被渲染的圖元混合,事實上alpha-mask的像素包含8位值(一個字節),這允許你以完美的反走樣(抗鋸齒)和任意形狀裁剪所有的圖形繪製。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章