Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

alpha_gradient.cpp

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include "agg_basics.h"
00003 #include "agg_rendering_buffer.h"
00004 #include "agg_rasterizer_scanline_aa.h"
00005 #include "agg_scanline_u.h"
00006 #include "agg_renderer_scanline.h"
00007 #include "agg_span_gradient.h"
00008 #include "agg_span_gradient_alpha.h"
00009 #include "agg_span_interpolator_linear.h"
00010 #include "agg_span_allocator.h"
00011 #include "agg_span_converter.h"
00012 #include "agg_ellipse.h"
00013 #include "agg_pixfmt_rgb.h"
00014 #include "agg_vcgen_stroke.h"
00015 #include "platform/agg_platform_support.h"
00016 
00017 #include "ctrl/agg_spline_ctrl.h"
00018 
00019 enum flip_y_e { flip_y = true };
00020 
00021 
00022 
00023 #define pix_format agg::pix_format_bgr24
00024 typedef agg::pixfmt_bgr24 pixfmt_type;
00025 typedef pixfmt_type::color_type color_type;
00026 typedef color_type::value_type color_value_type;
00027 
00028 
00029 class the_application : public agg::platform_support
00030 {
00031     double m_x[3];
00032     double m_y[3];
00033     double m_dx;
00034     double m_dy;
00035     int    m_idx;
00036     agg::spline_ctrl<color_type> m_alpha;
00037 
00038 
00039 public:
00040     the_application(agg::pix_format_e format, bool flip_y) :
00041         agg::platform_support(format, flip_y),
00042         m_idx(-1),
00043         m_alpha(2,  2,  200, 30,  6, !flip_y)
00044     {
00045         m_x[0] = 257;    m_y[0] = 60;
00046         m_x[1] = 369;   m_y[1] = 170;
00047         m_x[2] = 143;   m_y[2] = 310;
00048 
00049         m_alpha.point(0, 0.0,     0.0);
00050         m_alpha.point(1, 1.0/5.0, 1.0 - 4.0/5.0);
00051         m_alpha.point(2, 2.0/5.0, 1.0 - 3.0/5.0);
00052         m_alpha.point(3, 3.0/5.0, 1.0 - 2.0/5.0);
00053         m_alpha.point(4, 4.0/5.0, 1.0 - 1.0/5.0);
00054         m_alpha.point(5, 1.0,     1.0);
00055         m_alpha.update_spline();
00056         add_ctrl(m_alpha);
00057     }
00058 
00059 
00060 
00061     // A simple function to form the gradient color array 
00062     // consisting of 3 colors, "begin", "middle", "end"
00063     //---------------------------------------------------
00064     template<class ColorArrayT>
00065     static void fill_color_array(ColorArrayT& array, 
00066                                  color_type begin, 
00067                                  color_type middle, 
00068                                  color_type end)
00069     {
00070         unsigned i;
00071         for(i = 0; i < 128; ++i)
00072         {
00073             array[i] = begin.gradient(middle, i / 128.0);
00074         }
00075         for(; i < 256; ++i)
00076         {
00077             array[i] = middle.gradient(end, (i - 128) / 128.0);
00078         }
00079     }
00080 
00081 
00082 
00083     virtual void on_draw()
00084     {
00085         typedef agg::renderer_base<pixfmt_type> base_ren_type;
00086 
00087         pixfmt_type pf(rbuf_window());
00088         base_ren_type ren_base(pf);
00089         ren_base.clear(agg::rgba(1,1,1));
00090 
00091         agg::scanline_u8 sl;
00092         agg::rasterizer_scanline_aa<> ras;
00093 
00094 
00095         // Draw some background
00096         agg::ellipse ell;
00097         srand(1234);
00098         unsigned i;
00099         unsigned w = unsigned(width());
00100         unsigned h = unsigned(height());
00101         for(i = 0; i < 100; i++)
00102         {
00103             ell.init(rand() % w, rand() % h, rand() % 60 + 5, rand() % 60 + 5, 50);
00104             ras.add_path(ell);
00105             agg::render_scanlines_aa_solid(ras, sl, ren_base, 
00106                                            agg::rgba(rand() / double(RAND_MAX), 
00107                                                      rand() / double(RAND_MAX), 
00108                                                      rand() / double(RAND_MAX), 
00109                                                      rand() / double(RAND_MAX) / 2.0));
00110         }
00111 
00112 
00113 
00114         double parallelogram[6];
00115         parallelogram[0] = m_x[0];
00116         parallelogram[1] = m_y[0];
00117         parallelogram[2] = m_x[1];
00118         parallelogram[3] = m_y[1];
00119         parallelogram[4] = m_x[2];
00120         parallelogram[5] = m_y[2];
00121 
00122 
00123         // Gradient shape function (linear, radial, custom, etc)
00124         //-----------------
00125         typedef agg::gradient_circle gradient_func_type;   
00126 
00127         // Alpha gradient shape function (linear, radial, custom, etc)
00128         //-----------------
00129         typedef agg::gradient_xy gradient_alpha_func_type;
00130 
00131         // Span interpolator. This object is used in all span generators 
00132         // that operate with transformations during iterating of the spans,
00133         // for example, image transformers use the interpolator too.
00134         //-----------------
00135         typedef agg::span_interpolator_linear<> interpolator_type;
00136 
00137 
00138         // Span allocator is an object that allocates memory for 
00139         // the array of colors that will be used to render the 
00140         // color spans. One object can be shared between different 
00141         // span generators.
00142         //-----------------
00143         typedef agg::span_allocator<color_type> span_allocator_type;
00144 
00145 
00146         // Gradient colors array adaptor
00147         //-----------------
00148         typedef agg::pod_auto_array<color_type, 256> gradient_colors_type;
00149 
00150 
00151         // Finally, the gradient span generator working with the color_type 
00152         // color type. 
00153         //-----------------
00154         typedef agg::span_gradient<color_type, 
00155                                    interpolator_type, 
00156                                    gradient_func_type, 
00157                                    gradient_colors_type> span_gradient_type;
00158 
00159 
00160         // Gradient alpha array adaptor
00161         //-----------------
00162         typedef agg::pod_auto_array<color_value_type, 256> gradient_alpha_type;
00163 
00164         // The alpha gradient span converter working with the color_type 
00165         // color type. 
00166         //-----------------
00167         typedef agg::span_gradient_alpha<color_type, 
00168                                          interpolator_type, 
00169                                          gradient_alpha_func_type, 
00170                                          gradient_alpha_type> span_gradient_alpha_type;
00171 
00172 
00173         // Span converter type
00174         //-----------------
00175         typedef agg::span_converter<span_gradient_type,
00176                                     span_gradient_alpha_type> span_conv_type;
00177 
00178 
00179         // The gradient objects declarations
00180         //----------------
00181         gradient_func_type       gradient_func;                      // The gradient function
00182         gradient_alpha_func_type alpha_func;                         // The gradient function
00183         agg::trans_affine        gradient_mtx;                       // Gradient affine transformer
00184         agg::trans_affine        alpha_mtx;                          // Alpha affine transformer
00185         interpolator_type        span_interpolator(gradient_mtx);    // Span gradient interpolator
00186         interpolator_type        span_interpolator_alpha(alpha_mtx); // Span alpha interpolator
00187         span_allocator_type      span_allocator;                     // Span Allocator
00188         gradient_colors_type     color_array;                        // The gradient colors
00189 
00190         // Declare the gradient span itself. 
00191         // The last two arguments are so called "d1" and "d2" 
00192         // defining two distances in pixels, where the gradient starts
00193         // and where it ends. The actual meaning of "d1" and "d2" depands
00194         // on the gradient function.
00195         //----------------
00196         span_gradient_type span_gradient(span_interpolator, 
00197                                          gradient_func, 
00198                                          color_array, 
00199                                          0, 150);
00200 
00201         // Declare the gradient span itself. 
00202         // The last two arguments are so called "d1" and "d2" 
00203         // defining two distances in pixels, where the gradient starts
00204         // and where it ends. The actual meaning of "d1" and "d2" depands
00205         // on the gradient function.
00206         //----------------
00207         gradient_alpha_type alpha_array;
00208         span_gradient_alpha_type span_gradient_alpha(span_interpolator_alpha, 
00209                                                      alpha_func, 
00210                                                      alpha_array, 
00211                                                      0, 100);
00212 
00213         // Span converter declaration
00214         span_conv_type span_conv(span_gradient, span_gradient_alpha);
00215 
00216 
00217         // Finally we can draw a circle.
00218         //----------------
00219         gradient_mtx *= agg::trans_affine_scaling(0.75, 1.2);
00220         gradient_mtx *= agg::trans_affine_rotation(-agg::pi/3.0);
00221         gradient_mtx *= agg::trans_affine_translation(width()/2, height()/2);
00222         gradient_mtx.invert();
00223         alpha_mtx.parl_to_rect(parallelogram, -100, -100, 100, 100);
00224         fill_color_array(color_array, 
00225                          agg::rgba(0,    0.19, 0.19), 
00226                          agg::rgba(0.7,  0.7,  0.19),
00227                          agg::rgba(0.31, 0,    0));
00228 
00229         // Fill Alpha array
00230         //----------------
00231         for(i = 0; i < 256; i++)
00232         {
00233             alpha_array[i] = color_value_type(m_alpha.value(i / 255.0) * double(color_type::base_mask));
00234         }
00235 
00236         ell.init(width()/2, height()/2, 150, 150, 100);
00237         ras.add_path(ell);
00238 
00239         // Render the circle with gradient plus alpha-gradient 
00240         agg::render_scanlines_aa(ras, sl, ren_base, span_allocator, span_conv);
00241 
00242 
00243         // Draw the control points and the parallelogram
00244         //-----------------
00245         agg::rgba color_pnt(0, 0.4, 0.4, 0.31);
00246         ell.init(m_x[0], m_y[0], 5, 5, 20);
00247         ras.add_path(ell);
00248         agg::render_scanlines_aa_solid(ras, sl, ren_base, color_pnt);
00249         ell.init(m_x[1], m_y[1], 5, 5, 20);
00250         ras.add_path(ell);
00251         agg::render_scanlines_aa_solid(ras, sl, ren_base, color_pnt);
00252         ell.init(m_x[2], m_y[2], 5, 5, 20);
00253         ras.add_path(ell);
00254         agg::render_scanlines_aa_solid(ras, sl, ren_base, color_pnt);
00255 
00256         agg::vcgen_stroke stroke;
00257         stroke.add_vertex(m_x[0], m_y[0], agg::path_cmd_move_to);
00258         stroke.add_vertex(m_x[1], m_y[1], agg::path_cmd_line_to);
00259         stroke.add_vertex(m_x[2], m_y[2], agg::path_cmd_line_to);
00260         stroke.add_vertex(m_x[0]+m_x[2]-m_x[1], m_y[0]+m_y[2]-m_y[1], agg::path_cmd_line_to);
00261         stroke.add_vertex(0, 0, agg::path_cmd_end_poly | agg::path_flags_close);
00262         ras.add_path(stroke);
00263         agg::render_scanlines_aa_solid(ras, sl, ren_base, agg::rgba(0, 0, 0));
00264 
00265         agg::render_ctrl(ras, sl, ren_base, m_alpha);
00266     }
00267 
00268 
00269 
00270 
00271 
00272     virtual void on_mouse_button_down(int x, int y, unsigned flags)
00273     {
00274         unsigned i;
00275         if(flags & agg::mouse_left)
00276         {
00277             for (i = 0; i < 3; i++)
00278             {
00279                 if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 10.0)
00280                 {
00281                     m_dx = x - m_x[i];
00282                     m_dy = y - m_y[i];
00283                     m_idx = i;
00284                     break;
00285                 }
00286             }
00287             if(i == 3)
00288             {
00289                 if(agg::point_in_triangle(m_x[0], m_y[0], 
00290                                           m_x[1], m_y[1],
00291                                           m_x[2], m_y[2],
00292                                           x, y))
00293                 {
00294                     m_dx = x - m_x[0];
00295                     m_dy = y - m_y[0];
00296                     m_idx = 3;
00297                 }
00298 
00299             }
00300         }
00301     }
00302 
00303 
00304     virtual void on_mouse_move(int x, int y, unsigned flags)
00305     {
00306         if(flags & agg::mouse_left)
00307         {
00308             if(m_idx == 3)
00309             {
00310                 double dx = x - m_dx;
00311                 double dy = y - m_dy;
00312                 m_x[1] -= m_x[0] - dx;
00313                 m_y[1] -= m_y[0] - dy;
00314                 m_x[2] -= m_x[0] - dx;
00315                 m_y[2] -= m_y[0] - dy;
00316                 m_x[0] = dx;
00317                 m_y[0] = dy;
00318                 force_redraw();
00319                 return;
00320             }
00321 
00322             if(m_idx >= 0)
00323             {
00324                 m_x[m_idx] = x - m_dx;
00325                 m_y[m_idx] = y - m_dy;
00326                 force_redraw();
00327             }
00328         }
00329         else
00330         {
00331             on_mouse_button_up(x, y, flags);
00332         }
00333     }
00334 
00335     virtual void on_mouse_button_up(int x, int y, unsigned flags)
00336     {
00337         m_idx = -1;
00338     }
00339 
00340     
00341     virtual void on_key(int x, int y, unsigned key, unsigned flags)
00342     {
00343         double dx = 0;
00344         double dy = 0;
00345         switch(key)
00346         {
00347         case agg::key_left:  dx = -0.1; break;
00348         case agg::key_right: dx =  0.1; break;
00349         case agg::key_up:    dy =  0.1; break;
00350         case agg::key_down:  dy = -0.1; break;
00351         }
00352         m_x[0] += dx;
00353         m_y[0] += dy;
00354         m_x[1] += dx;
00355         m_y[1] += dy;
00356         force_redraw();
00357     }
00358 
00359 
00360 };
00361 
00362 
00363 int agg_main(int argc, char* argv[])
00364 {
00365     the_application app(pix_format, flip_y);
00366     app.caption("AGG Example. Alpha channel gradient");
00367 
00368     if(app.init(400, 320, agg::window_resize))
00369     {
00370         return app.run();
00371     }
00372     return 1;
00373 }
00374 
00375 

© sourcejam.com 2005-2008