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

 直接贴代码了....

 

View Code
  1 #include <stdio.h>
  2 #include "agg_basics.h"
  3 #include "agg_rendering_buffer.h"
  4 #include "agg_rasterizer_scanline_aa.h"
  5 #include "agg_scanline_u.h"
  6 #include "agg_renderer_scanline.h"
  7 #include "agg_pixfmt_rgb.h"
  8 #include "agg_gamma_lut.h"
  9 #include "agg_conv_dash.h"
 10 #include "agg_conv_stroke.h"
 11 #include "agg_span_gradient.h"
 12 #include "agg_span_interpolator_linear.h"
 13 #include "agg_span_gouraud_rgba.h"
 14 #include "agg_span_allocator.h"
 15 #include "agg_platform_support.h"
 16 #include "agg_slider_ctrl.h"
 17 #include "agg_cbox_ctrl.h"
 18 #include "agg_rounded_rect.h"
 19 
 20 enum flip_y_e { flip_y = true };
 21 
 22 
 23 typedef agg::gamma_lut<agg::int8u, agg::int8u, 8, 8>        gamma_lut_type;
 24 typedef agg::pixfmt_bgr24                                    pixfmt_type;
 25 typedef pixfmt_type::color_type                             color_type;
 26 typedef agg::renderer_base<pixfmt_type>                     renderer_base_type;
 27 typedef agg::renderer_scanline_aa_solid<renderer_base_type> renderer_scanline_type;
 28 typedef agg::scanline_u8                                    scanline_type;
 29 typedef agg::rasterizer_scanline_aa<>                       rasterizer_type;
 30 
 31 
 32 // A simple function to form the gradient color array 
 33 // consisting of 3 colors, "begin", "middle", "end"
 34 //---------------------------------------------------
 35 template<class ColorArrayT>
 36 void fill_color_array(ColorArrayT& array, 
 37                       color_type begin, 
 38                       color_type end)
 39 {
 40     unsigned i;
 41     for(i = 0; i < 256; ++i)
 42     {
 43         array[i] = begin.gradient(end, i / 255.0);
 44     }
 45 }
 46 
 47 
 48 class the_application : public agg::platform_support
 49 {
 50     double m_x[2];
 51     double m_y[2];
 52     double m_dx;
 53     double m_dy;
 54     int    m_idx;
 55 
 56     
 57 
 58     agg::slider_ctrl<agg::rgba8> m_radius;//圆角半径
 59     agg::slider_ctrl<agg::rgba8> m_offset;//偏移量
 60 
 61     agg::slider_ctrl<agg::rgba8> gradientx;//x方向渐变程度
 62     agg::slider_ctrl<agg::rgba8> gradienty;//y方向渐变程度
 63 
 64     agg::slider_ctrl<agg::rgba8> leftr;//左边起始点红色分量
 65     agg::slider_ctrl<agg::rgba8> leftg;//左边起始点绿色分量
 66     agg::slider_ctrl<agg::rgba8> leftb;//左边起始点蓝色分量
 67 
 68     agg::slider_ctrl<agg::rgba8> rightr;//右边起始点红色分量
 69     agg::slider_ctrl<agg::rgba8> rightg;//右边起始点绿色分量
 70     agg::slider_ctrl<agg::rgba8> rightb;//右边起始点蓝色分量
 71 public:
 72     the_application(agg::pix_format_e format, bool flip_y) :
 73         agg::platform_support(format, flip_y),
 74         m_idx(-1),
 75         m_radius(10, 10, 300-10,   19,    !flip_y),
 76         m_offset(10, 10+20, 300-10, 19+20, !flip_y),
 77         gradientx(300, 10, 600-10, 19, !flip_y),
 78         gradienty(300, 10+20, 600-10, 19+20, !flip_y),
 79         leftr(10, 10+40, 300-10, 19+40, !flip_y),
 80         leftg(10, 10+60, 300-10, 19+60, !flip_y),
 81         leftb(10, 10+80, 300-10, 19+80, !flip_y),
 82         rightr(300, 10+40, 600-10, 19+40, !flip_y),
 83         rightg(300, 10+60, 600-10, 19+60, !flip_y),
 84         rightb(300, 10+80, 600-10, 19+80, !flip_y)
 85     {
 86         m_x[0] = 100;   m_y[0] = 200;
 87         m_x[1] = 500;   m_y[1] = 550;
 88         add_ctrl(m_radius);
 89         add_ctrl(m_offset);
 90 
 91         add_ctrl(gradientx);
 92         add_ctrl(gradienty);
 93 
 94         add_ctrl(leftr);
 95         add_ctrl(leftg);
 96         add_ctrl(leftb);
 97 
 98         add_ctrl(rightr);
 99         add_ctrl(rightg);
100         add_ctrl(rightb);
101 
102         {
103             gradientx.label("x=%4.3f");
104             gradientx.range(-1.0, 1.0);
105             gradientx.value(0.5);
106 
107             gradienty.label("y=%4.3f");
108             gradienty.range(-1.0, 1.0);
109             gradienty.value(0.5);
110         }
111         {
112             leftr.label("lr=%4.3f");
113             leftr.range(0.0, 1.0);
114             leftr.value(0.5);
115 
116             leftg.label("lg=%4.3f");
117             leftg.range(0.0, 1.0);
118             leftg.value(0.5);
119 
120             leftb.label("lb=%4.3f");
121             leftb.range(0.0, 1.0);
122             leftb.value(0.5);
123         }
124         {
125             rightr.label("lr=%4.3f");
126             rightr.range(0.0, 1.0);
127             rightr.value(0.5);
128 
129             rightg.label("lg=%4.3f");
130             rightg.range(0.0, 1.0);
131             rightg.value(0.5);
132 
133             rightb.label("lb=%4.3f");
134             rightb.range(0.0, 1.0);
135             rightb.value(0.5);
136         }
137         m_radius.label("radius=%4.3f");
138         m_radius.range(0.0, 50.0);
139         m_radius.value(25.0);
140 
141         m_offset.label("subpixel offset=%4.3f");
142         m_offset.range(-2.0, 3.0);
143     }
144 
145 
146     virtual ~the_application()
147     {
148     }
149 
150 
151     virtual void on_init()
152     {
153     }
154 
155 
156     virtual void on_draw()
157     {
158         pixfmt_type pixf(rbuf_window());
159         renderer_base_type ren_base(pixf);
160         renderer_scanline_type ren_sl(ren_base);
161         scanline_type sl;
162         rasterizer_type ras;
163 
164         ren_base.clear(agg::rgba(0,0,0));
165 
166         {
167 
168             agg::renderer_scanline_aa_solid<renderer_base_type>ren(ren_base);
169             ren.color(agg::rgba8(127,127,127));
170 
171             agg::ellipse e;
172             // Render two "control" circles
173             e.init(m_x[0], m_y[0], 3, 3, 16);
174             ras.add_path(e);
175             //agg::render_scanlines_aa_solid(ras, sl, ren_base, agg::rgba8(127, 127, 127));
176             agg::render_scanlines(ras, sl, ren);
177             e.init(m_x[1], m_y[1], 3, 3, 16);
178             ras.add_path(e);
179             //agg::render_scanlines_aa_solid(ras, sl, ren_base, agg::rgba8(127, 127, 127));
180             agg::render_scanlines(ras, sl, ren);
181 
182             
183         }
184         double d = m_offset.value();
185 
186         typedef agg::gradient_x gradient_func_type;
187         typedef agg::span_interpolator_linear<> interpolator_type;
188         typedef agg::span_allocator<color_type> span_allocator_type;
189         typedef agg::pod_auto_array<color_type, 256> color_array_type;
190         typedef agg::span_gradient<color_type, 
191                                    interpolator_type, 
192                                    gradient_func_type, 
193                                    color_array_type> span_gradient_type;
194 
195         typedef agg::renderer_scanline_aa<renderer_base_type, 
196                                           span_allocator_type,
197                                           span_gradient_type> renderer_gradient_type;
198 
199         gradient_func_type  gradient_func;                   // The gradient function
200         agg::trans_affine   gradient_mtx;                    // Affine transformer
201         interpolator_type   span_interpolator(gradient_mtx); // Span interpolator
202         span_allocator_type span_allocator;                  // Span Allocator
203         color_array_type    gradient_colors;                 // The gradient colors
204         span_gradient_type  span_gradient(span_interpolator, 
205                                           gradient_func, 
206                                           gradient_colors, 
207                                           0, 100);
208 
209         renderer_gradient_type ren_gradient(ren_base, span_allocator, span_gradient);
210 
211         double x1=m_x[0]+d, y1=m_y[0]+d, x2=m_x[1]+d, y2=m_y[1]+d;
212 
213         {
214             //----------------
215             fill_color_array(gradient_colors, 
216                             agg::rgba(leftr.value(),leftg.value(),leftb.value()), 
217                             agg::rgba(rightr.value(),rightg.value(),rightb.value()));
218 
219             {
220                 double gradient_d2 = 100.0;
221                 double dx = (x2 - x1)*gradientx.value();
222                 double dy = (y2 - y1)*gradienty.value();
223                 gradient_mtx.reset();
224                 gradient_mtx *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / gradient_d2);
225                 gradient_mtx *= agg::trans_affine_rotation(atan2(dy, dx));
226                 gradient_mtx *= agg::trans_affine_translation(x1 + 0.5, y1 + 0.5);
227                 gradient_mtx.invert();
228             }
229             agg::rounded_rect r(x1, y1, x2, y2, m_radius.value());
230             r.normalize_radius();
231             ras.add_path(r);
232             agg::render_scanlines(ras, sl, ren_gradient);
233         }
234         // Reset AA Gamma and render the controls
235         // Render the controls
236         
237         agg::render_ctrl(ras, sl, ren_base, m_radius);
238         agg::render_ctrl(ras, sl, ren_base, m_offset);
239 
240         agg::render_ctrl(ras, sl, ren_base, gradientx);
241         agg::render_ctrl(ras, sl, ren_base, gradienty);
242 
243         agg::render_ctrl(ras, sl, ren_base, leftr);
244         agg::render_ctrl(ras, sl, ren_base, leftg);
245         agg::render_ctrl(ras, sl, ren_base, leftb);
246 
247         agg::render_ctrl(ras, sl, ren_base, rightr);
248         agg::render_ctrl(ras, sl, ren_base, rightb);
249         agg::render_ctrl(ras, sl, ren_base, rightg);
250     }
251 
252 
253 
254     virtual void on_mouse_button_down(int x, int y, unsigned flags)
255     {
256         if(flags & agg::mouse_left)
257         {
258             unsigned i;
259             for (i = 0; i < 2; i++)
260             {
261                 if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 5.0)
262                 {
263                     m_dx = x - m_x[i];
264                     m_dy = y - m_y[i];
265                     m_idx = i;
266                     break;
267                 }
268             }
269         }
270         //update_window();
271     }
272 
273 
274 
275 
276     virtual void on_mouse_move(int x, int y, unsigned flags)
277     {
278         if(flags & agg::mouse_left)
279         {
280             if(m_idx >= 0)
281             {
282                 m_x[m_idx] = x - m_dx;
283                 m_y[m_idx] = y - m_dy;
284                 force_redraw();
285             }
286         }
287         else
288         {
289             on_mouse_button_up(x, y, flags);
290         }
291     }
292 
293     virtual void on_mouse_button_up(int x, int y, unsigned flags)
294     {
295         m_idx = -1;
296     }
297 };
298 
299 
300 int agg_main(int argc, char* argv[])
301 {
302     the_application app(agg::pix_format_bgr24, flip_y);
303     app.caption("AGG Example. Anti-Aliasing Test");
304 
305     if(app.init(600, 600, agg::window_resize))
306     {
307         return app.run();
308     }
309     return 1;
310 }

 最终效果

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

 

 欢迎与一起学习agg的朋友共同交流哈,网上资料不多

posted @ 2012-08-01 23:31  狂热与执着  阅读(1426)  评论(0编辑  收藏  举报