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

posted on 2012-07-24 16:30 Shihira 阅读(4198) 评论(1)  编辑 收藏 引用 所属分类: 图形编程

评论

# re: AGG入门(六) - 练习和细节 2012-07-24 23:02 agg

支持。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

公告

留言簿(2)

随笔分类

搜索

最新随笔

最新评论

阅读排行榜

评论排行榜