AGG高质量图形输出 下载本文

?? agg::renderer_scanline_aa_solid > ren(renb); ?? ?? ?? ??

// Rasterizer & scanline

agg::rasterizer_scanline_aa<> ras; agg::scanline_p8 sl;

??

?? // 多义线(三角形) ?? ras.move_to_d(20.7, 34.15); ?? ras.line_to_d(398.23, 123.43); ?? ras.line_to_d(165.45, 401.87); ??

?? // 设置颜色后渲染

?? ren.color(agg::rgba8(80, 90, 60)); ?? agg::render_scanlines(ras, sl, ren);

?? //============================================================ ??

?? // 把bmp显示到hdc上,如果图片中有Alpha通道,可以使用AlphaBlend代替BitBlt。 ?? ::BitBlt( ?? hdc, ?? rt.left, ?? rt.top, ?? ?? ?? ??

width, height, mem_dc, 0,

?? 0,

?? SRCCOPY ?? ); ??

?? // 释放资源

?? ::SelectObject(mem_dc, temp); ?? ::DeleteObject(bmp); ?? ::DeleteObject(mem_dc);

得到的图形是:

使用AGG提供的pixel_map类

如果你觉得上面的方法还是有点烦的话(这个要怪MS的API太麻烦),可以考虑用AGG友情提供的pixel_map类,用它操作 BMP方便多了。(要把[AGG]\\src\\platform\\win32\\agg_win32_bmp.cpp加入一起编译)

?? #include ?? #include ?? #include

?? #include ?? #include

?? #include ?? ...

?? CRect rc; ?? ?? ?? ??

GetClientRect(&rc);

agg::pixel_map pm;

pm.create(rc.right,rc.bottom,agg::org_color32);

??

?? //============================================================ ??? // 以下是AGG代码

??? agg::rendering_buffer rbuf;

??? rbuf.attach(pm.buf(), pm.width(), pm.height(), -pm.stride());

???

??? // 像素格式和renderer_base

??? agg::pixfmt_bgra32 pixf(rbuf);

??? agg::renderer_base renb(pixf); ???

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

??? // Scanline renderer

??? agg::renderer_scanline_aa_solid > ren(renb); ???

??? // Rasterizer & scanline

??? agg::rasterizer_scanline_aa<> ras; ??? agg::scanline_p8 sl; ???

??? // 多义线(三角形) ??? ras.move_to_d(20.7, 34.15); ??? ras.line_to_d(398.23, 123.43); ??? ras.line_to_d(165.45, 401.87); ???

??? // 设置颜色后渲染

??? ren.color(agg::rgba8(80, 90, 60));

??? agg::render_scanlines(ras, sl, ren);

??? //============================================================ ??? pm.draw(hdc);

线段生成器(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,这里再写一遍它的声明:

? template ? class renderer_scanline_aa; 另外,还有一个函数版本:

? template

? void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, ? SpanAllocator& alloc, SpanGenerator& span_gen); renderer_scanline_aa (还有一个兄弟版本renderer_scanline_bin)可以按指定的图案或不同的颜色(如渐变)填充顶点源里的多边形。其中的模板参数 SpanAllocator用于准备sp

an,我们直接使用agg::span_allocator就行。这里的SpanGenerator就是本节要说的线段生成器,它决定了最终用什么东西填到rendering_buffer里。

线段生成器品种很多,常用的在致可以分成图案类和色彩类两大部分:图案类线段生成器使用已有图像作为span来源;色彩类线段生成器使用指定的颜色作为span来源。

图案类线段生成器

头文件

? #include ? #include ? #include ?? #include ?? #include ?? #include 类型

?? template ?? span_image_filter_[gray|rgb|rgba] ?? template ?? span_image_filter_[gray|rgb|rgba]_2x2 ?? template

?? span_image_filter_[gray|rgb|rgba]_bilinear ?? template

?? span_image_filter_[gray|rgb|rgba]_bilinear_clip ?? template ?? span_image_filter_[gray|rgb|rgba]_nn ?? template ?? span_image_resample_[gray|rgb|rgba] ?? template

?? span_image_resample_[gray|rgb|rgba]_affine ?? template

?? 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),加入下面的头文件 ?? #include

?? #include \?? #include \在on_draw()方法的最后加上下面这些代码 ?? ...

?? // 以图像填充

?? agg::pixel_map pm_img;

?? if(pm_img.load_from_bmp(\?? {

?? // pm_img里的图案作为填充来源 ?? agg::rendering_buffer rbuf_img( ?? pm_img.buf(),

?? pm_img.width(), pm_img.height(),

?? -pm_img.stride());

?? agg::pixfmt_bgr24 pixf_img(rbuf_img);// 我用的bmp是24位的

?? // 线段分配器

?? typedef agg::span_allocator span_allocator_type;//分配器类型 ?? span_allocator_type span_alloc; // span_allocator ?? // 插值器

?? typedef agg::span_interpolator_linear<> interpolator_type; //插值器类型 ?? agg::trans_affine img_mtx; // 变换矩阵 ?? interpolator_type ip(img_mtx); // 插值器 ?? // 线段生成器

?? typedef agg::span_image_filter_rgb_bilinear_clip span_gen_type; // 这个就是Span Generator ??

?? span_gen_type span_gen(pixf_img, agg::rgba(0,1,0), ip); ?? // 组合成渲染器

?? agg::renderer_scanline_aa< ?? ?? ?? ?? ??

renderer_base_type, span_allocator_type, span_gen_type

> my_renderer(renb, span_alloc, span_gen); // 插值器的矩阵变换

?? img_mtx.scale(0.5); ?? img_mtx.translate(40,40); ?? img_mtx.invert(); //注意这里 ?? // 用我们的渲染器画圆 ?? ras.add_path(ell);

?? agg::render_scanlines(ras,sl,my_renderer); ?? }

其中的d:\\\\spheres.bmp(下载)是我预先放在D盘里的24位bmp图像,作为填充的来源。