agg::path_storage函数start_new_path和开销问题

设计理念

path_storage专门为了减少内存碎片而设计出来的。她采用了块分配

(block allocations)的机制而不是重新分配(reallocates)内存。是否意味着

path_storage可能是由多个块内存组成的,没有详细查看源码!!

应用场景

agg::path_storage作为路径存储器,意味着可以存储多个轨迹路径,

而不单单是一条直线。尝试解释,确实很难。除非有深刻的理解和应用。

例如,现在有三组轨迹路径,任何一条轨迹路径都有很多条直线(可以相连

或者离散)或者各种形状的线条组成。我们可以尝试调用start_new_path

来将这三组轨迹路径整合到一个路径存储器中,知道大家是没有时间查看

源码的,可以说agg::path_storage实际上充当了一个STL中vector数组

的功能,会动态的分配内存和必要时进行动态增长,对于嵌入式的设备,

开销很大。作者也说最好是一个单实例。但是问题随之而来,怎么才能够

绘制某一组轨迹路径,比如第二段。start_new_path会返回即将添加组的

顶点编号,当需要渲染这一组轨迹路径的时候,可以通过ras.add_path的

第二个参数传递进去,一般情况下,都是直接使用ras.add_path(path);

比如start_new_path返回值是100,就可以通过这样子调用:

ras.add_path(path, 100);基本的问题就是需要保存每一段轨迹路径的开始

顶点编号。她的优点在于对于固定的轨迹路径组,提供了很好的容器支持。

源码摘录

template<class VC>

unsigned path_base<VC>::start_new_path()

{

if(!is_stop(m_vertices.last_command()))

{

m_vertices.add_vertex(0.0, 0.0, path_cmd_stop);

}

return m_vertices.total_vertices();

}

源码剖析

start_new_path会为当前的路径提供一个停止的标志。当使用vertex函数

遍历到该停止的标志就会终止添加顶点。然后返回下一个路径开始的索引编号。

agg::path_storage作为路径存储器,意味着可以存储多个轨迹路径,而不单单是一条直线

其中提供了函数start_new_path,可以继续加入其他的路径。

例子

不使用:

agg::path_storage ps;

ps.move_to(20,40);

ps.line_to(40,60);

ps.move_to(120,140);

ps.line_to(140,160);

agg::conv_stroke<agg::path_storage> stroke(ps);

ras.add_path(stroke);

采用情况:

agg::path_storage ps;

int path1 = ps.start_new_path();

ps.move_to(20,40);

ps.line_to(40,60);

int path2 = ps.start_new_path();

ps.move_to(120,140);

ps.line_to(140,160);

agg::conv_stroke<agg::path_storage> stroke(ps);

ras.add_path(stroke,path1);//渲染第一组路径

ras.add_path(stroke,path2);//渲染第二组路径

//ras.add_path(stroke);//尝试替换上面的,对比看看

总结

优点:最小的内存开销而且是最快的。

缺点:无法轻易的移除存储器中的中间部分的路径。没有提供任何的方法,你想啊,这些点都是放在一块连续的内存中的,你可以修改,但是怎么移除,难!

进一步的优化:

根据具体的使用场景,如果预先知道顶点的个数,重构存储器再好不过。你需要做的工作就是重构一下path_storage的容器。查看定义:

typedefpath_base<vertex_block_storage<double> > path_storage;

需要替换掉vertex_block_storage.

时间: 2024-09-30 10:37:48

agg::path_storage函数start_new_path和开销问题的相关文章

agg::conv_contour函数auto_detect_orientation作用

正如名称所言:自动检测方向,什么方向,可能很多人不了解,通过AGG邮件了解到几点:扩展轮廓线跟图形的绘制方向有关(也就是move_to,line_to,构成的图形的顺时针,还是逆时针).如下的两个例子,一个是顺时针绘制矩形,一个是逆时针绘制矩形,然后扩展轮廓线. 例子1逆时针 agg::path_storage ps; ps.move_to(395.5,200.5); ps.line_to(295.5,200.5); ps.line_to(295.5,210.5); ps.line_to(395

AGG第三十九课 rasterizer_scanline_aa画线函数疑惑

头文件 #include<agg_rasterizer_scanline_aa.h> 类型 template<class Clip =rasterizer_sl_clip_int> class rasterizer_scanline_aa 成员函数 void add_path(VertexSource&vs,unsigned path_id=0)加入顶点源 void reset() 清空上一次的渲染缓存数据,每次调用add_path函数之前都需要执行该操作 其中也提供了简单

C++性能榨汁机之虚函数的开销

C++性能榨汁机之虚函数的开销 来源  http://irootlee.com/juicer_vtable/ 虚函数的实现 虽然C++标准并没有规定编译器实现虚函数的方式,但是大部分编译器均是采用了虚函数表来实现虚函数,即对于每一个包含虚成员函数的类生成一个虚函数表,一个指向虚函数表的指针被放在对象的首地址(不考虑多继承等复杂情况),虚函数表中存储该类所有的虚函数地址.当使用引用或者指针调用虚函数时,首先通过虚函数表指针找到虚函数表,然后通过偏移量找到虚函数地址并调用.关于虚函数表的更多细节,建

agg::ellipse画圆

前言: path_storage是一个非常重要的顶点容器,并且也提供了很多的形状,在这里,我们看看path_storage是否可以描绘圆形,没有找到任何相关的函数支持直接画圆形,由于项目中并没有使用到任何贝塞尔曲线,所以也并不展开讨论相关的话题.因此引入了其他的顶点源,agg::ellipse去描绘一个圆形.该实例代码并没有引入坐标转换管道,该专业术语将会在一章描述.     //Vertex Source顶点源,我更喜欢称之为端点集合,或者点集合矩阵     //第一个参数是圆形圆心的X坐标,

(转)用AGG实现高质量图形输出(二)

本文上接<用AGG实现高质量图形输出(一)>,分别介绍了AGG显示流程中的各个环节. 上次讲了AGG的显示原理并举了一个简单的例子,这一篇文章开始讲AGG工作流程里的每个环节.为了方便对照,再放一次AGG显示流程 图 另外,上一篇文章里的例程也很重要,后面的例子都将基于这个代码. 下面,我们来考察AGG显示流程中的每个环节.理解每个环节最好的方法是编写实验代码,建议先参照这里建 立一个可以运行的AGG实验环境. 顶点源(Vertex Source) 顶点源是一种可以产生多边形所需要的“带命令的

AGG第十八课 agg::trans_affine仿射变换

1 affine仿射变换概念 在几何上定义为两个向量空间之间的一个仿射变换或者仿射映射(来自拉丁语,affinis,"和...相关")由一个线性变换接上一个平移组成. 2  agg::trans_affine成员函数说明 2.1 缩放 inline const trans_affine&trans_affine::scale(double x, double y) 参数一对x横坐标的缩放系数,参数二对y纵坐标的缩放系数 这里有一个问题:就是图形的缩放之后,并不是在原有的位置上,

AGG第二十一课 agg::conv_contour 扩展轮廓线

1前言 轮廓线就是图形的边界,任何封闭的顶点源跳过agg::conv_stroke阶段,将会描绘实心的图形,填充的颜色和边界保持一致.如果不封闭的顶点源一旦跳过agg::conv_stroke就什么也不绘制.agg::conv_stroke就是用来描绘图形边界的. 和agg::trans_affine对比可知,agg::conv_contour是扩展图形的轮廓线,通俗一点就是拓展图形的边界,对图形的边界进行放缩(但是和agg::trans_affine仿射变换不同,这是中心位置不变的缩放). 2

AGG代码框架以及变量剖析

1源码目录 1)examples 最大的参考价值,作者在AGG库下的example目录中,创建了很多win32的测试用例,创建使用的是VC6.0的工程,目前采用VS2005,可以轻松的进行工程的导入.初学者可以简单的使用.进入agg\examples\win32_api目录,点击example.dsw,允许进行工程的导入,就OK了.接下来会对每一个例子进行详细的应用剖析. 2)font_freetype ?? 3)font_win32_tt ?? 4)gps 多边形集合算法,后面剖析一二!! 5

agg::conv_contour无法应用于自交的封闭图形

测试代码: void DrawIntersectContour() { agg::rendering_buffer &rbuf = rbuf_window(); agg::pixfmt_bgr24 pixf(rbuf); typedef agg::renderer_base<agg::pixfmt_bgr24> renderer_base_type; renderer_base_type renb(pixf); typedef agg::renderer_scanline_aa_sol