学到目前为止,已经认识了六个类型:
     - platform_support
- rendering_buffer
- rgba8
- pixfmt_rgb24
- rect_i
- renderer_base
 
现在来做些练习,看看有没有掌握学过的东西,并且灵活运用吧。
一、基本框架
这一节的程序都以这个框架为基础,都是在on_draw中稍微改动的:
#include <agg_pixfmt_rgb.h>
#include <agg_renderer_base.h>
#include <platform/agg_platform_support.h>
class the_application : 
public agg::platform_support
{
public:
    the_application(agg::pix_format_e format, 
bool flip_y) : 
        agg::platform_support(format, flip_y),
        pix_fmt(rbuf_window()),
        ren_bas(pix_fmt) 
//初始化渲染器
    { }
    
    
virtual void on_draw()
    {
         ren_bas.reset_clipping(true);
         ren_bas.clear(agg::rgba8(255, 255, 255));
    }
private:
    agg::pixfmt_rgb24 pix_fmt;
    agg::renderer_base<agg::pixfmt_rgb24> ren_bas;
};
int agg_main(
int argc, 
char* argv[])
{
    the_application app(agg::pix_format_bgr24, 
true);
    app.caption("AGG Test");
    
    
if(app.init(500, 500, agg::window_resize)) {
        
return app.run();
    }
    
return -1;
}
 
二、画线函数
编写如下函数,实现在渲染缓存中画线的功能(无需反锯齿):
    inline void stroke_line(int x1, int y1, int x2, int y2, agg::rgba8& color);
参数:
     - x1, y1, x2, y2分别是两个端点的坐标;
- color是颜色;
 
三、画圆函数
编写如下函数,实现在渲染缓存中画圆的功能(无需反锯齿):
    void stroke_round(int r, int C_x, int C_y, agg::rgba8& color, float step = 0.01)
参数:
     - C_x, C_y 是圆心的坐标;
- color是颜色;
- step是步长,也就是吧圆细分成1/step边形;
     
 
四、答案
     - 画线函数
 inline void stroke_line(int x1, int y1, int x2, int y2, agg::rgba8& color)
 {
 double precision = max(abs(x1 - x2), abs(y1 - y2));
 //精度,也就是画多少个点
 
 for(int i=0; i <= precision; i++)
 ren_bas.copy_pixel( x1 + ( x2 - x1 ) / precision * i, //x
 y1 + ( y2 - y1 ) / precision * i, //y
 color);
 }
 
- 画圆函数
 void stroke_round(int r, int C_x, int C_y, agg::rgba8& color, float step = 0.01)
 {
 int prev_x = int(r * cos(-0.01)) + C_x,
 prev_y = int(r * sin(-0.01)) + C_y; //保存上一个点
 
 int x, y; //保存当前的点
 for(double rad = 0; rad < 2 * PI + step; rad+= step) {
 x = int(r * cos(rad)) + C_x;
 y = int(r * sin(rad)) + C_y; //计算弧度为rad时的坐标
 stroke_line(x, y, prev_x, prev_y, color);
 prev_x = x; prev_y = y;
 }
 }
 
可能有的人会觉得奇怪的是,为什么在画线函数中,不用pix_fmt.copy_pixel()而用ren_bas.copy_pixel()呢?因为,在pix_fmt中,混合器不进行检查,像素拷贝的时候会拷贝到剪裁区域以外,这样会造成很奇怪的情况,以至于如果写到了缓存以外,还会出现异常。注意,剪裁盒功能是基础渲染器级别才提供的,更加底层的操作,比如像素格式混合和直接操作缓存,高层次的渲染器是无从管理的。为了安全起见,建议少碰基础渲染器以下的工具……