AGG入门资料整理文档格式.docx
- 文档编号:19871702
- 上传时间:2023-01-11
- 格式:DOCX
- 页数:76
- 大小:702.45KB
AGG入门资料整理文档格式.docx
《AGG入门资料整理文档格式.docx》由会员分享,可在线阅读,更多相关《AGG入门资料整理文档格式.docx(76页珍藏版)》请在冰豆网上搜索。
Inkspace:
一个跨平台的SVG编辑软件,部分使用了AGG的功能(还使用了ArtLib的功能,我以后会对ArtLib作介绍)。
wxArt2d:
一个基于Wxwindow的2D图形编辑软件,提供了AGG可以一种作图选择。
vcf:
一个C++框架库,使用AGG作为图形输出。
这些库都可以到上找到。
一、概要
AGG是一个用标准的平台无关的C++写成的通用图形工具包。
它可以应用在计算机程序中需要高质量的2D图形的许多方面。
例如,AGG可以用于渲染2D地图。
AGG只使用了C++和标准C的函数,如memcpy,sin,cos,sqrt等。
基本的算法甚至没有使用C++StandardTemplateLibrary。
因此,AGG能够在大量的应用软件中使用,包括嵌入式系统中。
另一方面,AGG允许对库的一部分进行替换,比如在它不能适应性能的要求时。
如果需要,你也能够添加其他的颜色空间。
因为AGG是基于C++的模板机制的。
AGG不是一个紧密的图形库,它并不容易使用。
这是由于考虑到AGG是一个“创建其他工具的工具”。
这意味着,没有“Graphcis”对象或是其他类似的东西。
取而代之的是许多组织松散的、能单独或是组合使用的算法。
这些算法有着定义良好的接口,它们之间有着尽可能最小的隐式或显式的依赖关系。
1.建议
AGG最主要的目标是打破一下旧的传统(针对GDI,GDI++的一些缺点,比如过于庞大,不能修改以满足要求等)。
AGG所要展示的是稳定,轻巧,灵活和自由。
与STL不同,AGG是C++图形库。
STL通常能够很方便的直接在程序中使用。
而并不建议象使用STL那样使用AGG。
更好的使用AGG的方法是,可以针对需要处理的问题对它进行简单的封装后进行使用。
这与GDI+有什么不同?
首先,可以对封装后的AGG完全进行控制。
AGG只是提供了一系列基本的算法,而这些算法间有着很少的的关联。
可以只定义接口,转换管道和输出的形式。
甚至可以替代任何已经存在的图形接口的一部分。
例如,可以使用AGG的光栅化器来在屏幕上显式图形并直接调用用GDI来打印。
下图是GDI+和AGG的渲染品质的比较。
但最重要的是,如果程序设计的足够灵活,这可以使得程序变成完全可移植的。
2.反锯齿和亚像素精度
反锯齿是用于在低分辩率设备上显示图象时改善视觉品质的一种广为人知的技术。
它基于人类的视觉特性。
看看下图,尝试猜测一下是什么意思。
这是一个用反锯齿方式绘制的词。
现在来看看正常大小的同一幅图。
能够很容易的分辨出这是“stereo”。
然而这是两幅相同的图。
只是第一幅比第二幅大。
反锯齿并没有让它看起来更清楚,它只是让你的大脑更容易推断出是什么。
AGG中不仅仅使用了反锯齿,它还利用了亚像素精度的技术。
下图中显示了使用简单的Bresenham差值放大后的结果。
如图中
(2)和(3),由于利用了亚像素精度,虽然线的起始点和结束点是同样的,但是可以表示两种不同的线。
而如果不利用亚像素精度,同样的起始点和结束点则只能表示一种线,如
(1)。
如果同时利用亚像素精度和反锯齿,就能够获得更好的效果。
看看下面的图有什么不同:
这三个螺旋形可以近似的看成是由短的直线段组成的。
左边的那幅图采用的是正常的IntegerBresenham方法(使用WindowsGDI的LineTo和MoveTo函数也可以得到类似的效果)。
中间的图采用了改进后的精度为1/256像素的IntegerBresenham方法。
而右边的图同样使用了1/256像素的精度,但是同时还使用了反锯齿。
请注意,将线段中亚像素真实定位的能力非常重要。
如果我们对正常像素坐标使用反锯齿,那么螺旋形看起来会更平滑,但仍然同左边的图一样难看。
亚像素精度甚至比控制线的视觉厚度(visualthickness)更加重要。
只有当我们有一个好的反锯齿算法时,良好的精确性才能成为可能。
另一方面,如果我们可以只用一个点的离散性来确定线的宽度,那么反锯齿就没有什么用处了。
反锯齿和亚像素精确度总是协同使用的。
现代显示器的分辨率最多是120DPI,而利用亚像素精度可以达到300DPI。
下面的图片显示的线的宽度从0.3像素开始,依次递增0.3像素。
用反锯齿和亚像素精度渲染的线
下面是两个用亚像素精度进行渲染的例子:
用反锯齿和亚像素精度渲染的圆形
可爱的狮子
请注意:
那些小的狮子虽然丢失了一些细节,但还是保持了与较大狮子的一致性。
二、基本观念
1.库的设计
AGG被设计成一系列松散的算法和类模板。
因此所有的部分都能够很容易的组合起来。
基于模板的设计使得可以替代库的一部分而不需要修改一行代码。
AGG也被设计的易扩展和灵活。
可以在其中很容易的添加新的算法。
AGG并没有指定任何它的形式,可以自由的使用它的任何一部分。
然而,AGG被当作一个在内存中渲染图象的工具。
这是学习AGG的一个不错的着手点,可这样并不十分准确。
在AGG提供的教程中有如何开始学习AGG更好的例子。
下面是一个典型的AGG渲染途径。
注意在VertexSource和ScreenOutput之间的任一步骤都不是强制性的。
例如,你能使用基于WindowsAPI光栅化器,这样你就不需要AGG的光栅化和渲染了。
如果只想绘制线,可以使用AGG的outline光栅化器,这样可以更快。
对上图的一些说明:
VertexSource
VertexSource是一些对象。
如多边形,polyline等一系列连续的2D顶点。
可以通过MoveTo,LineTo产生。
Coordinateconversionpipeline
Coordinateconversionpipeline由一组坐标转换器组成。
它通常作用于用浮点数描绘的矢量数据(X,Y)。
可能会包括一些几何变换,轮廓生成等。
ScanlineRasterizer
ScanlineRasterizer把矢量数据转换成许多水平的扫描线。
这些扫描线通常(不是必须)带有反锯齿的信息。
Renderers
Renderers对扫描线进行渲染。
把渲染的结果写入renderingbuffer。
RenderingBuffer
RenderingBuffer是内存中的一个在后面用于显示的缓冲区。
通常(不是必须)它包含了适应于显示系统的像素格式。
如,24位的B-G-R,32位的B-G-R-A或15位的R-G-B-555等。
2.颜色,颜色空间和像素格式
在AGG中颜色直到要把数据放入renderingbuffer中时才在渲染过程中出现。
一般来说,没有通常“color”意图的结构体或类。
AGG总是对具体的颜色空间进行操作。
这儿包括的颜色空间有很多种,如RGB,HSV,CMYK等。
这些颜色空间通常有特定的限制。
比如,RGB空间就只是人眼可见颜色的一个很小的子集,下图中的三角形区域。
CIE色品图和RGB色域
换句话说,在真实世界中有很多颜色是不能用RGB,CMYK,HSV等颜色空间来描述的。
除了自然中存在的,任何一个其他颜色空间都是受限制的。
因此,为了避免在将来可能出现的限制,没有引入一个如“color”般的对象。
3.坐标单位
AGG主要使用输出设备的坐标。
在屏幕上就是像素。
但是不同于其他一些库和API,AGG支持亚像素精度。
这意味着需要用浮点数描述坐标,因为小数部分的值也将会产生影响。
为了不限制使用者的自由,AGG中没有嵌入从世界坐标转换到屏幕坐标的转换机制。
当不同的应用软件中需要不同的近似方式时,这就显得很重要了。
AGG只是提供了从viewport到设备的变换器。
可以添加自己的简单的类来以毫米、英寸或是其他物理单位为单位进行转换。
评论
评论1
曾计划用AGG做文档编辑软件的图形内核,读过一段时间它的代码:
设计精巧,结构清晰,颇有学术风格,对模板的理念和应用不亚于STL。
然而却感觉这么好的东西,地位却非常尴尬:
同样跨平台的有QT,Cario;
高阶渲染功能未全部实现,已实现的有bug(可能因为未经过大规模应用验证);
可扩展性还不错,前提是读懂大量带模板的代码。
最致命的是纯软件渲染,不能硬件加速;
无三维扩展性,不能用在有三维需要的场合,在vista图形引擎都已经三维化的年代,三维恐怕是未来图形系统的入门级要求了,大型图形应用软件恐怕不敢用它做底层。
所以比较适合做轻量级的图形效果控件,像素操作是GDI的10倍。
从功能上,Cario倒是比较平衡的选择。
但C代码读起挺郁闷不说,扩展也难。
评论2
C++的接口对C++程序员是比较有吸引力的,作为GDI的替代方案,它在速度和质量上确实好很多。
我主要用来做GIS的图形显示,感觉够用了。
就是其中的组件比较零散,学起来比较费劲。
用AGG实现高质量图形输出
使用前AGG的准备工作
下载AGG库,它的家在,目前最高版本是AGG2.5
解压,后面以[AGG]表示AGG的解压目录.
把[AGG]/include加入到include搜索目录中
把[AGG]/src里所有cpp加入到项目中(或者用makefile一起编译)
另外,AGG还有一些其它组件,用到时也要把它们(都是些.h和.cpp文件)加入项目:
如果要用AGG的控件和窗体,要加入[AGG]/src/ctrl/*.cpp和[AGG]/src/platform/<
OS>
/*.cpp,头文件在[AGG]/include/ctrl和[AGG]/include/platform里
如果要用到TrueType字体显示,要加入[AGG]/font_win32_tt目录下的源码和头文件。
利用freetype库,则是[AGG]/font_freetype目录。
如果要用到GenericPolygonClipper库(一个区域剪裁计算库),加入[AGG]/gpc目录下的源码和头文件。
AGG图形显示原理见下图:
其中:
VertexSource
顶点源,里面存放了一堆2D顶点以及对应的命令,如"
MoveTo"
、"
LineTo"
等。
Coordinateconversionpipeline
坐标转换管道,它可以变换VertexSource中的顶点,比如矩阵变换,轮廓提取,转换为虚线等。
ScanlineRasterizer
把顶点数据(矢量数据)转换成一组水平扫描线,扫描线由一组线段(Span)组成,线段(Span)包含了起始位置、长度和覆盖率(可以理解为透明度)信息。
AGG的抗锯齿(Anti-Aliasing)功能也是在这时引入的。
Renderers
渲染器,渲染扫描线(Scanline)中的线段(Span),最简单的就是为Span提供单一颜色,复杂的有多种颜色(如渐变)、使用图像数据、Pattern等。
RenderingBuffer
用于存放像素点阵数据的内存块,这里是最终形成的图像数据。
要理解AGG的工作原理,先看一段代码:
#include
"
agg_basics.h"
agg_rendering_buffer.h"
agg_rasterizer_scanline_aa.h"
agg_scanline_u.h"
agg_renderer_scanline.h"
agg_pixfmt_rgb.h"
platform/agg_platform_support.h"
agg_ellipse.h"
agg_conv_contour.h"
agg_conv_stroke.h"
class
the_application
:
public
agg:
platform_support
{
public:
the_application(agg:
pix_format_e
format,
bool
flip_y)
platform_support(format,
flip_y)
}
virtual
void
on_draw()
//Rendering
Buffer
rendering_buffer
&
rbuf
=
rbuf_window();
pixfmt_bgr24
pixf(rbuf);
//
Renderers
typedef
renderer_base<
pixfmt_bgr24>
renderer_base_type;
renderer_base_type
renb(pixf);
renderer_scanline_aa_solid<
renderer_base_type>
renderer_scanline_type;
renderer_scanline_type
rensl(renb);
Vertex
Source
ellipse
ell(100,100,50,50);
Coordinate
conversion
pipeline
conv_contour<
ellipse>
ell_cc_type;
ell_cc_type
ccell(ell);
conv_stroke<
ell_cc_type>
ell_cc_cs_type;
ell_cc_cs_type
csccell(ccell);
Scanline
Rasterizer
rasterizer_scanline_aa<
>
ras;
scanline_u8
sl;
Draw
renb.clear(agg:
rgba8(255,255,255));
for(int
i=0;
i<
5;
i++)
ccell.width(i*20);
ras.add_path(csccell);
rensl.color(
rgba8(0,0,i*50));
render_scanlines(ras,sl,rensl);
};
int
agg_main(int
argc,
char*
argv[])
app(agg:
pix_format_bgr24,
false);
app.caption("
AGG
Example.
Anti-Aliasing
Demo"
);
if(app.init(600,
400,
window_resize))
return
app.run();
-1;
编译这段代码的方法是(以VC为例):
新建空白GUI项目(就是有WinMain的项目)
把[AGG]/src里所有*.cpp加入到项目中
把[AGG]/src/platform/Win32/*.cpp加入到项目中
Ctrl+C/Ctrl+V上面的代码
编译!
显示效果:
我们先不管agg_main及agg:
platform_support的问题,实际上agg:
platform_support只是AGG给我们方便显示AGG图形用的,真正应用时几乎不会用到(后面会讲到怎样把AGG图形画到HDC上)。
现在我们只需要知道这个框架可以生成一个窗体,当窗体重画时会调用virtualvoidon_draw()就行了。
现在直接从on_draw()开始看
通过rbuf_window()方法得到一个agg:
rendering_buffer,它就是“RenderingBuffer”,是一块用于存放图像的内存块。
通过pixfmt_bgr24包装,我们就可以以像素为单位存取图像。
renderer_base和agg:
renderer_scanline_aa_solid都属于"
渲染器Renderer"
。
renderer_base为底层渲染器,它支撑起所有的高层渲染器。
这里的renderer_scanline_aa_solid就是一个高层渲染器。
ellipse是“顶点源VertexSource”,这个顶点源呈现的是一个圆形。
conv_contour和agg:
conv_stroke作为“坐标转换管道Coordinateconversionpipeline”,conv_contour扩展轮廓线,conv_stroke只显示轮廓线(如果没有conv_stroke就会显示实心圆,可以去掉试试)。
就是“ScanlineRasterizer”啦。
render_scanlines函数执行这个AGG工作流程。
顶点源(VertexSource)
顶点源是一种可以产生多边形所需要的“带命令的顶点”的对象。
比如三角形顶点源,就应该会产生一个带“MoveTo”命令的点,另外二个带"
命令的点和最终闭合的“ClosePoly”命令。
头文件
#include<
agg_path_storage.h>
//path_storage
agg_ellipse.h>
//ellipse
agg_arc.h>
//arc
agg_arrowhead.h>
//arrowhead
agg_curves.h>
//curve3,curve4
agg_gsv_text.h>
//gsv_text,gsv_text_outline
agg_rounded_rect.h>
//rounded_rect
...
类型
自定义类
所有实现了voidrewind(unsignedpath_id);
和unsignedvertex(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颇为特殊,它一般作为线段的标记点,具体用法是这样的:
arrowheadah;
ah.head(d1,d2,d3,d4);
//定义箭头
ah.tail(d1,d2,d3,d4);
//定义箭尾
VertexSourceVS;
//其它顶点源
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- AGG 入门 资料 整理
![提示](https://static.bdocx.com/images/bang_tan.gif)