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

alpha_mask3.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_p.h"
00006 #include "agg_renderer_scanline.h"
00007 #include "agg_renderer_primitives.h"
00008 #include "agg_conv_curve.h"
00009 #include "agg_conv_stroke.h"
00010 #include "agg_gsv_text.h"
00011 #include "agg_pixfmt_rgb.h"
00012 #include "agg_pixfmt_gray.h"
00013 #include "agg_pixfmt_amask_adaptor.h"
00014 #include "agg_span_allocator.h"
00015 #include "agg_alpha_mask_u8.h"
00016 
00017 #include "platform/agg_platform_support.h"
00018 
00019 #include "ctrl/agg_slider_ctrl.h"
00020 #include "ctrl/agg_cbox_ctrl.h"
00021 #include "ctrl/agg_rbox_ctrl.h"
00022 
00023 
00024 enum flip_y_e { flip_y = true };
00025 
00026 
00027 
00028 
00029 class spiral
00030 {
00031 public:
00032     spiral(double x, double y, double r1, double r2, double step, double start_angle=0) :
00033         m_x(x), 
00034         m_y(y), 
00035         m_r1(r1), 
00036         m_r2(r2), 
00037         m_step(step), 
00038         m_start_angle(start_angle),
00039         m_angle(start_angle),
00040         m_da(agg::deg2rad(4.0)),
00041         m_dr(m_step / 90.0)
00042     {
00043     }
00044 
00045     void rewind(unsigned) 
00046     { 
00047         m_angle = m_start_angle; 
00048         m_curr_r = m_r1; 
00049         m_start = true; 
00050     }
00051 
00052     unsigned vertex(double* x, double* y)
00053     {
00054         if(m_curr_r > m_r2) return agg::path_cmd_stop;
00055 
00056         *x = m_x + cos(m_angle) * m_curr_r;
00057         *y = m_y + sin(m_angle) * m_curr_r;
00058         m_curr_r += m_dr;
00059         m_angle += m_da;
00060         if(m_start) 
00061         {
00062             m_start = false;
00063             return agg::path_cmd_move_to;
00064         }
00065         return agg::path_cmd_line_to;
00066     }
00067 
00068 private:
00069     double m_x;
00070     double m_y;
00071     double m_r1;
00072     double m_r2;
00073     double m_step;
00074     double m_start_angle;
00075 
00076     double m_angle;
00077     double m_curr_r;
00078     double m_da;
00079     double m_dr;
00080     bool   m_start;
00081 };
00082 
00083 
00084 
00085 
00086 
00087 void make_gb_poly(agg::path_storage& ps);
00088 void make_arrows(agg::path_storage& ps);
00089 
00090 
00091 class the_application : public agg::platform_support
00092 {
00093     agg::rbox_ctrl<agg::rgba8> m_polygons;
00094     agg::rbox_ctrl<agg::rgba8> m_operation;
00095 
00096     typedef agg::amask_no_clip_gray8 alpha_mask_type;
00097     //typedef agg::alpha_mask_gray8 alpha_mask_type;
00098 
00099     typedef agg::pixfmt_bgr24 pixfmt_type;
00100 
00101     unsigned char* m_alpha_buf;
00102     agg::rendering_buffer m_alpha_mask_rbuf;
00103     alpha_mask_type m_alpha_mask;
00104     agg::rasterizer_scanline_aa<> m_ras;
00105     agg::scanline_p8              m_sl;
00106 
00107     double m_x;
00108     double m_y;
00109 
00110 public:
00111     ~the_application()
00112     {
00113         delete [] m_alpha_buf;
00114     }
00115     
00116     the_application(agg::pix_format_e format, bool flip_y) :
00117         agg::platform_support(format, flip_y),
00118         m_polygons (5.0,     5.0, 5.0+205.0,  110.0,  !flip_y),
00119         m_operation(555.0,   5.0, 555.0+80.0, 55.0,  !flip_y),
00120         m_alpha_buf(0),
00121         m_alpha_mask_rbuf(),
00122         m_alpha_mask(m_alpha_mask_rbuf),
00123         m_x(0),
00124         m_y(0)
00125     {
00126         m_operation.add_item("AND");
00127         m_operation.add_item("SUB");
00128         m_operation.cur_item(0);
00129         add_ctrl(m_operation);
00130         m_operation.no_transform();
00131 
00132         m_polygons.add_item("Two Simple Paths");
00133         m_polygons.add_item("Closed Stroke");
00134         m_polygons.add_item("Great Britain and Arrows");
00135         m_polygons.add_item("Great Britain and Spiral");
00136         m_polygons.add_item("Spiral and Glyph");
00137         m_polygons.cur_item(3);
00138         add_ctrl(m_polygons);
00139         m_polygons.no_transform();
00140     }
00141 
00142 
00143     void draw_text(double x, double y, const char* str)
00144     {
00145         pixfmt_type pf(rbuf_window());
00146         agg::renderer_base<pixfmt_type> rb(pf);
00147         agg::renderer_scanline_aa_solid<agg::renderer_base<pixfmt_type> > ren(rb);
00148 
00149         agg::gsv_text txt;
00150         agg::conv_stroke<agg::gsv_text> txt_stroke(txt);
00151         txt_stroke.width(1.5);
00152         txt_stroke.line_cap(agg::round_cap);
00153         txt.size(10.0);
00154         txt.start_point(x, y);
00155         txt.text(str);
00156         m_ras.add_path(txt_stroke);
00157         ren.color(agg::rgba(0.0, 0.0, 0.0));
00158         agg::render_scanlines(m_ras, m_sl, ren);
00159     }
00160 
00161 
00162     template<class VertexSource> void generate_alpha_mask(VertexSource& vs)
00163     {
00164         unsigned cx = (unsigned)width();
00165         unsigned cy = (unsigned)height();
00166 
00167         delete [] m_alpha_buf;
00168         m_alpha_buf = new unsigned char[cx * cy];
00169         m_alpha_mask_rbuf.attach(m_alpha_buf, cx, cy, cx);
00170 
00171         typedef agg::renderer_base<agg::pixfmt_gray8> ren_base;
00172         typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
00173 
00174         agg::pixfmt_gray8 pixf(m_alpha_mask_rbuf);
00175         ren_base rb(pixf);
00176         renderer ren(rb);
00177 
00178         start_timer();
00179         if(m_operation.cur_item() == 0)
00180         {
00181             rb.clear(agg::gray8(0));
00182             ren.color(agg::gray8(255));
00183         }
00184         else 
00185         {
00186             rb.clear(agg::gray8(255));
00187             ren.color(agg::gray8(0));
00188         }
00189         m_ras.add_path(vs);
00190         agg::render_scanlines(m_ras, m_sl, ren);
00191         double t1 = elapsed_time();
00192 
00193         char buf[100];
00194         sprintf(buf, "Generate AlphaMask: %.3fms", t1);
00195         draw_text(250, 20, buf);
00196     }
00197 
00198 
00199     template<class VertexSource>
00200     void perform_rendering(VertexSource& vs)
00201     {
00202         pixfmt_type pixf(rbuf_window());
00203 
00204         typedef agg::pixfmt_amask_adaptor<pixfmt_type, alpha_mask_type> pixfmt_amask_type;
00205         typedef agg::renderer_base<pixfmt_amask_type>                   amask_ren_type;
00206 
00207 
00208         pixfmt_amask_type pixfa(pixf, m_alpha_mask);
00209         amask_ren_type rbase(pixfa);
00210         agg::renderer_scanline_aa_solid<amask_ren_type> ren(rbase);
00211 
00212         ren.color(agg::rgba(0.5, 0.0, 0, 0.5));
00213 
00214         start_timer();
00215         m_ras.reset();
00216         m_ras.add_path(vs);
00217         agg::render_scanlines(m_ras, m_sl, ren);
00218         double t1 = elapsed_time();
00219 
00220 
00221         char buf[100];
00222         sprintf(buf, "Render with AlphaMask: %.3fms", t1);
00223         draw_text(250, 5, buf);
00224     }
00225 
00226 
00227     unsigned render()
00228     {
00229         pixfmt_type pf(rbuf_window());
00230         agg::renderer_base<pixfmt_type> rb(pf);
00231         agg::renderer_scanline_aa_solid<agg::renderer_base<pixfmt_type> > ren(rb);
00232 
00233         switch(m_polygons.cur_item())
00234         {
00235             case 0:
00236             {
00237                 //------------------------------------
00238                 // Two simple paths
00239                 //
00240                 agg::path_storage ps1;
00241                 agg::path_storage ps2;
00242 
00243                 double x = m_x - initial_width()/2 + 100;
00244                 double y = m_y - initial_height()/2 + 100;
00245                 ps1.move_to(x+140, y+145);
00246                 ps1.line_to(x+225, y+44);
00247                 ps1.line_to(x+296, y+219);
00248                 ps1.close_polygon();
00249 
00250                 ps1.line_to(x+226, y+289);
00251                 ps1.line_to(x+82,  y+292);
00252 
00253                 ps1.move_to(x+220, y+222);
00254                 ps1.line_to(x+363, y+249);
00255                 ps1.line_to(x+265, y+331);
00256 
00257                 ps1.move_to(x+242, y+243);
00258                 ps1.line_to(x+268, y+309);
00259                 ps1.line_to(x+325, y+261);
00260 
00261                 ps1.move_to(x+259, y+259);
00262                 ps1.line_to(x+273, y+288);
00263                 ps1.line_to(x+298, y+266);
00264 
00265                 ps2.move_to(100+32,  100+77);
00266                 ps2.line_to(100+473, 100+263);
00267                 ps2.line_to(100+351, 100+290);
00268                 ps2.line_to(100+354, 100+374);
00269 
00270                 m_ras.reset();
00271                 m_ras.add_path(ps1);
00272                 ren.color(agg::rgba(0, 0, 0, 0.1));
00273                 agg::render_scanlines(m_ras, m_sl, ren);
00274 
00275                 m_ras.reset();
00276                 m_ras.add_path(ps2);
00277                 ren.color(agg::rgba(0, 0.6, 0, 0.1));
00278                 agg::render_scanlines(m_ras, m_sl, ren);
00279 
00280                 generate_alpha_mask(ps1);
00281                 perform_rendering(ps2);
00282             }
00283             break;
00284 
00285             case 1:
00286             {
00287                 //------------------------------------
00288                 // Closed stroke
00289                 //
00290                 agg::path_storage ps1;
00291                 agg::path_storage ps2;
00292                 agg::conv_stroke<agg::path_storage> stroke(ps2);
00293                 stroke.width(10.0);
00294 
00295                 double x = m_x - initial_width()/2 + 100;
00296                 double y = m_y - initial_height()/2 + 100;
00297                 ps1.move_to(x+140, y+145);
00298                 ps1.line_to(x+225, y+44);
00299                 ps1.line_to(x+296, y+219);
00300                 ps1.close_polygon();
00301 
00302                 ps1.line_to(x+226, y+289);
00303                 ps1.line_to(x+82,  y+292);
00304 
00305                 ps1.move_to(x+220-50, y+222);
00306                 ps1.line_to(x+265-50, y+331);
00307                 ps1.line_to(x+363-50, y+249);
00308                 ps1.close_polygon(agg::path_flags_ccw);
00309 
00310                 ps2.move_to(100+32,  100+77);
00311                 ps2.line_to(100+473, 100+263);
00312                 ps2.line_to(100+351, 100+290);
00313                 ps2.line_to(100+354, 100+374);
00314                 ps2.close_polygon();
00315 
00316                 m_ras.reset();
00317                 m_ras.add_path(ps1);
00318                 ren.color(agg::rgba(0, 0, 0, 0.1));
00319                 agg::render_scanlines(m_ras, m_sl, ren);
00320 
00321                 m_ras.reset();
00322                 m_ras.add_path(stroke);
00323                 ren.color(agg::rgba(0, 0.6, 0, 0.1));
00324                 agg::render_scanlines(m_ras, m_sl, ren);
00325 
00326                 generate_alpha_mask(ps1);
00327                 perform_rendering(stroke);
00328             }
00329             break;
00330 
00331 
00332             case 2:
00333             {
00334                 //------------------------------------
00335                 // Great Britain and Arrows
00336                 //
00337                 agg::path_storage gb_poly;
00338                 agg::path_storage arrows;
00339                 make_gb_poly(gb_poly);
00340                 make_arrows(arrows);
00341 
00342                 agg::trans_affine mtx1;
00343                 agg::trans_affine mtx2;
00344                 mtx1 *= agg::trans_affine_translation(-1150, -1150);
00345                 mtx1 *= agg::trans_affine_scaling(2.0);
00346 
00347                 mtx2 = mtx1;
00348                 mtx2 *= agg::trans_affine_translation(m_x - initial_width()/2, 
00349                                                       m_y - initial_height()/2);
00350 
00351                 agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx1);
00352                 agg::conv_transform<agg::path_storage> trans_arrows(arrows, mtx2);
00353 
00354                 m_ras.add_path(trans_gb_poly);
00355                 ren.color(agg::rgba(0.5, 0.5, 0, 0.1));
00356                 agg::render_scanlines(m_ras, m_sl, ren);
00357 
00358                 agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly);
00359                 stroke_gb_poly.width(0.1);
00360                 m_ras.add_path(stroke_gb_poly);
00361                 ren.color(agg::rgba(0, 0, 0));
00362                 agg::render_scanlines(m_ras, m_sl, ren);
00363         
00364                 m_ras.add_path(trans_arrows);
00365                 ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1));
00366                 agg::render_scanlines(m_ras, m_sl, ren);
00367 
00368                 generate_alpha_mask(trans_gb_poly);
00369                 perform_rendering(trans_arrows);
00370             }
00371             break;
00372 
00373 
00374             case 3:
00375             {
00376                 //------------------------------------
00377                 // Great Britain and a Spiral
00378                 //
00379                 spiral sp(m_x, m_y, 10, 150, 30, 0.0);
00380                 agg::conv_stroke<spiral> stroke(sp);
00381                 stroke.width(15.0);
00382 
00383                 agg::path_storage gb_poly;
00384                 make_gb_poly(gb_poly);
00385 
00386                 agg::trans_affine mtx;
00387                 mtx *= agg::trans_affine_translation(-1150, -1150);
00388                 mtx *= agg::trans_affine_scaling(2.0);
00389 
00390                 agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx);
00391 
00392                 m_ras.add_path(trans_gb_poly);
00393                 ren.color(agg::rgba(0.5, 0.5, 0, 0.1));
00394                 agg::render_scanlines(m_ras, m_sl, ren);
00395 
00396                 agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly);
00397                 stroke_gb_poly.width(0.1);
00398                 m_ras.add_path(stroke_gb_poly);
00399                 ren.color(agg::rgba(0, 0, 0));
00400                 agg::render_scanlines(m_ras, m_sl, ren);
00401         
00402                 m_ras.add_path(stroke);
00403                 ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1));
00404                 agg::render_scanlines(m_ras, m_sl, ren);
00405 
00406                 generate_alpha_mask(trans_gb_poly);
00407                 perform_rendering(stroke);
00408             }
00409             break;
00410 
00411 
00412             case 4:
00413             {
00414                 //------------------------------------
00415                 // Spiral and glyph
00416                 //
00417                 spiral sp(m_x, m_y, 10, 150, 30, 0.0);
00418                 agg::conv_stroke<spiral> stroke(sp);
00419                 stroke.width(15.0);
00420 
00421                 agg::path_storage glyph;
00422                 glyph.move_to(28.47, 6.45);
00423                 glyph.curve3(21.58, 1.12, 19.82, 0.29);
00424                 glyph.curve3(17.19, -0.93, 14.21, -0.93);
00425                 glyph.curve3(9.57, -0.93, 6.57, 2.25);
00426                 glyph.curve3(3.56, 5.42, 3.56, 10.60);
00427                 glyph.curve3(3.56, 13.87, 5.03, 16.26);
00428                 glyph.curve3(7.03, 19.58, 11.99, 22.51);
00429                 glyph.curve3(16.94, 25.44, 28.47, 29.64);
00430                 glyph.line_to(28.47, 31.40);
00431                 glyph.curve3(28.47, 38.09, 26.34, 40.58);
00432                 glyph.curve3(24.22, 43.07, 20.17, 43.07);
00433                 glyph.curve3(17.09, 43.07, 15.28, 41.41);
00434                 glyph.curve3(13.43, 39.75, 13.43, 37.60);
00435                 glyph.line_to(13.53, 34.77);
00436                 glyph.curve3(13.53, 32.52, 12.38, 31.30);
00437                 glyph.curve3(11.23, 30.08, 9.38, 30.08);
00438                 glyph.curve3(7.57, 30.08, 6.42, 31.35);
00439                 glyph.curve3(5.27, 32.62, 5.27, 34.81);
00440                 glyph.curve3(5.27, 39.01, 9.57, 42.53);
00441                 glyph.curve3(13.87, 46.04, 21.63, 46.04);
00442                 glyph.curve3(27.59, 46.04, 31.40, 44.04);
00443                 glyph.curve3(34.28, 42.53, 35.64, 39.31);
00444                 glyph.curve3(36.52, 37.21, 36.52, 30.71);
00445                 glyph.line_to(36.52, 15.53);
00446                 glyph.curve3(36.52, 9.13, 36.77, 7.69);
00447                 glyph.curve3(37.01, 6.25, 37.57, 5.76);
00448                 glyph.curve3(38.13, 5.27, 38.87, 5.27);
00449                 glyph.curve3(39.65, 5.27, 40.23, 5.62);
00450                 glyph.curve3(41.26, 6.25, 44.19, 9.18);
00451                 glyph.line_to(44.19, 6.45);
00452                 glyph.curve3(38.72, -0.88, 33.74, -0.88);
00453                 glyph.curve3(31.35, -0.88, 29.93, 0.78);
00454                 glyph.curve3(28.52, 2.44, 28.47, 6.45);
00455                 glyph.close_polygon();
00456 
00457                 glyph.move_to(28.47, 9.62);
00458                 glyph.line_to(28.47, 26.66);
00459                 glyph.curve3(21.09, 23.73, 18.95, 22.51);
00460                 glyph.curve3(15.09, 20.36, 13.43, 18.02);
00461                 glyph.curve3(11.77, 15.67, 11.77, 12.89);
00462                 glyph.curve3(11.77, 9.38, 13.87, 7.06);
00463                 glyph.curve3(15.97, 4.74, 18.70, 4.74);
00464                 glyph.curve3(22.41, 4.74, 28.47, 9.62);
00465                 glyph.close_polygon();
00466 
00467                 agg::trans_affine mtx;
00468                 mtx *= agg::trans_affine_scaling(4.0);
00469                 mtx *= agg::trans_affine_translation(220, 200);
00470                 agg::conv_transform<agg::path_storage> trans(glyph, mtx);
00471                 agg::conv_curve<agg::conv_transform<agg::path_storage> > curve(trans);
00472 
00473                 m_ras.reset();
00474                 m_ras.add_path(stroke);
00475                 ren.color(agg::rgba(0, 0, 0, 0.1));
00476                 agg::render_scanlines(m_ras, m_sl, ren);
00477 
00478                 m_ras.reset();
00479                 m_ras.add_path(curve);
00480                 ren.color(agg::rgba(0, 0.6, 0, 0.1));
00481                 agg::render_scanlines(m_ras, m_sl, ren);
00482 
00483                 generate_alpha_mask(stroke);
00484                 perform_rendering(curve);
00485             }
00486             break;
00487         }
00488 
00489         return 0;
00490     }
00491 
00492 
00493     virtual void on_init()
00494     {
00495         m_x = width() / 2.0;
00496         m_y = height() / 2.0;
00497     }
00498 
00499     virtual void on_draw()
00500     {
00501         typedef agg::renderer_base<pixfmt_type> base_ren_type;
00502 
00503         pixfmt_type pf(rbuf_window());
00504         base_ren_type ren_base(pf);
00505         ren_base.clear(agg::rgba(1,1,1));
00506 
00507         render();
00508 
00509         agg::render_ctrl(m_ras, m_sl, ren_base, m_polygons);
00510         agg::render_ctrl(m_ras, m_sl, ren_base, m_operation);
00511     }
00512 
00513 
00514 
00515 
00516     virtual void on_mouse_button_down(int x, int y, unsigned flags)
00517     {
00518         if(flags & agg::mouse_left)
00519         {
00520             m_x = x;
00521             m_y = y;
00522             force_redraw();
00523         }
00524 
00525         if(flags & agg::mouse_right)
00526         {
00527             char buf[100];
00528             sprintf(buf, "%d %d", x, y);
00529             message(buf);
00530         }
00531     }
00532 
00533 
00534     virtual void on_mouse_move(int x, int y, unsigned flags)
00535     {
00536         if(flags & agg::mouse_left)
00537         {
00538             m_x = x;
00539             m_y = y;
00540             force_redraw();
00541         }
00542     }
00543 
00544 
00545 
00546 };
00547 
00548 
00549 
00550 int agg_main(int argc, char* argv[])
00551 {
00552     the_application app(agg::pix_format_bgr24, flip_y);
00553     app.caption("AGG Example. Alpha-Mask as a Polygon Clipper");
00554 
00555     if(app.init(640, 520, agg::window_resize))
00556     {
00557         return app.run();
00558     }
00559     return 1;
00560 }
00561 
00562 

© sourcejam.com 2005-2008