基础渲染器Basic Rnderers

摘自:http://www.cnblogs.com/muxue/archive/2010/06/03/1751094.html

学习经验:很多人在接触新的概念的时候,总会有抵触的情绪,并且由于不了解源码的内部结构而无法了解使用。现在进行简单的分析:

裁剪可能是一个模糊的概念,除非了解图形学,简单来说就是指定一个区域,在这个区域内的任何操作都是有效的,超出限制区域所有的操作都是无效的,最基本的一点就是在渲染像素的时候,先判断该像素是否在指定区域内,发现实际上renderer_base调用的还是像素对象的函数进行渲染,像素对象可以是agg::pixfmt_rgb24,这里几乎没有使用到任何的算法,完全是对像素点进行着色,类似用一支有颜色的毛笔对像素点进行描绘,提供了一些画点,画线的函数。

有两种基础渲染器,renderer_base 和 renderer_mclip 它们的功能几乎是一样的。主要使用的是前者(renderer_base),它进行低层次的裁剪处理。通用的裁剪处理(clipping)是一个复杂的任务。在 AGG 中,至少可以有两层的裁剪,底层(像素级)的,和高层的(向量级)。这两个类可以进行像素级别的裁剪,用以防止对缓存区的越界访问。 renderer_mclip 类可以支持多个矩形区域的裁剪区域,但它的性能和裁剪区域的数量有关。

renderer_base 和 renderer_mclip 都是模板类,它们的模板参数就是像素格式渲染器(pixelformat renderer)。

template<class PixelFormat> classrenderer_base

{

public:

typedef PixelFormat pixfmt_type;

typedef typename pixfmt_type::color_type color_type;

.. .

};

Creation

renderer_base(pixfmt_type& ren);

renderer_mclip(pixfmt_type& ren);

两个类的构造函数都可以接受像素格式渲染器(pixel format renderer)对象作为参数。 renderer_mclip 在内部使用renderer_base<PixelFormat> ,用来进行单矩形区域的裁剪。注意,你也可以使用pixfmt_amask_adaptor 作为参数 PixelFormat。

构造的开销是非常小的,它只是初始化各个成员变量。不过,如果你添加新的裁剪区域,那么renderer_mclip 需要申请新的内存,在析构时也会有相应的释放动作。它会用 pod_deque 类来完成内存块的申请,并且它不会(提前)释放不需要的内存,当你重新设置裁剪区域的时候,它会重用原来申请的内存区。 AGG 中广泛使用了这种技术,这可以避免产生过多的内存碎片。

Member Functions

const pixfmt_type& ren() const;

pixfmt_type& ren();

返回指向像素渲染器(pixel format renderer)的引用。

unsigned width()  const;

unsigned height() const;

返回渲染缓存区(rendering buffer)的高和度。

void reset_clipping(bool visibility);

这个函数会重设裁剪区域,如果 visibility 值设置为 true ,那么裁剪区域会被设置为 (0, 0, width()-1, height()-1),如果设置为 false,会设置一个不可见的区域,比如(1,1,0,0)。对于 renderer_mclip 的这个函数来说,它会移除之前添加的所有剪裁区域。

重要!

如果你将另一块内存区附着到 rendering_buffer 上的话(rendering_buffer是连接着这个(basic_renderer),你必须调用一次 reset_clipping() ,否则的话,原来的裁剪区域会变得无效。 因为这个内存改变动作做完之后并不会,rendering buffer 不会给 renderers 任何反馈。也就是说,renderer_base 和 renderer_mclip 对于 rendering buffer 的变动一无所知(译注:renderer_base是用pixel format render来构造的,而pixel format render 又是由 rendering buffer 来支撑,所以它们之间就有这样的关系,具体可见前文)。如果有这样的机制,可以在它们之间传递消息或是使用委托,那么这种机制可能成为 overkill (译注:不知道怎么理解这个overkill)。

bool clip_box(int x1, int y1, int x2, inty2);

这个函数用于设置新的裁剪区域(clipping box)。只有 renderer_base 才有这个函数。裁剪区域包含了边界位置,所以最大的裁剪区域是 (0, 0, width()-1, height()-1) 。裁剪区域在(重新)设置之前,会被设置为最大值。所以,就算你设置新区域的比 (0, 0, width()-1, height()-1) 还要大,也是安全的(译注:因为不会被采用)

void add_clip_box(int x1, int y1, int x2,int y2);

添加一个新的裁剪区域。只有 renderer_mclip 才有这个函数。你可以添加任何个新的矩形区域,但他们之间不能有重叠的部分。如果有重叠的区域的话,有些元素就会被描画两次或两次以上。被添加的新区域会在加入之时被 (0, 0, width()-1, height()-1) 这个区域预先裁剪掉,这主要是有效率上的考量。这也意味着调用 reset_clipping(false)没有任何意义,因为所有被添加的新区域都会用一个不可见区域内先裁剪掉,因此也就不会被添加。(译注:原句如下:t also means that calling reset_clipping(false) for therenderer_mclip doesn‘t make any sense because all adding regions will beclipped by an invisible area and will not be actually added.对这个我不能理解它的意思,后面看了代码再来修正吧)。可见区域包含裁剪区域的边界,也就是说,调用 add_clip_box(100,100,100,100) 会添加一个 1 像素的裁剪区域。

void clip_box_naked(int x1, int y1, int x2,int y2);

只有 renderer_base 有这个函数,它用来给rendering buffer 大小设置一个新的裁剪区域。这个函数不安全,主要是 renderer_mclip 类在使用它,用来在不同的子区域之间快速的切换。这个函数的目的就是为了避免额外的开销。

bool inbox(int x, int y) const;

检查 (x,y) 这个点是不是在裁剪区域内。只有 renderer_base 才有这个函数。

void first_clip_box();

bool next_clip_box();

这两个函数用于枚举渲染器所有的裁剪区域。对于 renderer_base 类来说,它是返回的是空的, next_clip_box() 始终返回 false。

const rect& clip_box() const;

int        xmin()     const;

int        ymin()     const;

int        xmax()     const;

int        ymax()     const;

以一个矩形的形式可是以四个独立的整数值形式返回裁剪区域。 renderer_mclip 的这个函数始终返回 (0, 0, width()-1, height()-1)。

const rect& bounding_clip_box() const;

int        bounding_xmin()     const;

int        bounding_ymin()     const;

int        bounding_xmax()     const;

int        bounding_ymax()     const;

以一个矩形的形式可是以四个独立的整数值形式返回裁剪区域的边界。对于 renderer_base,这个函数返回的值于上面那组函数是一样的。对于 renderer_mclip 来说,它们返回的边界是由所有被添加的矩形合计得出的。

void clear(const color_type& c);

用 c 这个颜色来清除缓存区内的所有区域(不考虑裁剪区域)。

void copy_pixel(int x, int y, constcolor_type& c);

设置一个像素的颜色(考虑裁剪区域clipping)。

void blend_pixel(int x, int y, constcolor_type& c, cover_type cover);

混合描画一个像素。它的行为与 pixel format renderer 的对应函数是一样的。

color_type pixel(int x, int y) const;

获取指定坐标(x,y)的颜色值,如果这个点在裁剪区域外,这个函数返回 color_type::no_color(). 对于 rgba8 来说,就是 (0,0,0,0).

void copy_hline(int x1, int y, int x2,const color_type& c);

void copy_vline(int x, int y1, int y2,const color_type& c);

void blend_hline(int x1, int y, int x2,

const color_type& c,cover_type cover);

void blend_vline(int x, int y1, int y2,

const color_type& c,cover_type cover);

描画(拷贝)或是混合渲染水平或垂直的像素线。行为与 pixel format renders 的相应函数一样。但在这里,使用的是线的起始点和终点坐标,而不是 pixfmt 中的(x, y, length)。

void copy_bar(int x1, int y1, int x2, inty2, const color_type& c);

void blend_bar(int x1, int y1, int x2, inty2,

const color_type& c,cover_type cover);

描画(拷贝)或是混合渲染一个矩形区。

void blend_solid_hspan(int x, int y, intlen,

const color_type& c,const cover_type* covers);

void blend_solid_vspan(int x, int y, intlen,

const color_type& c,const cover_type* covers);

混合渲染一个水平或是垂直的纯色(solid-color)的span。这些在渲染实多边形时会用到。

void blend_color_hspan(int x, int y, intlen,

const color_type*colors, const cover_type* covers);

void blend_color_vspan(int x, int y, intlen,

const color_type*colors, const cover_type* covers);

混合渲染一个水平或是垂直的(? vertical -color)的span。这个函数与不同的 span 生成器一起使用,比如gradients, images, patterns, Gouraud interpolation 等等。函数接受一个颜色数组,颜色的类型必须与正在使用 pixel format 兼容。

void blend_color_hspan_no_clip(int x, inty, int len,

constcolor_type* colors,

const cover_type*covers);

void blend_color_vspan_no_clip(int x, inty, int len,

constcolor_type* colors,

constcover_type* covers);

与上面的函数是一样的,但不考虑裁剪区域。这两个函数用到 scanline renderers 中。分离出这两个函数的原因也是为了效率,scanline 由很多的 spans 组合而成,在进行区域裁剪时,拥有整个 scanline 的信息会比逐个的裁剪每个 span 来得更有效率一些,对于 renderer_mclip 这个类尤其如此。

void copy_from(const rendering_buffer&from,

const rect* rc=0,

int x_to=0,

int y_to=0);

将源缓存区的内容拷入本缓存区中(考虑区域裁剪)。它假设两块缓存区的像素格式是一样的。rc是一个可选项,它指示的是源缓存区内的一个矩形,x_to 、 y_to ————rc->x1, rc->y1 坐标值映射到目标缓存区。

时间: 2024-10-06 17:48:03

基础渲染器Basic Rnderers的相关文章

基于opengl的基础渲染器

一.项目分工 刘星魁:实现所有的功能 二.需求分析 参考主流的渲染引擎,实现基本的摄影机,天空盒,模型,贴图,粒子系统,以及漫游功能 2.软件需求规格说明书 三.原型设计 使用素材: 1.天空盒的上下左右前后图片(bmp格式) 2.测试用的两张图片(png格式) 3.平面和球体模型(obj格式),球体用来表示地球模型,地球贴图(bmp格式) 四.编码规范 由于使用vs2017编写,软件会自动规范格式. 五.代码地址 https://gitee.com/ClothoSword/RasterRend

通过渲染器Shader实现图像变换效果

在上一篇文章中,一起学习了通过设定画笔风格来实现图形变换,没读过的朋友可以点击下面链接: http://www.cnblogs.com/fuly550871915/p/4886455.html 是不是觉得自己学到的知识更多了呢?那么再多学一点总没坏处.在本篇文章中,将会一起学习通过给画笔设定Shader属性,实现图形变换.并带领读者一起实现两个实际例子,图片渲染器和线性渲染器.有没有发现我们的画笔特别强大呢??确实,我们曾经给它设置过颜色矩阵属性,设置过xfermode风格属性,现在又来设定Sh

渲染入门,使用C++编写基本的渲染器

序 一直以来,电影特效和那些炫目.逼真的三维场景令我惊奇且赞叹不已.在具体接触计算机科学以及C++编程语言之前,我并不知道3DMax或者Maya这类软件的背后究竟发生着什么--在一个可交互的窗口中编辑三维场景,然后进入一个叫做"渲染"的神奇过程,神秘而复杂精妙的事情再不为人知的计算机中发生着,然后就能产生处足以以假乱真的图像.尽管在计算机技术相当发达的今天,通过计算机和软件生成图像并不让人感到惊讶,但是作为一个软件工程的学生,这其中的奥秘依然让我深深着迷. 图1    使用本博客所实现

基于OpenGL编写一个简易的2D渲染框架-08 重构渲染器-整体架构

事实上,前面编写的渲染器 Renderer 非常简陋,虽然能够进行一些简单的渲染,但是它并不能满足我们的要求. 当渲染粒子系统时,需要开启混合模式,但渲染其他顶点时却不需要开启混合模式.所以同时渲染粒子系统和其他纹理时会得不到想要的结果,渲染器还存在许多的不足: 1.当渲染许多透明图形时,没有对其进行排序,使得本应透明的图形没有透明. 2.不能对不同的顶点使用不同的状态进行渲染. 渲染器要做的东西很简单,就是 1.传递数据到 GPU 2.设置 OpenGL 状态信息(Alpha测试.模板测试.深

上下文渲染器RequestContext

在render_to_response中加RequestContext会将settings中设置的context_processors返回值收集起来传到模板 return render_to_response('index.html', {...}, context_instance=RequestContext(request)) settings.py TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemp

基于OpenGL编写一个简易的2D渲染框架-11 重构渲染器-Renderer

假如要渲染一个纯色矩形在窗口上,应该怎么做? 先确定顶点的格式,一个顶点应该包含位置信息 vec3 以及颜色信息 vec4,所以顶点的结构体定义可以这样: struct Vertex { Vec3 position; Vec4 color; }; 然后填充矩形四个顶点是数据信息: Vertex* data = ( Vertex* ) malloc(sizeof( Vertex ) * 4); data[0].position.set(0, 0, 0); data[1].position.set(

ZendFramework-2.4 源代码 - 关于MVC - View层 - 视图渲染器、视图插件管理器

<?php // 1. 视图渲染器 class PhpRenderer implements Renderer, TreeRendererInterface { /** * 插件管理器 */ public function getHelperPluginManager() { if (null === $this->__helpers) {// false $this->setHelperPluginManager(new HelperPluginManager()); } return

renderer_base低级渲染器应用的时机

1 前言 该话题是由于讨论整型和浮点型的线宽之间的差异,从而引出的低级渲染器的出现时机,实际上主要是考虑到性能. 2 翻译 实际上,如果需要渲染1个像素宽度的横线或者竖线,通常和像素对齐,就是占满坐标格子)实际上,如果确定不需要使用AGG的任何转换,最好使用低级的渲染器render_base. Actually, if you need to draw horizontal and vertical lines of exactly 1 pixel width, always aligned t

SDL2源代码分析6:复制到渲染器(SDL_RenderCopy())

上一篇文章分析了SDL更新纹理像素数据的函数SDL_UpdateTexture().这篇文章继续分析SDL的源代码.本文分析SDL纹理复制到渲染目标的函数SDL_RenderCopy(). SDL播放视频的代码流程如下所示.初始化:  SDL_Init(): 初始化SDL. SDL_CreateWindow(): 创建窗口(Window). SDL_CreateRenderer(): 基于窗口创建渲染器(Render). SDL_CreateTexture(): 创建纹理(Texture). 循