AGG 渲染缓存(Rendering Buffer)

Rendering Buffer

Rendering Buffer是一个内存块,用于保存图像数据。这是AGG与显示器之间的桥梁,我们要显示AGG图形实际上就是识别这个内存块并使用系统的API显示出来 而已(实际上几乎不需要做转换工作,因为无论是Windows还是Linux,API所用的图像存储格式与Rendering Buffer都是兼容的)。

头文件:
#include "agg_rendering_buffer.h"
类型:
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)返回指向第y行起点的指针
void clear(int8u value)以value值填充整个内存块
template<class RenBuf> void copy_from(const RenBuf& src)从另一rendering_buffer中复制数据
实验代码(基于此处代码)

在on_draw()方法的最后加上:

  1. agg::int8u* p = rbuf.row_ptr(20);//得到第20行指针
  2. memset(p,0,rbuf.stride_abs());//整行以0填充
得到的图形是:

AGG与GDI显示

Rendering Buffer的图像存储方式和Windows的BMP是一样的,所以让AGG处理BMP是很简单的事情,下面的代码演示了怎样在HDC上显示AGG

  1. #include <agg_rendering_buffer.h>
  2. #include <agg_pixfmt_rgba.h>
  3. #include <agg_renderer_base.h>
  4. #include <agg_rasterizer_scanline_aa.h>
  5. #include <agg_scanline_p.h>
  6. ...
  7. // 首先让系统生成一个32位的bmp缓存
  8. BITMAPINFO bmp_info;
  9. bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  10. bmp_info.bmiHeader.biWidth = width;
  11. bmp_info.bmiHeader.biHeight = height;
  12. bmp_info.bmiHeader.biPlanes = 1;
  13. bmp_info.bmiHeader.biBitCount = 32;
  14. bmp_info.bmiHeader.biCompression = BI_RGB;
  15. bmp_info.bmiHeader.biSizeImage = 0;
  16. bmp_info.bmiHeader.biXPelsPerMeter = 0;
  17. bmp_info.bmiHeader.biYPelsPerMeter = 0;
  18. bmp_info.bmiHeader.biClrUsed = 0;
  19. bmp_info.bmiHeader.biClrImportant = 0;
  20. HDC mem_dc = ::CreateCompatibleDC(hdc);
  21. void* buf = 0;
  22. HBITMAP bmp = ::CreateDIBSection(
  23.      mem_dc,
  24.      &bmp_info,
  25.      DIB_RGB_COLORS,
  26.      &buf,
  27.      0,
  28.      0
  29.      );
  30. // 把bmp与mem_dc关联,这样AGG就可以和原生GDI一起工作了
  31. HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp);
  32. //============================================================
  33. // 以下是AGG代码
  34. agg::rendering_buffer rbuf;
  35. // 32位位图,每行字节数为width*4。
  36. // BMP是上下倒置的,为了和GDI习惯相同,最后一个参数是负值。
  37. rbuf.attach((unsigned char*)buf, width, height, -width*4);
  38. // 像素格式和renderer_base
  39. agg::pixfmt_bgra32 pixf(rbuf);
  40. agg::renderer_base<agg::pixfmt_bgra32> renb(pixf);
  41. renb.clear(agg::rgba8(255, 255, 255, 255));
  42. // Scanline renderer
  43. agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgra32> > ren(renb);
  44. // Rasterizer & scanline
  45. agg::rasterizer_scanline_aa<> ras;
  46. agg::scanline_p8 sl;
  47. // 多义线(三角形)
  48. ras.move_to_d(20.7, 34.15);
  49. ras.line_to_d(398.23, 123.43);
  50. ras.line_to_d(165.45, 401.87);
  51. // 设置颜色后渲染
  52. ren.color(agg::rgba8(80, 90, 60));
  53. agg::render_scanlines(ras, sl, ren);
  54. //============================================================
  55. // 把bmp显示到hdc上,如果图片中有Alpha通道,可以使用AlphaBlend代替BitBlt。
  56. ::BitBlt(
  57.      hdc,
  58.      rt.left,
  59.      rt.top,
  60.      width,
  61.      height,
  62.      mem_dc,
  63.      0,
  64.      0,
  65.      SRCCOPY
  66.      );
  67. // 释放资源
  68. ::SelectObject(mem_dc, temp);
  69. ::DeleteObject(bmp);
  70. ::DeleteObject(mem_dc);
得到的图形是:

使用AGG提供的pixel_map类

如果你觉得上面的方法还是有点烦的话(这个要怪MS的API太麻烦),可以考虑用AGG友情提供的pixel_map类,用它操作 BMP方便多了。(要把[AGG]/src/platform/win32/agg_win32_bmp.cpp加入一起编译)

  1. #include <agg_rendering_buffer.h>
  2. #include <agg_pixfmt_rgba.h>
  3. #include <agg_renderer_base.h>
  4. #include <agg_rasterizer_scanline_aa.h>
  5. #include <agg_scanline_p.h>
  6. #include <platform/win32/agg_win32_bmp.h>
  7. ...
  8. CRect rc;
  9. GetClientRect(&rc);
  10. agg::pixel_map pm;
  11. pm.create(rc.right,rc.bottom,agg::org_color32);
  12. //============================================================
  13. // 以下是AGG代码
  14. agg::rendering_buffer rbuf;
  15. rbuf.attach(pm.buf(), pm.width(), pm.height(), -pm.stride());
  16. // 像素格式和renderer_base
  17. agg::pixfmt_bgra32 pixf(rbuf);
  18. agg::renderer_base<agg::pixfmt_bgra32> renb(pixf);
  19. renb.clear(agg::rgba8(255, 255, 255, 255));
  20. // Scanline renderer
  21. agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgra32> > ren(renb);
  22. // Rasterizer & scanline
  23. agg::rasterizer_scanline_aa<> ras;
  24. agg::scanline_p8 sl;
  25. // 多义线(三角形)
  26. ras.move_to_d(20.7, 34.15);
  27. ras.line_to_d(398.23, 123.43);
  28. ras.line_to_d(165.45, 401.87);
  29. // 设置颜色后渲染
  30. ren.color(agg::rgba8(80, 90, 60));
  31. agg::render_scanlines(ras, sl, ren);
  32. //============================================================
  33. pm.draw(hdc);
待续

 

作者:毛毛 来源:www.cppprog.com

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值