您的位置:首页 > 其它

Agg图形库学习笔记-实现任意方向圆角渐变矩形

2012-08-01 23:31 393 查看
直接贴代码了....

View Code

#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgb.h"
#include "agg_gamma_lut.h"
#include "agg_conv_dash.h"
#include "agg_conv_stroke.h"
#include "agg_span_gradient.h"
#include "agg_span_interpolator_linear.h"
#include "agg_span_gouraud_rgba.h"
#include "agg_span_allocator.h"
#include "agg_platform_support.h"
#include "agg_slider_ctrl.h"
#include "agg_cbox_ctrl.h"
#include "agg_rounded_rect.h"

enum flip_y_e { flip_y = true };

typedef agg::gamma_lut<agg::int8u, agg::int8u, 8, 8>        gamma_lut_type;
typedef agg::pixfmt_bgr24                                    pixfmt_type;
typedef pixfmt_type::color_type                             color_type;
typedef agg::renderer_base<pixfmt_type>                     renderer_base_type;
typedef agg::renderer_scanline_aa_solid<renderer_base_type> renderer_scanline_type;
typedef agg::scanline_u8                                    scanline_type;
typedef agg::rasterizer_scanline_aa<>                       rasterizer_type;

// A simple function to form the gradient color array
// consisting of 3 colors, "begin", "middle", "end"
//---------------------------------------------------
template<class ColorArrayT>
void fill_color_array(ColorArrayT& array,
color_type begin,
color_type end)
{
unsigned i;
for(i = 0; i < 256; ++i)
{
array[i] = begin.gradient(end, i / 255.0);
}
}

class the_application : public agg::platform_support
{
double m_x[2];
double m_y[2];
double m_dx;
double m_dy;
int    m_idx;

agg::slider_ctrl<agg::rgba8> m_radius;//圆角半径
agg::slider_ctrl<agg::rgba8> m_offset;//偏移量

agg::slider_ctrl<agg::rgba8> gradientx;//x方向渐变程度
agg::slider_ctrl<agg::rgba8> gradienty;//y方向渐变程度

agg::slider_ctrl<agg::rgba8> leftr;//左边起始点红色分量
agg::slider_ctrl<agg::rgba8> leftg;//左边起始点绿色分量
agg::slider_ctrl<agg::rgba8> leftb;//左边起始点蓝色分量

agg::slider_ctrl<agg::rgba8> rightr;//右边起始点红色分量
agg::slider_ctrl<agg::rgba8> rightg;//右边起始点绿色分量
agg::slider_ctrl<agg::rgba8> rightb;//右边起始点蓝色分量
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_idx(-1),
m_radius(10, 10, 300-10,   19,    !flip_y),
m_offset(10, 10+20, 300-10, 19+20, !flip_y),
gradientx(300, 10, 600-10, 19, !flip_y),
gradienty(300, 10+20, 600-10, 19+20, !flip_y),
leftr(10, 10+40, 300-10, 19+40, !flip_y),
leftg(10, 10+60, 300-10, 19+60, !flip_y),
leftb(10, 10+80, 300-10, 19+80, !flip_y),
rightr(300, 10+40, 600-10, 19+40, !flip_y),
rightg(300, 10+60, 600-10, 19+60, !flip_y),
rightb(300, 10+80, 600-10, 19+80, !flip_y)
{
m_x[0] = 100;   m_y[0] = 200;
m_x[1] = 500;   m_y[1] = 550;
add_ctrl(m_radius);
add_ctrl(m_offset);

add_ctrl(gradientx);
add_ctrl(gradienty);

add_ctrl(leftr);
add_ctrl(leftg);
add_ctrl(leftb);

add_ctrl(rightr);
add_ctrl(rightg);
add_ctrl(rightb);

{
gradientx.label("x=%4.3f");
gradientx.range(-1.0, 1.0);
gradientx.value(0.5);

gradienty.label("y=%4.3f");
gradienty.range(-1.0, 1.0);
gradienty.value(0.5);
}
{
leftr.label("lr=%4.3f");
leftr.range(0.0, 1.0);
leftr.value(0.5);

leftg.label("lg=%4.3f");
leftg.range(0.0, 1.0);
leftg.value(0.5);

leftb.label("lb=%4.3f");
leftb.range(0.0, 1.0);
leftb.value(0.5);
}
{
rightr.label("lr=%4.3f");
rightr.range(0.0, 1.0);
rightr.value(0.5);

rightg.label("lg=%4.3f");
rightg.range(0.0, 1.0);
rightg.value(0.5);

rightb.label("lb=%4.3f");
rightb.range(0.0, 1.0);
rightb.value(0.5);
}
m_radius.label("radius=%4.3f");
m_radius.range(0.0, 50.0);
m_radius.value(25.0);

m_offset.label("subpixel offset=%4.3f");
m_offset.range(-2.0, 3.0);
}

virtual ~the_application()
{
}

virtual void on_init()
{
}

virtual void on_draw()
{
pixfmt_type pixf(rbuf_window());
renderer_base_type ren_base(pixf);
renderer_scanline_type ren_sl(ren_base);
scanline_type sl;
rasterizer_type ras;

ren_base.clear(agg::rgba(0,0,0));

{

agg::renderer_scanline_aa_solid<renderer_base_type>ren(ren_base);
ren.color(agg::rgba8(127,127,127));

agg::ellipse e;
// Render two "control" circles
e.init(m_x[0], m_y[0], 3, 3, 16);
ras.add_path(e);
//agg::render_scanlines_aa_solid(ras, sl, ren_base, agg::rgba8(127, 127, 127));
agg::render_scanlines(ras, sl, ren);
e.init(m_x[1], m_y[1], 3, 3, 16);
ras.add_path(e);
//agg::render_scanlines_aa_solid(ras, sl, ren_base, agg::rgba8(127, 127, 127));
agg::render_scanlines(ras, sl, ren);

}
double d = m_offset.value();

typedef agg::gradient_x gradient_func_type;
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_allocator<color_type> span_allocator_type;
typedef agg::pod_auto_array<color_type, 256> color_array_type;
typedef agg::span_gradient<color_type,
interpolator_type,
gradient_func_type,
color_array_type> span_gradient_type;

typedef agg::renderer_scanline_aa<renderer_base_type,
span_allocator_type,
span_gradient_type> renderer_gradient_type;

gradient_func_type  gradient_func;                   // The gradient function
agg::trans_affine   gradient_mtx;                    // Affine transformer
interpolator_type   span_interpolator(gradient_mtx); // Span interpolator
span_allocator_type span_allocator;                  // Span Allocator
color_array_type    gradient_colors;                 // The gradient colors
span_gradient_type  span_gradient(span_interpolator,
gradient_func,
gradient_colors,
0, 100);

renderer_gradient_type ren_gradient(ren_base, span_allocator, span_gradient);

double x1=m_x[0]+d, y1=m_y[0]+d, x2=m_x[1]+d, y2=m_y[1]+d;

{
//----------------
fill_color_array(gradient_colors,
agg::rgba(leftr.value(),leftg.value(),leftb.value()),
agg::rgba(rightr.value(),rightg.value(),rightb.value()));

{
double gradient_d2 = 100.0;
double dx = (x2 - x1)*gradientx.value();
double dy = (y2 - y1)*gradienty.value();
gradient_mtx.reset();
gradient_mtx *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / gradient_d2);
gradient_mtx *= agg::trans_affine_rotation(atan2(dy, dx));
gradient_mtx *= agg::trans_affine_translation(x1 + 0.5, y1 + 0.5);
gradient_mtx.invert();
}
agg::rounded_rect r(x1, y1, x2, y2, m_radius.value());
r.normalize_radius();
ras.add_path(r);
agg::render_scanlines(ras, sl, ren_gradient);
}
// Reset AA Gamma and render the controls
// Render the controls

agg::render_ctrl(ras, sl, ren_base, m_radius);
agg::render_ctrl(ras, sl, ren_base, m_offset);

agg::render_ctrl(ras, sl, ren_base, gradientx);
agg::render_ctrl(ras, sl, ren_base, gradienty);

agg::render_ctrl(ras, sl, ren_base, leftr);
agg::render_ctrl(ras, sl, ren_base, leftg);
agg::render_ctrl(ras, sl, ren_base, leftb);

agg::render_ctrl(ras, sl, ren_base, rightr);
agg::render_ctrl(ras, sl, ren_base, rightb);
agg::render_ctrl(ras, sl, ren_base, rightg);
}

virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
unsigned i;
for (i = 0; i < 2; i++)
{
if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 5.0)
{
m_dx = x - m_x[i];
m_dy = y - m_y[i];
m_idx = i;
break;
}
}
}
//update_window();
}

virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_idx >= 0)
{
m_x[m_idx] = x - m_dx;
m_y[m_idx] = y - m_dy;
force_redraw();
}
}
else
{
on_mouse_button_up(x, y, flags);
}
}

virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
m_idx = -1;
}
};

int agg_main(int argc, char* argv[])
{
the_application app(agg::pix_format_bgr24, flip_y);
app.caption("AGG Example. Anti-Aliasing Test");

if(app.init(600, 600, agg::window_resize))
{
return app.run();
}
return 1;
}


最终效果



怎么上传源码呢?有谁告诉我么?

欢迎与一起学习agg的朋友共同交流哈,网上资料不多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: