分享

AGG 渲染缓存(Rendering Buffer)

 lhzstudio 2011-10-15
AGG 渲染缓存(Rendering Buffer)
2010-07-11 21:45

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 & hdc

使用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);

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多