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

aa_test.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_pixfmt_rgb.h"
00008 #include "agg_gamma_lut.h"
00009 #include "agg_conv_dash.h"
00010 #include "agg_conv_stroke.h"
00011 #include "agg_span_gradient.h"
00012 #include "agg_span_interpolator_linear.h"
00013 #include "agg_span_gouraud_rgba.h"
00014 #include "agg_span_allocator.h"
00015 #include "platform/agg_platform_support.h"
00016 #include "ctrl/agg_slider_ctrl.h"
00017 #include "ctrl/agg_cbox_ctrl.h"
00018 
00019 
00020 enum flip_y_e { flip_y = false };
00021 
00022 
00023 
00024 typedef agg::gamma_lut<agg::int8u, agg::int8u, 8, 8>        gamma_lut_type;
00025 typedef agg::pixfmt_bgr24_gamma<gamma_lut_type>             pixfmt_type;
00026 typedef pixfmt_type::color_type                             color_type;
00027 typedef agg::renderer_base<pixfmt_type>                     renderer_base_type;
00028 typedef agg::renderer_scanline_aa_solid<renderer_base_type> renderer_scanline_type;
00029 typedef agg::scanline_u8                                    scanline_type;
00030 typedef agg::rasterizer_scanline_aa<>                       rasterizer_type;
00031 
00032 template<class T> T min(T a, T b) { return (a < b) ? a : b; }
00033 
00034 inline double frand(double x)
00035 { 
00036     return ((((rand() << 15) | rand()) & 0x3FFFFFFF) % 1000000) * x / 1000000.0;
00037 }
00038  
00039  
00040 
00041 
00042 class simple_vertex_source
00043 {
00044 public:
00045     simple_vertex_source() : m_num_vertices(0), m_count(0) 
00046     { 
00047         m_cmd[0] = agg::path_cmd_stop;
00048     }
00049 
00050 
00051     simple_vertex_source(double x1, double y1, double x2, double y2)
00052     {
00053         init(x1, y1, x2, y2);
00054     }
00055 
00056 
00057     simple_vertex_source(double x1, double y1, 
00058                          double x2, double y2,
00059                          double x3, double y3)
00060     {
00061         init(x1, y1, x2, y2, x3, y3);
00062     }
00063 
00064     void init(double x1, double y1, double x2, double y2)
00065     {
00066         m_num_vertices = 2;
00067         m_count = 0;
00068         m_x[0] = x1;
00069         m_y[0] = y1;
00070         m_x[1] = x2;
00071         m_y[1] = y2;
00072         m_cmd[0] = agg::path_cmd_move_to;
00073         m_cmd[1] = agg::path_cmd_line_to;
00074         m_cmd[2] = agg::path_cmd_stop;
00075     }
00076 
00077 
00078 
00079     void init(double x1, double y1, 
00080               double x2, double y2,
00081               double x3, double y3)
00082     {
00083         m_num_vertices = 3;
00084         m_count = 0;
00085         m_x[0] = x1;
00086         m_y[0] = y1;
00087         m_x[1] = x2;
00088         m_y[1] = y2;
00089         m_x[2] = x3;
00090         m_y[2] = y3;
00091         m_x[3] = m_y[3] = m_x[4] = m_y[4] = 0.0;
00092         m_cmd[0] = agg::path_cmd_move_to;
00093         m_cmd[1] = agg::path_cmd_line_to;
00094         m_cmd[2] = agg::path_cmd_line_to;
00095         m_cmd[3] = agg::path_cmd_end_poly | agg::path_flags_close;
00096         m_cmd[4] = agg::path_cmd_stop;
00097     }
00098 
00099 
00100     void rewind(unsigned)
00101     {
00102         m_count = 0;
00103     }
00104 
00105     unsigned vertex(double* x, double* y)
00106     {
00107         *x = m_x[m_count];
00108         *y = m_y[m_count];
00109         return m_cmd[m_count++];
00110     }
00111 
00112 private:
00113     unsigned m_num_vertices;
00114     unsigned m_count;
00115     double   m_x[8];
00116     double   m_y[8];
00117     unsigned m_cmd[8];
00118 };
00119 
00120 
00121 
00122 
00123 
00124 template<class Ras, class Ren, class Scanline> class dashed_line
00125 {
00126 public:
00127     dashed_line(Ras& ras, Ren& ren, Scanline& sl) : 
00128         m_ras(ras), m_ren(ren), m_sl(sl),
00129         m_src(),
00130         m_dash(m_src),
00131         m_stroke(m_src),
00132         m_dash_stroke(m_dash)
00133     {}
00134 
00135     void draw(double x1, double y1, double x2, double y2, 
00136               double line_width, double dash_length)
00137     {
00138         m_src.init(x1 + 0.5, y1 + 0.5, x2 + 0.5, y2 + 0.5);
00139         m_ras.reset();
00140         if(dash_length > 0.0)
00141         {
00142             m_dash.remove_all_dashes();
00143             m_dash.add_dash(dash_length, dash_length);
00144             m_dash_stroke.width(line_width);
00145             m_dash_stroke.line_cap(agg::round_cap);
00146             m_ras.add_path(m_dash_stroke);
00147         }
00148         else
00149         {
00150             m_stroke.width(line_width);
00151             m_stroke.line_cap(agg::round_cap);
00152             m_ras.add_path(m_stroke);
00153         }
00154         agg::render_scanlines(m_ras, m_sl, m_ren);
00155     }
00156 
00157 private:
00158     Ras&      m_ras;
00159     Ren&      m_ren;
00160     Scanline& m_sl;
00161     simple_vertex_source m_src;
00162     agg::conv_dash<simple_vertex_source> m_dash;
00163     agg::conv_stroke<simple_vertex_source> m_stroke;
00164     agg::conv_stroke<agg::conv_dash<simple_vertex_source> > m_dash_stroke;
00165 };
00166 
00167 
00168 
00169 // Calculate the affine transformation matrix for the linear gradient 
00170 // from (x1, y1) to (x2, y2). gradient_d2 is the "base" to scale the
00171 // gradient. Here d1 must be 0.0, and d2 must equal gradient_d2.
00172 //---------------------------------------------------------------
00173 void calc_linear_gradient_transform(double x1, double y1, double x2, double y2, 
00174                                     agg::trans_affine& mtx,
00175                                     double gradient_d2 = 100.0)
00176 {
00177     double dx = x2 - x1;
00178     double dy = y2 - y1;
00179     mtx.reset();
00180     mtx *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / gradient_d2);
00181     mtx *= agg::trans_affine_rotation(atan2(dy, dx));
00182     mtx *= agg::trans_affine_translation(x1 + 0.5, y1 + 0.5);
00183     mtx.invert();
00184 }
00185 
00186 
00187 // A simple function to form the gradient color array 
00188 // consisting of 3 colors, "begin", "middle", "end"
00189 //---------------------------------------------------
00190 template<class ColorArrayT>
00191 void fill_color_array(ColorArrayT& array, 
00192                       color_type begin, 
00193                       color_type end)
00194 {
00195     unsigned i;
00196     for(i = 0; i < 256; ++i)
00197     {
00198         array[i] = begin.gradient(end, i / 255.0);
00199     }
00200 }
00201 
00202 
00203 
00204 
00205 
00206 
00207 class the_application : public agg::platform_support
00208 {
00209     gamma_lut_type              m_gamma;
00210     agg::slider_ctrl<agg::rgba> m_slider_gamma;
00211 
00212 public:
00213     the_application(agg::pix_format_e format, bool flip_y) :
00214         agg::platform_support(format, flip_y),
00215         m_gamma(1.0),
00216         m_slider_gamma(3, 3,    480-3, 8,    !flip_y)
00217     {
00218         add_ctrl(m_slider_gamma);
00219         m_slider_gamma.range(0.1, 3.0);
00220         m_slider_gamma.value(1.6);
00221         m_slider_gamma.label("Gamma=%4.3f");
00222     }
00223 
00224 
00225     virtual ~the_application()
00226     {
00227     }
00228 
00229 
00230     virtual void on_init()
00231     {
00232     }
00233 
00234 
00235     virtual void on_draw()
00236     {
00237         pixfmt_type pixf(rbuf_window(), m_gamma);
00238         renderer_base_type ren_base(pixf);
00239         renderer_scanline_type ren_sl(ren_base);
00240         scanline_type sl;
00241         rasterizer_type ras;
00242 
00243         ren_base.clear(agg::rgba(0,0,0));
00244 
00245 
00246         // gamma correction
00247         //ras.gamma(agg::gamma_power());
00248         m_gamma.gamma(m_slider_gamma.value());
00249 
00250         int i;
00251 
00252         // radial line test
00253         //-------------------------
00254         dashed_line<rasterizer_type, 
00255                     renderer_scanline_type, 
00256                     scanline_type> dash(ras, ren_sl, sl);
00257 
00258         double cx = width() / 2.0;
00259         double cy = height() / 2.0;
00260 
00261         ren_sl.color(agg::rgba(1.0, 1.0, 1.0, 0.2));
00262         for(i = 180; i > 0; i--) 
00263         {
00264             double n = 2.0 * agg::pi * i / 180.0;
00265             dash.draw(cx + min(cx, cy) * sin(n), cy + min(cx, cy) * cos(n),
00266                       cx, cy, 
00267                       1.0, (i < 90) ? i : 0.0);
00268         }
00269 
00270 
00271         typedef agg::gradient_x gradient_func_type;
00272         typedef agg::span_interpolator_linear<> interpolator_type;
00273         typedef agg::span_allocator<color_type> span_allocator_type;
00274         typedef agg::pod_auto_array<color_type, 256> color_array_type;
00275         typedef agg::span_gradient<color_type, 
00276                                    interpolator_type, 
00277                                    gradient_func_type, 
00278                                    color_array_type> span_gradient_type;
00279 
00280         typedef agg::renderer_scanline_aa<renderer_base_type, 
00281                                           span_allocator_type,
00282                                           span_gradient_type> renderer_gradient_type;
00283 
00284         gradient_func_type  gradient_func;                   // The gradient function
00285         agg::trans_affine   gradient_mtx;                    // Affine transformer
00286         interpolator_type   span_interpolator(gradient_mtx); // Span interpolator
00287         span_allocator_type span_allocator;                  // Span Allocator
00288         color_array_type    gradient_colors;                 // The gradient colors
00289         span_gradient_type  span_gradient(span_interpolator, 
00290                                           gradient_func, 
00291                                           gradient_colors, 
00292                                           0, 100);
00293 
00294         renderer_gradient_type ren_gradient(ren_base, span_allocator, span_gradient);
00295 
00296         dashed_line<rasterizer_type, 
00297                     renderer_gradient_type, 
00298                     scanline_type> dash_gradient(ras, ren_gradient, sl);
00299 
00300         double x1, y1, x2, y2;
00301 
00302         for(i = 1; i <= 20; i++)
00303         {
00304             ren_sl.color(agg::rgba(1,1,1));
00305 
00306             // integral point sizes 1..20
00307             //----------------
00308             agg::ellipse ell;
00309             
00310             ell.init(20 + i * (i + 1) + 0.5, 
00311                      20.5, 
00312                      i / 2.0, 
00313                      i / 2.0, 
00314                      8 + i);
00315             ras.reset();
00316             ras.add_path(ell);
00317             agg::render_scanlines(ras, sl, ren_sl);
00318             
00319 
00320             // fractional point sizes 0..2
00321             //----------------
00322             ell.init(18 + i * 4 + 0.5, 33 + 0.5, 
00323                      i/20.0, i/20.0, 
00324                      8);
00325             ras.reset();
00326             ras.add_path(ell);
00327             agg::render_scanlines(ras, sl, ren_sl);
00328 
00329 
00330             // fractional point positioning
00331             //---------------
00332             ell.init(18 + i * 4 + (i-1) / 10.0 + 0.5, 
00333                      27 + (i - 1) / 10.0 + 0.5, 
00334                      0.5, 0.5, 8);
00335             ras.reset();
00336             ras.add_path(ell);
00337             agg::render_scanlines(ras, sl, ren_sl);
00338 
00339 
00340             // integral line widths 1..20
00341             //----------------
00342             fill_color_array(gradient_colors, 
00343                              agg::rgba(1,1,1), 
00344                              agg::rgba(i % 2, (i % 3) * 0.5, (i % 5) * 0.25));
00345 
00346             x1 = 20 + i* (i + 1);
00347             y1 = 40.5;
00348             x2 = 20 + i * (i + 1) + (i - 1) * 4;
00349             y2 = 100.5;
00350             calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
00351             dash_gradient.draw(x1, y1, x2, y2, i, 0);
00352 
00353 
00354             fill_color_array(gradient_colors, 
00355                              agg::rgba(1,0,0), 
00356                              agg::rgba(0,0,1));
00357 
00358             // fractional line lengths H (red/blue)
00359             //----------------
00360             x1 = 17.5 + i * 4;
00361             y1 = 107;
00362             x2 = 17.5 + i * 4 + i/6.66666667;
00363             y2 = 107;
00364             calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
00365             dash_gradient.draw(x1, y1, x2, y2, 1.0, 0);
00366 
00367 
00368             // fractional line lengths V (red/blue)
00369             //---------------
00370             x1 = 18 + i * 4;
00371             y1 = 112.5;
00372             x2 = 18 + i * 4;
00373             y2 = 112.5 + i / 6.66666667;
00374             calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
00375             dash_gradient.draw(x1, y1, x2, y2, 1.0, 0);
00376 
00377             // fractional line positioning (red)
00378             //---------------
00379             fill_color_array(gradient_colors, 
00380                              agg::rgba(1,0,0), 
00381                              agg::rgba(1,1,1));
00382             x1 = 21.5;
00383             y1 = 120 + (i - 1) * 3.1;
00384             x2 = 52.5;
00385             y2 = 120 + (i - 1) * 3.1;
00386             calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
00387             dash_gradient.draw(x1, y1, x2, y2, 1.0, 0);
00388 
00389 
00390             // fractional line width 2..0 (green)
00391             fill_color_array(gradient_colors, 
00392                              agg::rgba(0,1,0), 
00393                              agg::rgba(1,1,1));
00394             x1 = 52.5;
00395             y1 = 118 + i * 3;
00396             x2 = 83.5;
00397             y2 = 118 + i * 3;
00398             calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
00399             dash_gradient.draw(x1, y1, x2, y2, 2.0 - (i - 1) / 10.0, 0);
00400 
00401             // stippled fractional width 2..0 (blue)
00402             fill_color_array(gradient_colors, 
00403                              agg::rgba(0,0,1), 
00404                              agg::rgba(1,1,1));
00405             x1 = 83.5;
00406             y1 = 119 + i * 3;
00407             x2 = 114.5;
00408             y2 = 119 + i * 3;
00409             calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
00410             dash_gradient.draw(x1, y1, x2, y2, 2.0 - (i - 1) / 10.0, 3.0);
00411 
00412 
00413             ren_sl.color(agg::rgba(1,1,1));
00414             if(i <= 10)
00415             {
00416                 // integral line width, horz aligned (mipmap test)
00417                 //-------------------
00418                 dash.draw(125.5, 119.5 + (i + 2) * (i / 2.0),
00419                           135.5, 119.5 + (i + 2) * (i / 2.0),
00420                           i, 0.0);
00421             }
00422 
00423             // fractional line width 0..2, 1 px H
00424             //-----------------
00425             dash.draw(17.5 + i * 4, 192, 18.5 + i * 4, 192, i / 10.0, 0);
00426 
00427             // fractional line positioning, 1 px H
00428             //-----------------
00429             dash.draw(17.5 + i * 4 + (i - 1) / 10.0, 186, 
00430                       18.5 + i * 4 + (i - 1) / 10.0, 186,
00431                       1.0, 0);
00432         }
00433 
00434 
00435         // Triangles
00436         //---------------
00437         for (i = 1; i <= 13; i++) 
00438         {
00439             fill_color_array(gradient_colors, 
00440                              agg::rgba(1,1,1), 
00441                              agg::rgba(i % 2, (i % 3) * 0.5, (i % 5) * 0.25));
00442             calc_linear_gradient_transform(width()  - 150, 
00443                                            height() - 20 - i * (i + 1.5),
00444                                            width()  - 20,  
00445                                            height() - 20 - i * (i + 1),
00446                                            gradient_mtx);
00447             ras.reset();
00448             ras.move_to_d(width() - 150, height() - 20 - i * (i + 1.5));
00449             ras.line_to_d(width() - 20,  height() - 20 - i * (i + 1));
00450             ras.line_to_d(width() - 20,  height() - 20 - i * (i + 2));
00451             agg::render_scanlines(ras, sl, ren_gradient);
00452         }
00453 
00454 
00455         // Reset AA Gamma and render the controls
00456         ras.gamma(agg::gamma_power(1.0));
00457         agg::render_ctrl(ras, sl, ren_base, m_slider_gamma);
00458     }
00459 
00460 
00461 
00462     virtual void on_mouse_button_down(int x, int y, unsigned flags)
00463     {
00464         srand(123);
00465         pixfmt_type pixf(rbuf_window(), m_gamma);
00466         renderer_base_type ren_base(pixf);
00467         renderer_scanline_type ren_sl(ren_base);
00468         scanline_type sl;
00469         rasterizer_type ras;
00470 
00471         ren_base.clear(agg::rgba(0,0,0));
00472 
00473         int i;
00474 
00475         double w = width();
00476         double h = height();
00477 
00478         agg::ellipse ell;
00479 
00480         start_timer();
00481         for(i = 0; i < 20000; i++)
00482         {
00483             double r = frand(20.0) + 1.0;
00484             ell.init(frand(w), frand(h), r/2, r/2, int(r) + 10);
00485             ras.reset();
00486             ras.add_path(ell);
00487             agg::render_scanlines(ras, sl, ren_sl);
00488             ren_sl.color(agg::rgba(frand(1.0), frand(1.0), frand(1.0), 0.5+frand(0.5)));
00489         }
00490         double t1 = elapsed_time();
00491 
00492         typedef agg::gradient_x gradient_func_type;
00493         typedef agg::span_interpolator_linear<> interpolator_type;
00494         typedef agg::span_allocator<color_type> span_allocator_type;
00495         typedef agg::pod_auto_array<color_type, 256> color_array_type;
00496         typedef agg::span_gradient<color_type, 
00497                                    interpolator_type, 
00498                                    gradient_func_type, 
00499                                    color_array_type> span_gradient_type;
00500         typedef agg::renderer_scanline_aa<renderer_base_type, 
00501                                           span_allocator_type,
00502                                           span_gradient_type> renderer_gradient_type;
00503 
00504         gradient_func_type  gradient_func;                   // The gradient function
00505         agg::trans_affine   gradient_mtx;                    // Affine transformer
00506         interpolator_type   span_interpolator(gradient_mtx); // Span interpolator
00507         span_allocator_type span_allocator;                  // Span Allocator
00508         color_array_type    gradient_colors;
00509         span_gradient_type  span_gradient(span_interpolator, 
00510                                           gradient_func, 
00511                                           gradient_colors, 
00512                                           0, 100);
00513         renderer_gradient_type ren_gradient(ren_base, 
00514                                             span_allocator, 
00515                                             span_gradient);
00516         dashed_line<rasterizer_type, 
00517                     renderer_gradient_type, 
00518                     scanline_type> dash_gradient(ras, ren_gradient, sl);
00519 
00520         double x1, y1, x2, y2, x3, y3;
00521 
00522         start_timer();
00523         for(i = 0; i < 2000; i++)
00524         {
00525                         x1 = frand(w); 
00526             y1 = frand(h);
00527             x2 = x1 + frand(w * 0.5) - w * 0.25;
00528             y2 = y1 + frand(h * 0.5) - h * 0.25;
00529 
00530             fill_color_array(gradient_colors, 
00531                              agg::rgba(frand(1.0), frand(1.0), frand(1.0), 0.5+frand(0.5)), 
00532                              agg::rgba(frand(1.0), frand(1.0), frand(1.0), frand(1.0)));
00533             calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
00534             dash_gradient.draw(x1, y1, x2, y2, 10.0, 0);
00535         }
00536         double t2 = elapsed_time();
00537 
00538 
00539 
00540         typedef agg::span_gouraud_rgba<color_type> gouraud_span_gen_type;
00541         typedef agg::renderer_scanline_aa<renderer_base_type, 
00542                                           span_allocator_type,
00543                                           gouraud_span_gen_type> renderer_gouraud_type;
00544         
00545         gouraud_span_gen_type span_gouraud;
00546         renderer_gouraud_type ren_gouraud(ren_base, span_allocator, span_gouraud);
00547 
00548 
00549         start_timer();
00550         for(i = 0; i < 2000; i++)
00551         {
00552                         x1 = frand(w); 
00553             y1 = frand(h);
00554             x2 = x1 + frand(w * 0.4) - w * 0.2;
00555             y2 = y1 + frand(h * 0.4) - h * 0.2;
00556             x3 = x1 + frand(w * 0.4) - w * 0.2;
00557             y3 = y1 + frand(h * 0.4) - h * 0.2;
00558 
00559             span_gouraud.colors(agg::rgba(frand(1.0), frand(1.0), frand(1.0), 0.5+frand(0.5)),
00560                                 agg::rgba(frand(1.0), frand(1.0), frand(1.0), frand(1.0)),
00561                                 agg::rgba(frand(1.0), frand(1.0), frand(1.0), frand(1.0)));
00562             span_gouraud.triangle(x1, y1, x2, y2, x3, y3, 0.0);
00563             ras.add_path(span_gouraud);
00564             agg::render_scanlines(ras, sl, ren_gouraud);
00565         }
00566 
00567         double t3 = elapsed_time();
00568 
00569         char buf[256];
00570         sprintf(buf, "Points=%.2fK/sec, Lines=%.2fK/sec, Triangles=%.2fK/sec", 20000.0/t1, 2000.0/t2, 2000.0/t3);
00571         message(buf);
00572         update_window();
00573     }
00574 
00575 
00576 
00577 
00578     virtual void on_mouse_move(int x, int y, unsigned flags)
00579     {
00580     }
00581 
00582     virtual void on_mouse_button_up(int x, int y, unsigned flags)
00583     {
00584     }
00585 };
00586 
00587 
00588 int agg_main(int argc, char* argv[])
00589 {
00590     the_application app(agg::pix_format_bgr24, flip_y);
00591     app.caption("AGG Example. Anti-Aliasing Test");
00592 
00593     if(app.init(480, 350, agg::window_resize))
00594     {
00595         return app.run();
00596     }
00597     return 1;
00598 }
00599 
00600 

© sourcejam.com 2005-2008