Agg学习笔记
很久前就听一大牛说起Agg,据说是一个架构极度牛B的2D引擎,沉寂了许久,最后花了两周时间走马观花地把它过了一遍。果然如那大牛所言,这家伙简直就是巧夺天工的艺术品。今天稍稍瞄了一下Google扔出来的,也宣称极度牛B的2D引擎Skia,不过个人感觉整体架构大不如Agg漂亮。至于两者的性能,没做过比较,只是听说skia性能表现优异。
在啃这块骨头之前,有两点建议:
稍了解一点2D计算机图形学的知识。这一点在学习Agg的过程中至关重要。
至少尝试使用过一种UI框架,诸如Wtl、Mfc等。
很多人曾说Agg将C++模板用到了炉火纯青的地步,不过就我现在的认知,发现其用法也就正规正矩而已,没用像Boost那样到处是奇技淫巧,让人眼花缭乱,找不到北。也许我功底还不行,无法体会高人的用意。
学习代码最好的办法莫过于编译,看运行效果。下载源码见这里【http://www.antigrain.com/download/index.html】。Agg源码包中并没有对Virtual Studio的直接支持,不过建一个Project,然后将文件拖到里面编译即可(为了保证可移植性,Agg对标准的支持还是很得力的)。在源码包中的examples目录有很多sample,可以另建Project编译运行看效果。如果想偷懒,可以去这里【http://www.antigrain.com/demo/index.html 】下载编译好的可执行文件先睹为快。我围观了下,效果很“炫”。
对于开源的东西,找学习资料总是值得先去官网瞄瞄。Agg官网的Reference 不多,不过强烈建议看下这里【http://www.antigrain.com/doc/index.html 】。如果不喜欢看E文,国内有人翻译(感谢之),质量还不错,见这里【http://www.cnblogs.com/liyiwen/category/248229.html 】。认真看完第一篇【Basic Renderers】很重要,这篇文章对Agg的底层架构做了清晰的讲述,包括RenderBuffer和底层Render,以及两者的职责分离。这种设计相当好,因为RenderBuffer并不应该知道上层使用何种颜色模式。
为了对Agg有一个总体的了解(非技术层次),可以参考这里【http://www.cnblogs.com/Kane_zzt/archive/2009/02/15/1271793.html 】。下面这张图是Agg总体框架的一个总体表述
![]()
最后一项Screen Output可以不理会,那是OS的事。Agg处理的最底层是Rendering Buffer 。说白了Rendering Buffer就是一块内存块,类似Bitmap。当然这也不一定,它也可以是通过OS API获得窗口屏幕的映射地址(Windows下可以通过GDI函数获得),或者是FrameBuffer,这样整个屏幕就可以任意虐,如果没猜错的话,Android这鸟毛就这么干的。
在讲Renderers之前,有必要区分两个概念,图形和图像。简单地讲,图形就是一些点线组成的形状,可以通过LineTo和MoveTo原语构造。而图像一般包含形状和具体的颜色信息。而Readerers【渲染器】就是将图形信息渲染成图像。
渲染器层实际上包含三层:
颜色模式(例如RGBA)相关的底层渲染层,这一层直接跟Rendering Buffer日。在这一层,每一个像素的大小、颜色的表示被确定。
Basic Render层,这一层在底层的基础上进行简单的裁剪支持。包括单裁剪和多区域裁剪。多区域裁剪性能和区域数量相关。
应用渲染层,这一层负责渲染具体的线段。在后面会讲到,在Agg中任何一个多边形在光栅化后都会分解成一条条水平线(span),然后依次渲染。
Scanline Rasterizer就是将任意多边形(顶点源)分解成水平线,然后交给顶层渲染器渲染。在这一层也可以进行适当的裁剪。反锯齿功能在这一层引入,Agg中的像素存储使用浮点型,小数部分即传说中的亚像素。
Coordinate conversion pipeline对顶点源进行坐标转换,我们熟悉的操作如放大/缩小、旋转等操作都在这一层完成,这部分代码对数学基础和算法要求较高,我直接死不鸟跳过。在反走样插值功能在这一层引入。
Vertex Source提供光栅化的多边形,它通过一个迭代器来传递顶点。顶点源包括普通的图形,例如矩形、椭圆、三角形,也包括字体等复杂多边形。在Linux下被广泛应用的Freetype库就是根据字符编码、其他字符参数来生成一个字体多边形。这在Agg中也被支持。
前面提到的都是一些很简单的矢量绘图操作,那么Agg对贴图、渐变色和字体引擎的支持怎么样呢?
关于Agg对贴图的支持,默认包含对bmp格式的支持,Agg源码内置了对bmp图片格式的解码代码,不过默认并不支持png和jpg等流行格式。我想作者可能是为了保持简单,不想引入libpng和libjpeg。Agg对所有图片格式除了解码部分外,处理是一致的。
前面一直讲到渲染,那何谓渲染呢,说白了就是将一个像素用颜色填充(或混合Blend)。而前面一直忽略了一个问题,就是渲染时用什么颜色来填充(准确的讲,并不是填充,而是混合(Blend))特定的像素呢?在Agg中其实也包含一个虚拟的“颜色源”,这个颜色源中的每一个点和“顶点源“中的点一一对应。可以有多种方式构造这个虚拟的颜色源,首先可以指定一种颜色,即纯色填充,其次可以通过一定算法来生成”渐变“效果,当然也可以从图片中获取。
说到图片,其实任何格式在处理前都必须转化成bitmap格式,所谓的libpng和libjpeg就是干这个事。而bitmap说到底就是一个矩形颜色源。也许有人会疑惑,某些图片不是支持不规则形状么,例如png图片格式。其实png并不支持不规则形状,而是支持Alpha通道。而2D引擎在渲染时通过Alpha Blend后某些地方就成了透明色,用户看起来就是不规则形状了。
说到这里,Agg对贴图的支持就很简单了,从贴图资源中获得颜色源,然后使用它渲染特定多边形(裁剪在这个多边形中完成)。而对图片的放大/缩小、旋转等过程类似Coordinate conversion pipeline对顶点源的操作。
Agg对渐变的支持和贴图一致。
Agg内置对英文字符的支持,我没有仔细研究源码,不过可以推测它将所有英文字符的路径存储在一个全局(静态)变量中,渲染前直接通过这些路径生成顶点,因而效率极高。不过这种方式有几个不足:
不支持未存储的字符,很显然不要靠他来支持”我日“。
不支持字体,因为字体路径表述都是写死的,除非修改源代码。
更高级的字体支持来自字体引擎,Agg支持Windows Gdi的字体接口,也可以使用第三方的字体引擎,例如Freetype。Agg可以通过字体引擎提供的字模来包装一个顶点源,因而可以将字体渲染成任意效果。此外Agg也可以对字体引擎进一步封装,实现一个类似贴图的接口,然后渲染多边形,不过个人觉得这种方式很别扭,而且渲染时不太灵活。暂时没有测试两种方式的效率差别。
最后,因本人水平有限,错误之处在所难免,欢迎指正。
Agg学习笔记的更多相关文章
- 23 DesignPatterns学习笔记:C++语言实现 --- 2.4 Composite
23 DesignPatterns学习笔记:C++语言实现 --- 2.4 Composite 2016-07-22 (www.cnblogs.com/icmzn) 模式理解
- 23 DesignPatterns学习笔记:C++语言实现 --- 1.3 Singletion
23 DesignPatterns学习笔记:C++语言实现 --- 1.3 Singletion 2016-07-21 (www.cnblogs.com/icmzn) 模式理解
- Flink学习笔记:Flink Runtime
本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKhaz ...
- flink学习笔记-各种Time
说明:本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKh ...
- Elasticsearch7.6学习笔记1 Getting start with Elasticsearch
Elasticsearch7.6学习笔记1 Getting start with Elasticsearch 前言 权威指南中文只有2.x, 但现在es已经到7.6. 就安装最新的来学下. 安装 这里 ...
- hive学习笔记之十:用户自定义聚合函数(UDAF)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<hive学习笔记>的第十 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- PHP-会员登录与注册例子解析-学习笔记
1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...
随机推荐
- xcode 不值钱的动画UIImageView
了解 animateWithDuration方法 制作动画变得不值钱 代码创建一个UIImageView 后加入self.view 容器中 调用点击屏幕touchesBegan 方法执行动画 #imp ...
- 在 win 10 中使用sql 2012 附加低版本数据失败的解决办法。
随着win 10 的发布,我也尝试把自己的笔记本升级下,体验win10,由于自己电脑好长时间没有管理过,东西比较乱,一激动就格式了硬盘.但是所有的资料都丢失了,不过我都提前备份到网盘上.好了,废话不多 ...
- Jquery 遍历数组之grep()方法介绍
grep()方法用于数组元素过滤筛选. grep(array,callback,boolean);方法参数介绍. array ---待处理数组 callback ---这个回调函数用来处理数组中 ...
- MSSQL2005 修改数据库的排序规则
1.修改数据库排序规则ALTER DATABASE [DataBaseName] COLLATE Chinese_PRC_CI_AS ; 2.修改表中列的排序规则 如果下列其中之一当前正在引用一个列, ...
- load_library(linker.cpp:759): library "libmaliinstr.so" not found
1.02-07 15:19:09.277: E/linker(16043): load_library(linker.cpp:759): library "libmaliinstr.so&q ...
- w2wp.exe 已附加有调试器,但没有将该调试器配置为调试此未经处理的异常
一.问题描述 昨天系统联调,用到了VS2010 附件进程,把w2wp.exe 进程添加到vs2010 的调试进程中,这样其他系统访问我们系统,就可以捕获断点进行调试 但是,今天F5 调试的时候,发现直 ...
- mysql 组合索引
MySQL单列索引是我们使用MySQL数据库中经常会见到的,MySQL单列索引和组合索引的区别可能有很多人还不是十分的了解,下面就为您分析两者的主要区别,供您参考学习. 为了形象地对比两者,再建一个表 ...
- ftpclient卡死问题
ftpclient在调用retrieveFileStream(String remote)之后,返回inputstream,如果不想关闭ftp,继续读取其他文件. 一定要先关闭inputstream, ...
- Latex调整行距
修改行间距的方法: \usepackage{setspace}%使用间距宏包 \begin{document} \begin{spacing}{2.0}%%行间距变为double-space 双倍行距 ...
- Delphi的MDI编程中遇到的一个奇怪问题(值得研究的一个问题)
近日在用delphi写一个多文档应用程序,除了一个主界面是自动生成的,其他功能页面全部都是通过Application.CreateForm()动态生成的,也就是说在ProjectManager中点击程 ...