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
00170
00171
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
00188
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
00247
00248 m_gamma.gamma(m_slider_gamma.value());
00249
00250 int i;
00251
00252
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;
00285 agg::trans_affine gradient_mtx;
00286 interpolator_type span_interpolator(gradient_mtx);
00287 span_allocator_type span_allocator;
00288 color_array_type 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
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
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
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
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
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
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
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
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
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
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
00424
00425 dash.draw(17.5 + i * 4, 192, 18.5 + i * 4, 192, i / 10.0, 0);
00426
00427
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
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
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;
00505 agg::trans_affine gradient_mtx;
00506 interpolator_type span_interpolator(gradient_mtx);
00507 span_allocator_type 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