AGG反锯齿绘图库的学习笔记(二)

来源:互联网 发布:java中spring框架 编辑:程序博客网 时间:2024/05/06 04:51

     AGG与其他Graphics库最不同的是绘图过程,它的核心绘制模板类是agg::path_storage,但这个类完全不负责任何像素的绘制,它只是一个绘图的缓存器。agg::path_storage提供了线段,椭圆,样条曲线,圆弧等基本矢量绘制元素的绘制功能,但一定要记住,在agg::path_storage内的东西是不能直接绘出来的,它只是一个绘图指令的缓存器。

    AGG的图形绘制坐标是浮点数,这很重要,不要按照整数/像素的概念来理解AGG,在AGG中是允许绘出长度10.49像素这样长度的线条的。不过AGG的坐标系本身与普通绘图库一致,即一个像素为1.0长度,Y轴朝下,X轴朝右(当然,使用不同的渲染适配器可以改变这种坐标体系,我们以在一般意义上的位图来举例)。

    我在尝试AGG的时候使用了wxWidget作为绘制容器(这本来也是我学习AGG的目的),我使用wxImage对象作为“绘图板”,wxImage对象初始化以后会申请一个按RGB排列从左到右,从上到下的内存区域,保存设备无关位图。

wxImage test(1024,1024,false);   

unsigned char* pData=pImg->GetData();

这两行语句获取了一个wxImage维护的内存块,这就是我们的绘图板。

我们必须让AGG知道绘图板的基本结构,在AGG中定义了一大堆模板,几乎可以适应所有可能的位图结构,在wxImage条件下,可以定义以下位图类

#define pix_format agg::pix_format_rgb24
typedef agg::pixfmt_rgb24 pixfmt;
typedef agg::pixfmt_rgb24_pre pixfmt_pre;
#define pixfmt_gamma agg::pixfmt_rgb24_gamma
typedef agg::rgba8 color_type;
typedef agg::order_rgb component_order;
typedef agg::renderer_base<pixfmt> renderer_base;

    解释一下以上的类型定义:pixfmt就是位图格式了,显然wxImage是RGB 24位位图的格式;color_type 使用rgba8是没有问题的,虽然没有alpha通道,但是只要色彩顺序不乱,而且不是浮点值表示色彩就行(浮点色彩的色域更宽,目前我还用不到);typedef agg::renderer_base<pixfmt> renderer_base; typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_aa;这两条语句定义了反锯齿绘制的核心渲染对象类别,通过以上模板的定义,AGG就可以在wxImage位图条件下高效的工作了。AGG使用模板来适配不同的“绘图板”效率很高(编译器静态适配啊),但是的确让人很难理解,不过有点也很多,我们可以使用完全不同的“绘图板”,不像GDI+只能在Windows内部的Bitmap上工作。


    要让绘图板工作,当然要将绘图板的内存块传递给AGG,AGG比较操蛋,这个事情又给弄复杂了,不批判了,看以下代码:

pixfmt::rbuf_type m_rBuf;  

m_rBuf对象很重要,但是首先需要定义的是一个pixfmt类型的子类型pixfmt::rbuf_type,这真特莫坑爹,大概作者认为pixfmt是格式,pixfmt::rbuf_type才是首先需要的对象,可是文档中一笔带过,例程中千奇百怪,找到这个必须的定义真不容易啊。

    m_rBuf..attach(pData,W,H,W*3);

    这就完成了将wxImage内存块交给AGG绘图的功能了,W,H是绘图板的长和宽,按像素值设置(这又不用浮点了,很自然,但也不好理解),W*3很坑爹,这是绘图快一行的字节数,有些位图格式可能有对齐要求,wxImage不用对齐,所以一行是W*3(RGB三个字节一个像素)

    好了,很累,但很快就看到曙光了

pixfmt pixf(m_rBuf);
renderer_base rb(pixf); 
 

    这里,将m_rBuf传递给了AGG抽象位图---pixfmt对象pixf,为什么说是抽象位图呢,pixf其实是一个适配对象,它本身不申请任何绘图内存块,所以要先建立绘图内存对象m_rBuf,然后用来初始化pixf。rb对象,可爱的rb对象,这是我们初步使用AGG的根基了,rb其实也是一个适配器,本身也不申请绘图的内存块,所以又必须用pixf初始化它。


写得很辛苦.......明天接着写....



原创粉丝点击