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

compositing.cpp

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include "agg_rendering_buffer.h"
00003 #include "agg_renderer_base.h"
00004 #include "agg_rasterizer_scanline_aa.h"
00005 #include "agg_scanline_u.h"
00006 #include "agg_renderer_scanline.h"
00007 #include "agg_rounded_rect.h"
00008 #include "agg_pixfmt_rgba.h"
00009 #include "agg_span_allocator.h"
00010 #include "agg_span_gradient.h"
00011 #include "agg_gsv_text.h"
00012 #include "agg_span_interpolator_linear.h"
00013 #include "platform/agg_platform_support.h"
00014 #include "ctrl/agg_slider_ctrl.h"
00015 #include "ctrl/agg_rbox_ctrl.h"
00016 
00017 
00018 enum flip_y_e { flip_y = true };
00019 
00020 typedef agg::rgba8 color;
00021 typedef agg::order_bgra order;
00022 typedef agg::int32u pixel_type;
00023 typedef agg::rendering_buffer rbuf_type;
00024 #define pix_format agg::pix_format_bgra32
00025 
00026 typedef agg::blender_rgba<color, order> prim_blender_type; 
00027 typedef agg::pixfmt_alpha_blend_rgba<prim_blender_type, rbuf_type> prim_pixfmt_type;
00028 typedef agg::renderer_base<prim_pixfmt_type> prim_ren_base_type;
00029 
00030 void force_comp_op_link()
00031 {
00032     // For unknown reason Digital Mars C++ doesn't want to link these 
00033     // functions if they are not specified explicitly. 
00034     agg::int8u p[4] = {0};
00035     agg::comp_op_rgba_contrast   <color, order>::blend_pix(p,0,0,0,0,0);
00036     agg::comp_op_rgba_darken     <color, order>::blend_pix(p,0,0,0,0,0);
00037     agg::comp_op_rgba_lighten    <color, order>::blend_pix(p,0,0,0,0,0);
00038     agg::comp_op_rgba_color_dodge<color, order>::blend_pix(p,0,0,0,0,0);
00039     agg::comp_op_rgba_color_burn <color, order>::blend_pix(p,0,0,0,0,0);
00040     agg::comp_op_rgba_hard_light <color, order>::blend_pix(p,0,0,0,0,0);
00041     agg::comp_op_rgba_soft_light <color, order>::blend_pix(p,0,0,0,0,0);
00042     agg::comp_op_rgba_difference <color, order>::blend_pix(p,0,0,0,0,0);
00043     agg::comp_op_rgba_exclusion  <color, order>::blend_pix(p,0,0,0,0,0);
00044     agg::comp_op_rgba_src_atop   <color, order>::blend_pix(p,0,0,0,0,0);
00045     agg::comp_op_rgba_dst_atop   <color, order>::blend_pix(p,0,0,0,0,0);
00046     agg::comp_op_rgba_xor        <color, order>::blend_pix(p,0,0,0,0,0);
00047     agg::comp_op_rgba_plus       <color, order>::blend_pix(p,0,0,0,0,0);
00048     agg::comp_op_rgba_minus      <color, order>::blend_pix(p,0,0,0,0,0);
00049     agg::comp_op_rgba_multiply   <color, order>::blend_pix(p,0,0,0,0,0);
00050     agg::comp_op_rgba_screen     <color, order>::blend_pix(p,0,0,0,0,0);
00051     agg::comp_op_rgba_overlay    <color, order>::blend_pix(p,0,0,0,0,0);
00052     agg::comp_op_rgba_src        <color, order>::blend_pix(p,0,0,0,0,0);
00053     agg::comp_op_rgba_dst        <color, order>::blend_pix(p,0,0,0,0,0);
00054     agg::comp_op_rgba_src_over   <color, order>::blend_pix(p,0,0,0,0,0);
00055     agg::comp_op_rgba_dst_over   <color, order>::blend_pix(p,0,0,0,0,0);
00056     agg::comp_op_rgba_src_in     <color, order>::blend_pix(p,0,0,0,0,0);
00057     agg::comp_op_rgba_dst_in     <color, order>::blend_pix(p,0,0,0,0,0);
00058     agg::comp_op_rgba_src_out    <color, order>::blend_pix(p,0,0,0,0,0);
00059     agg::comp_op_rgba_dst_out    <color, order>::blend_pix(p,0,0,0,0,0);
00060     agg::comp_op_rgba_clear      <color, order>::blend_pix(p,0,0,0,0,0);
00061 }
00062 
00063 namespace agg
00064 {
00065 
00066     //========================================================================
00067     template<> struct gradient_linear_color<color>
00068     {
00069         typedef color color_type;
00070         enum base_scale_e { base_shift = color_type::base_shift };
00071 
00072         gradient_linear_color() {}
00073         gradient_linear_color(const color_type& c1, const color_type& c2) :
00074             m_c1(c1), m_c2(c2) {}
00075 
00076         static unsigned size() { return 256; }
00077         color_type operator [] (unsigned v) const 
00078         {
00079             color_type c;
00080             typedef color_type::value_type value_type;
00081             v <<= base_shift - 8;
00082             c.r = (value_type)((((m_c2.r - m_c1.r) * v) + (m_c1.r << base_shift)) >> base_shift);
00083             c.g = (value_type)((((m_c2.g - m_c1.g) * v) + (m_c1.g << base_shift)) >> base_shift);
00084             c.b = (value_type)((((m_c2.b - m_c1.b) * v) + (m_c1.b << base_shift)) >> base_shift);
00085             c.a = (value_type)((((m_c2.a - m_c1.a) * v) + (m_c1.a << base_shift)) >> base_shift);
00086             return c;
00087         }
00088 
00089         void colors(const color_type& c1, const color_type& c2)
00090         {
00091             m_c1 = c1;
00092             m_c2 = c2;
00093         }
00094 
00095         color_type m_c1;
00096         color_type m_c2;
00097     };
00098 
00099 }
00100 
00101 
00102 
00103 
00104 agg::trans_affine gradient_affine(double x1, double y1, double x2, double y2, 
00105                                   double gradient_d2 = 100.0)
00106 {
00107     agg::trans_affine mtx;
00108     double dx = x2 - x1;
00109     double dy = y2 - y1;
00110     mtx.reset();
00111     mtx *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / gradient_d2);
00112     mtx *= agg::trans_affine_rotation(atan2(dy, dx));
00113     mtx *= agg::trans_affine_translation(x1, y1);
00114     mtx.invert();
00115     return mtx;
00116 }
00117 
00118 
00119 
00120 template<class RenBase> 
00121 void circle(RenBase& rbase, color c1, color c2, 
00122             double x1, double y1, double x2, double y2,
00123             double shadow_alpha)
00124 {
00125     typedef RenBase renderer_base_type;
00126     typedef agg::gradient_x gradient_func_type;
00127     typedef agg::gradient_linear_color<color> color_func_type;
00128     typedef agg::span_interpolator_linear<> interpolator_type;
00129     typedef agg::span_allocator<color> span_allocator_type;
00130     typedef agg::span_gradient<color, 
00131                                interpolator_type, 
00132                                gradient_func_type, 
00133                                color_func_type> span_gradient_type;
00134 
00135     gradient_func_type  gradient_func;                   // The gradient function
00136     agg::trans_affine   gradient_mtx = gradient_affine(x1, y1, x2, y2, 100);
00137     interpolator_type   span_interpolator(gradient_mtx); // Span interpolator
00138     span_allocator_type span_allocator;                  // Span Allocator
00139     color_func_type     color_func(c1, c2);
00140     span_gradient_type  span_gradient(span_interpolator, 
00141                                       gradient_func, 
00142                                       color_func, 
00143                                       0, 100);
00144     agg::rasterizer_scanline_aa<> ras;
00145     agg::scanline_u8 sl;
00146 
00147     double r = agg::calc_distance(x1, y1, x2, y2) / 2;
00148     agg::ellipse ell((x1+x2)/2+5, (y1+y2)/2-3, r, r, 100);
00149 
00150     ras.add_path(ell);
00151     agg::render_scanlines_aa_solid(ras, sl, rbase, 
00152                                    agg::rgba(0.6, 0.6, 0.6, 0.7*shadow_alpha));
00153 
00154     ell.init((x1+x2)/2, (y1+y2)/2, r, r, 100);
00155     ras.add_path(ell);
00156     agg::render_scanlines_aa(ras, sl, rbase, span_allocator, span_gradient);
00157 }
00158 
00159 
00160 
00161 template<class RenBase> 
00162 void dst_shape(RenBase& rbase, color c1, color c2, 
00163                double x1, double y1, double x2, double y2)
00164 {
00165     typedef RenBase renderer_base_type;
00166     typedef agg::gradient_x gradient_func_type;
00167     typedef agg::gradient_linear_color<color> color_func_type;
00168     typedef agg::span_interpolator_linear<> interpolator_type;
00169     typedef agg::span_allocator<color> span_allocator_type;
00170     typedef agg::span_gradient<color, 
00171                                interpolator_type, 
00172                                gradient_func_type, 
00173                                color_func_type> span_gradient_type;
00174 
00175     gradient_func_type  gradient_func;                   // The gradient function
00176     agg::trans_affine   gradient_mtx = gradient_affine(x1, y1, x2, y2, 100);
00177     interpolator_type   span_interpolator(gradient_mtx); // Span interpolator
00178     span_allocator_type span_allocator;                  // Span Allocator
00179     color_func_type     color_func(c1, c2);
00180     span_gradient_type  span_gradient(span_interpolator, 
00181                                       gradient_func, 
00182                                       color_func, 
00183                                       0, 100);
00184     agg::rasterizer_scanline_aa<> ras;
00185     agg::scanline_u8 sl;
00186 
00187     agg::rounded_rect shape(x1, y1, x2, y2, 40);
00188 //    agg::ellipse shape((x1+x2)/2, (y1+y2)/2, fabs(x2-x1)/2, fabs(y2-y1)/2, 100);
00189 
00190     ras.add_path(shape);
00191     agg::render_scanlines_aa(ras, sl, rbase, span_allocator, span_gradient);
00192 }
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 class the_application : public agg::platform_support
00201 {
00202     agg::slider_ctrl<color>    m_alpha_src;
00203     agg::slider_ctrl<color>    m_alpha_dst;
00204     agg::rbox_ctrl<agg::rgba8> m_comp_op;
00205 
00206 public:
00207     the_application(agg::pix_format_e format, bool flip_y) :
00208         agg::platform_support(format, flip_y),
00209         m_alpha_src(5, 5,    400, 11,    !flip_y),
00210         m_alpha_dst(5, 5+15, 400, 11+15, !flip_y),
00211         m_comp_op(420, 5.0, 420+170.0, 395.0, !flip_y)
00212     {
00213         m_alpha_src.label("Src Alpha=%.2f");
00214         m_alpha_src.value(1.0);
00215         add_ctrl(m_alpha_src);
00216 
00217         m_alpha_dst.label("Dst Alpha=%.2f");
00218         m_alpha_dst.value(0.75);
00219         add_ctrl(m_alpha_dst);
00220 
00221         m_comp_op.text_size(7);
00222         m_comp_op.add_item("clear");
00223         m_comp_op.add_item("src");
00224         m_comp_op.add_item("dst");
00225         m_comp_op.add_item("src-over");
00226         m_comp_op.add_item("dst-over");
00227         m_comp_op.add_item("src-in");
00228         m_comp_op.add_item("dst-in");
00229         m_comp_op.add_item("src-out");
00230         m_comp_op.add_item("dst-out");
00231         m_comp_op.add_item("src-atop");
00232         m_comp_op.add_item("dst-atop");
00233         m_comp_op.add_item("xor");
00234         m_comp_op.add_item("plus");
00235         m_comp_op.add_item("minus");
00236         m_comp_op.add_item("multiply");
00237         m_comp_op.add_item("screen");
00238         m_comp_op.add_item("overlay");
00239         m_comp_op.add_item("darken");
00240         m_comp_op.add_item("lighten");
00241         m_comp_op.add_item("color-dodge");
00242         m_comp_op.add_item("color-burn");
00243         m_comp_op.add_item("hard-light");
00244         m_comp_op.add_item("soft-light");
00245         m_comp_op.add_item("difference");
00246         m_comp_op.add_item("exclusion");
00247         m_comp_op.add_item("contrast");
00248         m_comp_op.cur_item(3);
00249         add_ctrl(m_comp_op);
00250     }
00251 
00252     virtual ~the_application()
00253     {
00254     }
00255 
00256     virtual void on_init()
00257     {
00258     }
00259 
00260 
00261     void render_scene(rbuf_type& rbuf, prim_pixfmt_type& pixf)
00262     {
00263         typedef agg::comp_op_adaptor_rgba<color, order> blender_type;
00264         typedef agg::pixfmt_custom_blend_rgba<blender_type, rbuf_type> pixfmt_type;
00265         typedef agg::renderer_base<pixfmt_type> renderer_type;
00266 
00267         pixfmt_type ren_pixf(rbuf);
00268         renderer_type renderer(ren_pixf);
00269 
00270         agg::renderer_base<prim_pixfmt_type> rb(pixf);
00271 
00272         rb.blend_from(prim_pixfmt_type(rbuf_img(1)), 
00273                       0, 250, 180, 
00274                       unsigned(m_alpha_src.value() * 255));
00275 
00276         circle(rb, 
00277                agg::rgba8(0xFD, 0xF0, 0x6F, unsigned(m_alpha_src.value() * 255)), 
00278                agg::rgba8(0xFE, 0x9F, 0x34, unsigned(m_alpha_src.value() * 255)),
00279                70*3, 100+24*3, 37*3, 100+79*3,
00280                m_alpha_src.value());
00281 
00282         ren_pixf.comp_op(m_comp_op.cur_item());
00283 
00284         if(m_comp_op.cur_item() == 25) // Contrast
00285         {
00286             double v = m_alpha_dst.value();
00287             dst_shape(renderer, 
00288                       agg::rgba(v, v, v), 
00289                       agg::rgba(v, v, v),
00290                       300+50, 100+24*3, 107+50, 100+79*3);
00291         }
00292         else
00293         {
00294             dst_shape(renderer, 
00295                       agg::rgba8(0x7F, 0xC1, 0xFF, unsigned(m_alpha_dst.value() * 255)), 
00296                       agg::rgba8(0x05, 0x00, 0x5F, unsigned(m_alpha_dst.value() * 255)),
00297                       300+50, 100+24*3, 107+50, 100+79*3);
00298         }
00299     }
00300 
00301 
00302     virtual void on_draw()
00303     {
00304         prim_pixfmt_type pixf(rbuf_window());
00305         prim_ren_base_type rb(pixf);
00306         rb.clear(agg::rgba8(255, 255, 255));
00307 
00308         unsigned y;
00309         for(y = 0; y < rb.height(); y += 8)
00310         {
00311             unsigned x;
00312             for(x = ((y >> 3) & 1) << 3; x < rb.width(); x += 16)
00313             {
00314                 rb.copy_bar(x, y, x+7, y+7, agg::rgba8(0xdf, 0xdf, 0xdf));
00315             }
00316         }
00317 
00318         create_img(0, rbuf_window().width(), rbuf_window().height()); // agg_platform_support functionality
00319 
00320         prim_pixfmt_type pixf2(rbuf_img(0));
00321         prim_ren_base_type rb2(pixf2);
00322         rb2.clear(agg::rgba8(0,0,0,0));
00323 
00324         typedef agg::blender_rgba_pre<color, order> blender_type_pre; 
00325         typedef agg::pixfmt_alpha_blend_rgba<blender_type_pre, rbuf_type, pixel_type> pixfmt_pre;
00326         typedef agg::renderer_base<pixfmt_pre> ren_base_pre;
00327 
00328         pixfmt_pre pixf_pre(rbuf_window());
00329         ren_base_pre rb_pre(pixf_pre);
00330 
00331 
00332         start_timer();
00333         render_scene(rbuf_img(0), pixf2);
00334         double tm = elapsed_time();
00335 
00336         rb_pre.blend_from(pixf2);
00337 
00338         agg::rasterizer_scanline_aa<> ras;
00339         agg::scanline_u8 sl;
00340         agg::renderer_scanline_aa_solid<prim_ren_base_type> ren(rb);
00341 
00342         char buf[64]; 
00343         agg::gsv_text t;
00344         t.size(10.0);
00345 
00346         agg::conv_stroke<agg::gsv_text> pt(t);
00347         pt.width(1.5);
00348 
00349         sprintf(buf, "%3.2f ms", tm);
00350         t.start_point(10.0, 35.0);
00351         t.text(buf);
00352 
00353         ras.add_path(pt);
00354         ren.color(agg::rgba(0,0,0));
00355         agg::render_scanlines(ras, sl, ren);
00356 
00357         agg::render_ctrl_rs(ras, sl, ren, m_alpha_src);
00358         agg::render_ctrl_rs(ras, sl, ren, m_alpha_dst);
00359         agg::render_ctrl_rs(ras, sl, ren, m_comp_op);
00360     }
00361 
00362 
00363     virtual void on_mouse_button_down(int x, int y, unsigned flags)
00364     {
00365     }
00366 
00367     virtual void on_mouse_move(int x, int y, unsigned flags)
00368     {
00369     }
00370 
00371     virtual void on_mouse_button_up(int x, int y, unsigned flags)
00372     {
00373     }
00374 };
00375 
00376 
00377 int agg_main(int argc, char* argv[])
00378 {
00379     force_comp_op_link();
00380     the_application app(pix_format, flip_y);
00381     app.caption("AGG Example. Compositing Modes");
00382 
00383     const char* img_name = "compositing";
00384     if(argc >= 2) img_name = argv[1];
00385     if(!app.load_img(1, img_name)) 
00386     {
00387         char buf[256];
00388         if(strcmp(img_name, "compositing") == 0)
00389         {
00390             sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
00391                          "or copy it from another directory if available.",
00392                     img_name, app.img_ext(), img_name, app.img_ext());
00393         }
00394         else
00395         {
00396             sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
00397         }
00398         app.message(buf);
00399         return 1;
00400     }
00401 
00402 
00403     if(app.init(600, 400, agg::window_resize))
00404     {
00405         return app.run();
00406     }
00407     return 1;
00408 }
00409 
00410 

© sourcejam.com 2005-2008