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()方法的最后加上:
- agg::int8u* p = rbuf.row_ptr(20);
- memset(p,0,rbuf.stride_abs());
得到的图形是:
AGG与GDI显示
Rendering Buffer的图像存储方式和Windows的BMP是一样的,所以让AGG处理BMP是很简单的事情,下面的代码演示了怎样在HDC上显示AGG
- #include <agg_rendering_buffer.h>
- #include <agg_pixfmt_rgba.h>
- #include <agg_renderer_base.h>
- #include <agg_rasterizer_scanline_aa.h>
- #include <agg_scanline_p.h>
- ...
-
- 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
- );
-
- HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp);
-
- agg::rendering_buffer rbuf;
-
-
- rbuf.attach((unsigned char*)buf, width, height, -width*4);
-
- agg::pixfmt_bgra32 pixf(rbuf);
- agg::renderer_base<agg::pixfmt_bgra32> renb(pixf);
- renb.clear(agg::rgba8(255, 255, 255, 255));
-
- agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgra32> > ren(renb);
-
- agg::rasterizer_scanline_aa<> ras;
- agg::scanline_p8 sl;
-
- ras.move_to_d(20.7, 34.15);
- ras.line_to_d(398.23, 123.43);
- ras.line_to_d(165.45, 401.87);
-
- ren.color(agg::rgba8(80, 90, 60));
- agg::render_scanlines(ras, sl, ren);
-
-
- ::BitBlt(
- hdc,
- rt.left,
- rt.top,
- width,
- height,
- mem_dc,
- 0,
- 0,
- SRCCOPY
- );
- ::SelectObject(mem_dc, temp);
- ::DeleteObject(bmp);
- ::DeleteObject(mem_dc);
得到的图形是:
使用AGG提供的pixel_map类
如果你觉得上面的方法还是有点烦的话(这个要怪MS的API太麻烦),可以考虑用AGG友情提供的pixel_map类,用它操作 BMP方便多了。(要把[AGG]/src/platform/win32/agg_win32_bmp.cpp加入一起编译)
- #include <agg_rendering_buffer.h>
- #include <agg_pixfmt_rgba.h>
- #include <agg_renderer_base.h>
- #include <agg_rasterizer_scanline_aa.h>
- #include <agg_scanline_p.h>
- #include <platform/win32/agg_win32_bmp.h>
- ...
- CRect rc;
- GetClientRect(&rc);
- agg::pixel_map pm;
- pm.create(rc.right,rc.bottom,agg::org_color32);
-
- agg::rendering_buffer rbuf;
- rbuf.attach(pm.buf(), pm.width(), pm.height(), -pm.stride());
-
- agg::pixfmt_bgra32 pixf(rbuf);
- agg::renderer_base<agg::pixfmt_bgra32> renb(pixf);
- renb.clear(agg::rgba8(255, 255, 255, 255));
-
- agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgra32> > ren(renb);
-
- agg::rasterizer_scanline_aa<> ras;
- agg::scanline_p8 sl;
-
- ras.move_to_d(20.7, 34.15);
- ras.line_to_d(398.23, 123.43);
- ras.line_to_d(165.45, 401.87);
-
- ren.color(agg::rgba8(80, 90, 60));
- agg::render_scanlines(ras, sl, ren);
-
- pm.draw(hdc);
《
待续》
作者:毛毛 来源:www.cppprog.com
|