AGG入门(六) - 练习和细节

AGG入门(六) - 练习和细节

学到目前为止,已经认识了六个类型:
  • 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中,混合器不进行检查,像素拷贝的时候会拷贝到剪裁区域以外,这样会造成很奇怪的情况,以至于如果写到了缓存以外,还会出现异常。注意,剪裁盒功能是基础渲染器级别才提供的,更加底层的操作,比如像素格式混合和直接操作缓存,高层次的渲染器是无从管理的。为了安全起见,建议少碰基础渲染器以下的工具……

你可能感兴趣的:(AGG入门(六) - 练习和细节)