00001 #include <stdlib.h>
00002 #include <ctype.h>
00003 #include <stdio.h>
00004 #include "agg_basics.h"
00005 #include "agg_rendering_buffer.h"
00006 #include "agg_rasterizer_scanline_aa.h"
00007 #include "agg_scanline_u.h"
00008 #include "agg_scanline_p.h"
00009 #include "agg_color_gray.h"
00010 #include "agg_renderer_mclip.h"
00011 #include "agg_renderer_scanline.h"
00012 #include "agg_path_storage.h"
00013 #include "agg_conv_transform.h"
00014 #include "agg_bounding_rect.h"
00015 #include "agg_renderer_outline_aa.h"
00016 #include "agg_pixfmt_gray.h"
00017 #include "agg_pixfmt_amask_adaptor.h"
00018 #include "agg_renderer_primitives.h"
00019 #include "agg_renderer_markers.h"
00020 #include "agg_span_allocator.h"
00021 #include "agg_span_gradient.h"
00022 #include "agg_span_interpolator_linear.h"
00023 #include "agg_rasterizer_outline_aa.h"
00024 #include "agg_alpha_mask_u8.h"
00025 #include "agg_ellipse.h"
00026 #include "ctrl/agg_slider_ctrl.h"
00027 #include "platform/agg_platform_support.h"
00028
00029
00030
00031
00032
00033 #define AGG_BGRA32
00034
00035
00036
00037
00038
00039 #include "pixel_formats.h"
00040
00041 enum flip_y_e { flip_y = true };
00042
00043 agg::rasterizer_scanline_aa<> g_rasterizer;
00044 agg::scanline_u8 g_scanline;
00045 agg::path_storage g_path;
00046 agg::rgba8 g_colors[100];
00047 unsigned g_path_idx[100];
00048 unsigned g_npaths = 0;
00049 double g_x1 = 0;
00050 double g_y1 = 0;
00051 double g_x2 = 0;
00052 double g_y2 = 0;
00053 double g_base_dx = 0;
00054 double g_base_dy = 0;
00055 double g_angle = 0;
00056 double g_scale = 1.0;
00057 double g_skew_x = 0;
00058 double g_skew_y = 0;
00059 int g_nclick = 0;
00060
00061
00062 unsigned parse_lion(agg::path_storage& ps, agg::rgba8* colors, unsigned* path_idx);
00063 void parse_lion()
00064 {
00065 g_npaths = parse_lion(g_path, g_colors, g_path_idx);
00066 agg::pod_array_adaptor<unsigned> path_idx(g_path_idx, 100);
00067 agg::bounding_rect(g_path, path_idx, 0, g_npaths, &g_x1, &g_y1, &g_x2, &g_y2);
00068 g_base_dx = (g_x2 - g_x1) / 2.0;
00069 g_base_dy = (g_y2 - g_y1) / 2.0;
00070 }
00071
00072
00073 namespace agg
00074 {
00075
00076
00077
00078
00079 template<> struct gradient_linear_color<rgba8>
00080 {
00081 typedef rgba8 color_type;
00082
00083 gradient_linear_color() {}
00084 gradient_linear_color(const color_type& c1, const color_type& c2) :
00085 m_c1(c1), m_c2(c2) {}
00086
00087 static unsigned size() { return 256; }
00088 color_type operator [] (unsigned v) const
00089 {
00090 color_type c;
00091 c.r = (int8u)((((m_c2.r - m_c1.r) * int(v)) + (m_c1.r << 8)) >> 8);
00092 c.g = (int8u)((((m_c2.g - m_c1.g) * int(v)) + (m_c1.g << 8)) >> 8);
00093 c.b = (int8u)((((m_c2.b - m_c1.b) * int(v)) + (m_c1.b << 8)) >> 8);
00094 c.a = (int8u)((((m_c2.a - m_c1.a) * int(v)) + (m_c1.a << 8)) >> 8);
00095 return c;
00096 }
00097
00098 void colors(const color_type& c1, const color_type& c2)
00099 {
00100 m_c1 = c1;
00101 m_c2 = c2;
00102 }
00103
00104 color_type m_c1;
00105 color_type m_c2;
00106 };
00107
00108
00109
00110 template<> struct gradient_linear_color<gray8>
00111 {
00112 typedef gray8 color_type;
00113
00114 gradient_linear_color() {}
00115 gradient_linear_color(const color_type& c1, const color_type& c2) :
00116 m_c1(c1), m_c2(c2) {}
00117
00118 static unsigned size() { return 256; }
00119 color_type operator [] (unsigned v) const
00120 {
00121 color_type c;
00122 c.v = (int8u)((((m_c2.v - m_c1.v) * int(v)) + (m_c1.v << 8)) >> 8);
00123 c.a = (int8u)((((m_c2.a - m_c1.a) * int(v)) + (m_c1.a << 8)) >> 8);
00124 return c;
00125 }
00126
00127 void colors(const color_type& c1, const color_type& c2)
00128 {
00129 m_c1 = c1;
00130 m_c2 = c2;
00131 }
00132
00133 color_type m_c1;
00134 color_type m_c2;
00135 };
00136
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146 class the_application : public agg::platform_support
00147 {
00148 agg::slider_ctrl<agg::rgba> m_num_cb;
00149
00150 typedef agg::amask_no_clip_gray8 alpha_mask_type;
00151
00152
00153 unsigned char* m_alpha_buf;
00154 agg::rendering_buffer m_alpha_mask_rbuf;
00155 alpha_mask_type m_alpha_mask;
00156
00157 double m_slider_value;
00158
00159
00160 public:
00161 ~the_application()
00162 {
00163 delete [] m_alpha_buf;
00164 }
00165
00166 the_application(agg::pix_format_e format, bool flip_y) :
00167 agg::platform_support(format, flip_y),
00168 m_num_cb(5, 5, 150, 12, !flip_y),
00169
00170 m_alpha_buf(0),
00171 m_alpha_mask_rbuf(),
00172 m_alpha_mask(m_alpha_mask_rbuf),
00173 m_slider_value(0.0)
00174 {
00175 parse_lion();
00176 add_ctrl(m_num_cb);
00177 m_num_cb.range(5, 100);
00178 m_num_cb.value(10);
00179 m_num_cb.label("N=%.2f");
00180 m_num_cb.no_transform();
00181 }
00182
00183
00184
00185 void generate_alpha_mask(int cx, int cy)
00186 {
00187 delete [] m_alpha_buf;
00188 m_alpha_buf = new unsigned char[cx * cy];
00189 m_alpha_mask_rbuf.attach(m_alpha_buf, cx, cy, cx);
00190
00191 typedef agg::renderer_base<agg::pixfmt_gray8> ren_base;
00192 typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
00193
00194 agg::pixfmt_gray8 pixf(m_alpha_mask_rbuf);
00195 ren_base rb(pixf);
00196 renderer r(rb);
00197 agg::scanline_p8 sl;
00198
00199 rb.clear(agg::gray8(0));
00200
00201 agg::ellipse ell;
00202
00203 srand(1432);
00204
00205 int i;
00206 for(i = 0; i < (int)m_num_cb.value(); i++)
00207 {
00208 ell.init(rand() % cx,
00209 rand() % cy,
00210 rand() % 100 + 20,
00211 rand() % 100 + 20,
00212 100);
00213
00214 g_rasterizer.add_path(ell);
00215 r.color(agg::gray8((rand() & 127) + 128, (rand() & 127) + 128));
00216 agg::render_scanlines(g_rasterizer, sl, r);
00217 }
00218 }
00219
00220
00221 virtual void on_resize(int cx, int cy)
00222 {
00223 generate_alpha_mask(cx, cy);
00224 }
00225
00226
00227
00228
00229 virtual void on_draw()
00230 {
00231 unsigned i;
00232 int width = rbuf_window().width();
00233 int height = rbuf_window().height();
00234
00235 if(m_num_cb.value() != m_slider_value)
00236 {
00237 generate_alpha_mask(width, height);
00238 m_slider_value = m_num_cb.value();
00239 }
00240
00241
00242 pixfmt pf(rbuf_window());
00243
00244 typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
00245 typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
00246 typedef agg::renderer_base<pixfmt> base_ren_type;
00247
00248 pixfmt_amask_type pfa(pf, m_alpha_mask);
00249 amask_ren_type r(pfa);
00250 base_ren_type rbase(pf);
00251
00252 agg::renderer_scanline_aa_solid<amask_ren_type> rs(r);
00253 agg::renderer_scanline_aa_solid<base_ren_type> rb(rbase);
00254
00255 agg::trans_affine mtx;
00256 mtx *= agg::trans_affine_translation(-g_base_dx, -g_base_dy);
00257 mtx *= agg::trans_affine_scaling(g_scale, g_scale);
00258 mtx *= agg::trans_affine_rotation(g_angle + agg::pi);
00259 mtx *= agg::trans_affine_skewing(g_skew_x/1000.0, g_skew_y/1000.0);
00260 mtx *= agg::trans_affine_translation(width/2, height/2);
00261
00262 rbase.clear(agg::rgba(1, 1, 1));
00263
00264 int x, y;
00265
00266
00267 agg::conv_transform<agg::path_storage, agg::trans_affine> trans(g_path, mtx);
00268 agg::render_all_paths(g_rasterizer, g_scanline, rs, trans, g_colors, g_path_idx, g_npaths);
00269
00270
00271
00272 agg::renderer_markers<amask_ren_type> m(r);
00273 for(i = 0; i < 50; i++)
00274 {
00275 m.line_color(agg::rgba8(rand() & 0x7F,
00276 rand() & 0x7F,
00277 rand() & 0x7F,
00278 (rand() & 0x7F) + 0x7F));
00279 m.fill_color(agg::rgba8(rand() & 0x7F,
00280 rand() & 0x7F,
00281 rand() & 0x7F,
00282 (rand() & 0x7F) + 0x7F));
00283
00284 m.line(m.coord(rand() % width), m.coord(rand() % height),
00285 m.coord(rand() % width), m.coord(rand() % height));
00286
00287 m.marker(rand() % width, rand() % height, rand() % 10 + 5,
00288 agg::marker_e(rand() % agg::end_of_markers));
00289 }
00290
00291
00292
00293 double w = 5.0;
00294 agg::line_profile_aa profile;
00295 profile.width(w);
00296
00297 typedef agg::renderer_outline_aa<amask_ren_type> renderer_type;
00298 renderer_type ren(r, profile);
00299
00300 typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
00301 rasterizer_type ras(ren);
00302 ras.round_cap(true);
00303
00304 for(i = 0; i < 50; i++)
00305 {
00306 ren.color(agg::rgba8(rand() & 0x7F,
00307 rand() & 0x7F,
00308 rand() & 0x7F,
00309
00310 (rand() & 0x7F) + 0x7F));
00311 ras.move_to_d(rand() % width, rand() % height);
00312 ras.line_to_d(rand() % width, rand() % height);
00313 ras.render(false);
00314 }
00315
00316
00317
00318 typedef agg::gradient_linear_color<color_type> grad_color;
00319 typedef agg::gradient_circle grad_func;
00320 typedef agg::span_interpolator_linear<> interpolator_type;
00321 typedef agg::span_gradient<color_type,
00322 interpolator_type,
00323 grad_func,
00324 grad_color> span_grad_type;
00325
00326 agg::trans_affine grm;
00327 grad_func grf;
00328 grad_color grc(agg::rgba8(0,0,0), agg::rgba8(0,0,0));
00329 agg::ellipse ell;
00330 agg::span_allocator<color_type> sa;
00331 interpolator_type inter(grm);
00332 span_grad_type sg(inter, grf, grc, 0, 10);
00333 agg::renderer_scanline_aa<amask_ren_type,
00334 agg::span_allocator<color_type>,
00335 span_grad_type> rg(r, sa, sg);
00336 for(i = 0; i < 50; i++)
00337 {
00338 x = rand() % width;
00339 y = rand() % height;
00340 double r = rand() % 10 + 5;
00341 grm.reset();
00342 grm *= agg::trans_affine_scaling(r / 10.0);
00343 grm *= agg::trans_affine_translation(x, y);
00344 grm.invert();
00345 grc.colors(agg::rgba8(255, 255, 255, 0),
00346 agg::rgba8(rand() & 0x7F,
00347 rand() & 0x7F,
00348 rand() & 0x7F,
00349 255));
00350 sg.color_function(grc);
00351 ell.init(x, y, r, r, 32);
00352 g_rasterizer.add_path(ell);
00353 agg::render_scanlines(g_rasterizer, g_scanline, rg);
00354 }
00355
00356 agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_num_cb);
00357 }
00358
00359
00360 void transform(double width, double height, double x, double y)
00361 {
00362 x -= width / 2;
00363 y -= height / 2;
00364 g_angle = atan2(y, x);
00365 g_scale = sqrt(y * y + x * x) / 100.0;
00366 }
00367
00368
00369 virtual void on_mouse_button_down(int x, int y, unsigned flags)
00370 {
00371 if(flags & agg::mouse_left)
00372 {
00373 int width = rbuf_window().width();
00374 int height = rbuf_window().height();
00375 transform(width, height, x, y);
00376 force_redraw();
00377 }
00378
00379 if(flags & agg::mouse_right)
00380 {
00381 g_skew_x = x;
00382 g_skew_y = y;
00383 force_redraw();
00384 }
00385 }
00386
00387
00388 virtual void on_mouse_move(int x, int y, unsigned flags)
00389 {
00390 on_mouse_button_down(x, y, flags);
00391 }
00392
00393 };
00394
00395
00396
00397
00398
00399
00400 int agg_main(int argc, char* argv[])
00401 {
00402 the_application app(pix_format, flip_y);
00403 app.caption("AGG Example. Clipping to multiple rectangle regions");
00404
00405 if(app.init(512, 400, agg::window_resize))
00406 {
00407 return app.run();
00408 }
00409 return 1;
00410 }
00411
00412
00413
00414
00415
00416