x, int y, int len,
const color_type* colors, const cover_type* covers);
void copy_from(const rendering_buffer& from,
const rect* rc=0, int x_to=0, int y_to=0); 实验代码(基于此 处代码)
在on_draw()方法的renb.clear(agg::rgba8(255,255,255));语句后面加上: ? renb.clear(agg::rgba8(255,255,255));
? renb.clip_box(30,30,160,160); // 设置可写区域
得到的图形是:
从from复制一个矩形区域过来,rc指定源区域,x_to,y_to指定目标位置
PixelFormat Renderer
PixelFormat Renderer的作用是以指定的颜色空间来包装原始的Rendering Buffer(见后文),AGG把它归类于底层Renderer。
Rendering Buffer是以字节为单位的,而PixelFormat Renderer则是以像素为单位的。 头文件
#include \#include \ 类型
pixfmt_gray8 pixfmt_rgb24 pixfmt_bgr24 pixfmt_rgba32
pixfmt_bgr24_gamma ... 构造函数
pixfmt_base(rbuf_type& rb);
rb参数为Rendering Buffer类型 类型定义
像素类型
typedef color_type;
需要了解的是在AGG中像素也是一个功能完善的类,常用的有rgba、rgba8、gray8。
rgba里每个颜色分量用double表示,范围从0~1。其它像素类后面的数字代表每个颜色分量占用的位数。大部分像素类都可以从rgba构造。 同时, 像素类还有gradient等牛X的颜色计算方法。
typedef value_type; typedef order_type; 成员方法 unsigned width() unsigned height()
宽高
单个颜色分量的类型
颜色排序方式,我们可以通过里面的枚举值R G B A得到各颜色分量所在位置,常用的有order_rgb,order_bgr,order_rgba。
这是order_rgb的定义: struct order_rgb { enum rgb_e { R=0, G=1, B=2, rgb_tag }; };
color_type pixel(int x, int y);
void copy_pixel(int x, int y, const 取得、设置指定点的颜色
color_type& c);
与原颜色有混合效果,强度由covervoid blend_pixel(int x, int y, const 设置指定点颜色,
指定 color_type& c, int8u cover);
void copy_hline(int x, int y, unsigned
从x,y开始画一条长度为len的线,颜色为c,同样len, const color_type& c);
void copy_vline(int x, int y, unsigned 有blend_版本 len, const color_type& c);
void blend_solid_h(v)span(int x, int y, unsigned len,
const
类似hline和vline版本,color版指定一组颜色,依
color_type& c, const int8u* covers);
次着色。covers指定覆盖率
void blend_color_h(v)span(int x, int y, unsigned len,
const
color_type* colors, const int8u* covers); 实验代码(基于此 处代码)
在on_draw()方法的最后加上:
? //从50,20开始,画20条长度为100的坚线,颜色从黑渐变到红,覆盖率为128(半透明) ? for(int i=0; i<20; i++)
? pixf.blend_vline(50+i,20,100,agg::rgba(i/20.0,0,0),128);
得到的图形是:
Rendering Buffer
Rendering Buffer是一个内存块,用于保存图像数据。这是AGG与显示器之间的桥梁,我们要显示AGG图形实际上就是识别这个内存块并使用系统的API显示出来 而已(实际上几乎不需要做转换工作,因为无论是Windows还是Linux,API所用的图像存储格式与Rendering Buffer都是兼容的)。 头文件:
#include \ 类型: rendering_buffer 构造函数:
rendering_buffer(int8u* buf, unsigned width, unsigned height, int stride);
参数分别表示内存块指针,宽、高、每行的步幅(当步幅<0时,表示上下颠倒) 成员方法:
void attach(int8u* buf, unsigned width, unsigned height, int stride);
int8u* buf();
unsigned width() const; unsigned height() const; int stride() const;
unsigned stride_abs() const; int8u* row_ptr(int y) void clear(int8u value)
template
实验代码(基于此处代码)
在on_draw()方法的最后加上:
? agg::int8u* p = rbuf.row_ptr(20);//得到第20行指针 ? memset(p,0,rbuf.stride_abs());//整行以0填充
得到的图形是:
参数与构造函数相同 返回内存块指针
返回宽、高、每行步幅
返回指向第y行起点的指针 以value值填充整个内存块
从另一rendering_buffer中复制数据
AGG与GDI显示
Rendering Buffer的图像存储方式和Windows的BMP是一样的,所以让AGG处理BMP是很简单的事情,下面的代码演示了怎样在HDC上显示AGG
? #include
#include
#include
? ...
? // 首先让系统生成一个32位的bmp缓存 ?? ?? ?? ??
BITMAPINFO bmp_info;
bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmp_info.bmiHeader.biWidth = width; bmp_info.bmiHeader.biHeight = height;
?? bmp_info.bmiHeader.biPlanes = 1; ?? bmp_info.bmiHeader.biBitCount = 32;
?? bmp_info.bmiHeader.biCompression = BI_RGB; ?? bmp_info.bmiHeader.biSizeImage = 0; ?? bmp_info.bmiHeader.biXPelsPerMeter = 0; ?? bmp_info.bmiHeader.biYPelsPerMeter = 0; ?? bmp_info.bmiHeader.biClrUsed = 0; ?? bmp_info.bmiHeader.biClrImportant = 0; ??
?? HDC mem_dc = ::CreateCompatibleDC(hdc); ??
?? void* buf = 0; ??
?? HBITMAP bmp = ::CreateDIBSection( ?? mem_dc, ?? &bmp_info, ?? ?? ?? ??
DIB_RGB_COLORS, &buf, 0, 0
?? ); ??
?? // 把bmp与mem_dc关联,这样AGG就可以和原生GDI一起工作了 ?? HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp); ??
?? //============================================================ ?? // 以下是AGG代码
?? agg::rendering_buffer rbuf;
?? // 32位位图,每行字节数为width*4。
?? // BMP是上下倒置的,为了和GDI习惯相同,最后一个参数是负值。 ?? rbuf.attach((unsigned char*)buf, width, height, -width*4); ??
?? // 像素格式和renderer_base ?? agg::pixfmt_bgra32 pixf(rbuf);
?? agg::renderer_base
?? renb.clear(agg::rgba8(255, 255, 255, 255)); ??
?? // Scanline renderer