IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    Shihira发表于 2012-07-24 08:30:00
    love 0
    学到目前为止,已经认识了六个类型:
    • platform_support
    • rendering_buffer
    • rgba8
    • pixfmt_rgb24
    • rect_i
    • renderer_base
    现在来做些练习,看看有没有掌握学过的东西,并且灵活运用吧。

    一、基本框架

    这一节的程序都以这个框架为基础,都是在on_draw中稍微改动的:
    #include
    #include
    #include agg_platform_support.h><br >
    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 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中,混合器不进行检查,像素拷贝的时候会拷贝到剪裁区域以外,这样会造成很奇怪的情况,以至于如果写到了缓存以外,还会出现异常。注意,剪裁盒功能是基础渲染器级别才提供的,更加底层的操作,比如像素格式混合和直接操作缓存,高层次的渲染器是无从管理的。为了安全起见,建议少碰基础渲染器以下的工具……



    Shihira 2012-07-24 16:30 发表评论


沪ICP备19023445号-2号
友情链接