摘要:agg是一个非常优秀的开源矢量图形库,还有一个类似的库是Cairo。与Cairo相比,Agg的效率更高,网上有人做了一个比喻,Agg是一堆进口车零件,而Cairo是一辆完整的国产车。
这意味着Agg使用Agg需要我们自己对其进行封装,它提供从最原始的显存操作到最终的反走样操作的类的封装,只要细心研究它的文档,还是比较容易上手的。当然对图形渲染的流水线有个认识,能够更好的理解图形库,好了废话不多说,下面进入正题。
我们选择在Windows Vs2005下开发扫雷程序,窗口系统选择SDL,SDL是一款非常优秀的多媒体工具库,适用于各种嵌入式程序,并且是跨平台的。
1、首先新建一个vs2005的Win32工程。 配置Agg库,把agg 库源码放进工程,在工具 –>选项->项目和解决方案里面将包含目录 及 源码项分别增加一项 具体的值就是我们的当前的agg目录。
配置SDL将SDL将两个lib文件放入microsoft visual stdio8里面的vc目录的lib目录,
在include目录下建个sdl目录, 将头文件放进去 在工具->选项->项目解决方案 ,将此目录包含在内。
在 项目 –>项目属性(最下面一个)里面 链接器 输入里面增加对lib的引用
最后将sdl的dll文件放入system32目录下。
至此环境配置完毕。
2、封装一个渲染引擎,以便我们能够实现画东西,我们封装一个render_handler类,核心代码如下:

Code
1
class render_handler
{
2
public:
3
void init_buffer(const int& w, const int& h, unsigned char*& buffer)
4
{
5
buffer = new unsigned char [w * h * 4];
6
7
rbuf.attach(buffer, w, h, w * 4);
8
pixfmt.attach(rbuf);
9
renb.attach(pixfmt);
10
ren.attach(renb);
11
12
renb.clear(agg::rgba8(255, 255, 255, 255));
13
//the same as : memset(buffer, 255, w * h * 4);
14
}
15
16
void render_cell(cell& cl)
17
{
18
ren.color(cl.m_color);
19
ras.add_path(cl.m_path);
20
agg::render_scanlines(ras, sl, ren);
21
}
22
23
void init_scene(const int w_num, const int h_num)
24
{
25
26
//some init code
27
28
}
29
30
public:
31
agg::rendering_buffer rbuf;
32
agg::pixfmt_rgba32 pixfmt;
33
agg::renderer_base<agg::pixfmt_rgba32> renb;
34
agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_rgba32> > ren;
35
agg::scanline_p8 sl;
36
agg::rasterizer_scanline_aa<> ras;
37
};
38
39
40
其中的cell类实现了每一个小格子的相关属性信息及实现,

Code
1
class cell
2
{
3
public:
4
cell(int x, int y) : m_x(x), m_y(y)
5
{
6
m_width = cell_width;
7
m_height = cell_height;
8
m_checked = false;
9
m_is_bomb = false;
10
11
}
12
13
cell(int x, int y, int w, int h) : m_x(x), m_y(y), m_width(w), m_height(h)
14
{
15
m_checked = false;
16
m_is_bomb = false;
17
}
18
19
void Draw_Cell(agg::rgba8 color)
20
{
21
m_path.move_to(m_x * cell_width, m_y * cell_height);
22
m_path.line_to(m_x * cell_width , m_y * cell_height + m_height);
23
m_path.line_to(m_x * cell_width + cell_width, m_y * cell_height + m_height);
24
m_path.line_to(m_x * cell_width + m_width, m_y * cell_height);
25
m_color = color;
26
}
27
28
void Cell_On()
29
{
30
31
}
32
33
public:
34
int m_x;
35
int m_y;
36
int m_width;
37
int m_height;
38
bool m_checked;
39
bool m_is_bomb;
40
agg::rgba8 m_color;
41
agg::path_storage m_path;
42
};
以上两个类分别实现了对agg图形库的封装操作,以及缓冲区的绑定,还有一个函数用来初始化SDL,主要代码如下:

Code
1
namespace render_engin
{
2
3
bool initSDL(render_engin::render_handler& rh, SDL_Surface*& screen, SDL_Surface*& surface, unsigned char*& buff, int screen_width, int screen_height )
4

{
5
rh.init_buffer(render_engin::width, render_engin::height, buff);
6
7
int stride = screen_width * (SDL_GetVideoInfo()->vfmt->BytesPerPixel);
8
screen = SDL_SetVideoMode(screen_width, screen_height, 32, SDL_SWSURFACE|SDL_ANYFORMAT);
9
surface = SDL_CreateRGBSurfaceFrom((void* )buff, screen_width, screen_height, SDL_GetVideoInfo()->vfmt->BitsPerPixel, stride, 0x00, 0x00, 0x00, 0xff<<24);
10
11
SDL_WM_SetCaption("Agg_Bomb Game", NULL);
12
13
14
if( SDL_BlitSurface(surface, NULL, screen, NULL) < 0)
15
return false;
16
SDL_UpdateRect(screen, 0, 0, 0, 0);
17
18
return true;
19
20
}
21
22
};
程序的逻辑比较简单,就是有点麻烦,因为天色已晚,剩下的部分留作下一篇再介绍,今天先发个扫雷的界面截图上来,
