00001 #include <math.h>
00002 #include <stdio.h>
00003 #include "agg_basics.h"
00004 #include "agg_rendering_buffer.h"
00005 #include "agg_rasterizer_scanline_aa.h"
00006 #include "agg_rasterizer_outline.h"
00007 #include "agg_conv_stroke.h"
00008 #include "agg_conv_dash.h"
00009 #include "agg_conv_curve.h"
00010 #include "agg_conv_contour.h"
00011 #include "agg_conv_marker.h"
00012 #include "agg_conv_shorten_path.h"
00013 #include "agg_conv_marker_adaptor.h"
00014 #include "agg_conv_concat.h"
00015 #include "agg_arrowhead.h"
00016 #include "agg_vcgen_markers_term.h"
00017 #include "agg_scanline_p.h"
00018 #include "agg_scanline_u.h"
00019 #include "agg_renderer_scanline.h"
00020 #include "agg_renderer_primitives.h"
00021 #include "agg_span_allocator.h"
00022 #include "agg_span_gradient.h"
00023 #include "agg_span_interpolator_linear.h"
00024 #include "agg_pixfmt_rgb.h"
00025 #include "ctrl/agg_slider_ctrl.h"
00026 #include "ctrl/agg_rbox_ctrl.h"
00027 #include "ctrl/agg_cbox_ctrl.h"
00028 #include "platform/agg_platform_support.h"
00029
00030 enum flip_y_e { flip_y = true };
00031
00032
00033 typedef agg::pixfmt_bgr24 pixfmt;
00034 typedef pixfmt::color_type color_type;
00035 typedef agg::renderer_base<pixfmt> base_renderer;
00036 typedef agg::renderer_primitives<base_renderer> primitives_renderer;
00037
00038 typedef agg::renderer_scanline_aa_solid<base_renderer> solid_renderer;
00039 typedef agg::renderer_scanline_bin_solid<base_renderer> draft_renderer;
00040
00041 typedef agg::gradient_radial_d gradient_function;
00042 typedef agg::span_interpolator_linear<> interpolator;
00043 typedef agg::pod_auto_array<color_type, 256> color_array_type;
00044 typedef agg::span_gradient<color_type,
00045 interpolator,
00046 gradient_function,
00047 color_array_type> gradient_span_gen;
00048 typedef agg::span_allocator<color_type> gradient_span_alloc;
00049
00050 typedef agg::renderer_scanline_aa<base_renderer,
00051 gradient_span_alloc,
00052 gradient_span_gen> gradient_renderer;
00053
00054 typedef agg::rasterizer_scanline_aa<> scanline_rasterizer;
00055 typedef agg::rasterizer_outline<primitives_renderer> outline_rasterizer;
00056
00057
00058
00059
00060 class graph
00061 {
00062 public:
00063 struct node
00064 {
00065 double x, y;
00066 node() {}
00067 node(double x_, double y_) : x(x_), y(y_) {}
00068 };
00069
00070 struct edge
00071 {
00072 int node1;
00073 int node2;
00074 edge() {}
00075 edge(int n1, int n2) : node1(n1), node2(n2) {}
00076 };
00077
00078 ~graph()
00079 {
00080 delete [] m_edges;
00081 delete [] m_nodes;
00082 }
00083
00084 graph(int num_nodes, int num_edges) :
00085 m_num_nodes(num_nodes),
00086 m_num_edges(num_edges),
00087 m_nodes(new node[num_nodes]),
00088 m_edges(new edge[num_edges])
00089 {
00090 int i;
00091
00092 srand(100);
00093
00094 for(i = 0; i < m_num_nodes; i++)
00095 {
00096 m_nodes[i].x = (double(rand()) / RAND_MAX) * 0.75 + 0.2;
00097 m_nodes[i].y = (double(rand()) / RAND_MAX) * 0.85 + 0.1;
00098 }
00099
00100 for(i = 0; i < m_num_edges; i++)
00101 {
00102 m_edges[i].node1 = rand() % m_num_nodes;
00103 m_edges[i].node2 = rand() % m_num_nodes;
00104 if(m_edges[i].node1 == m_edges[i].node2) i--;
00105 }
00106 }
00107
00108 int get_num_nodes() const { return m_num_nodes; }
00109 int get_num_edges() const { return m_num_edges; }
00110
00111 node get_node(int idx, double w, double h) const
00112 {
00113 node p(0.0, 0.0);
00114 if(idx < m_num_nodes)
00115 {
00116 p = m_nodes[idx];
00117 p.x = p.x * w;
00118 p.y = p.y * h;
00119 }
00120 return p;
00121 }
00122
00123 edge get_edge(int idx) const
00124 {
00125 edge b(0,0);
00126 if(idx < m_num_edges)
00127 {
00128 b = m_edges[idx];
00129 }
00130 return b;
00131 }
00132
00133 private:
00134 graph(const graph&);
00135 const graph& operator = (const graph&);
00136
00137 int m_num_nodes;
00138 int m_num_edges;
00139 node* m_nodes;
00140 edge* m_edges;
00141 };
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 struct line
00153 {
00154 double x1, y1, x2, y2;
00155 int f;
00156
00157 line(double x1_, double y1_, double x2_, double y2_) :
00158 x1(x1_), y1(y1_), x2(x2_), y2(y2_), f(0) {}
00159
00160 void rewind(unsigned) { f = 0; }
00161 unsigned vertex(double* x, double* y)
00162 {
00163 if(f == 0) { ++f; *x = x1; *y = y1; return agg::path_cmd_move_to; }
00164 if(f == 1) { ++f; *x = x2; *y = y2; return agg::path_cmd_line_to; }
00165 return agg::path_cmd_stop;
00166 }
00167 };
00168
00169
00170
00171
00172
00173 struct curve
00174 {
00175 agg::curve4 c;
00176
00177 curve(double x1, double y1, double x2, double y2, double k=0.5)
00178 {
00179 c.init(x1, y1,
00180 x1 - (y2 - y1) * k,
00181 y1 + (x2 - x1) * k,
00182 x2 + (y2 - y1) * k,
00183 y2 - (x2 - x1) * k,
00184 x2, y2);
00185 }
00186
00187 void rewind(unsigned path_id) { c.rewind(path_id); }
00188 unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
00189 };
00190
00191
00192
00193
00194 template<class Source> struct stroke_draft_simple
00195 {
00196 Source& s;
00197 stroke_draft_simple(Source& src, double w) :
00198 s(src)
00199 {
00200 }
00201
00202 void rewind(unsigned path_id) { s.rewind(path_id); }
00203 unsigned vertex(double* x, double* y) { return s.vertex(x, y); }
00204 };
00205
00206
00207
00208 template<class Source> struct stroke_draft_arrow
00209 {
00210 typedef agg::conv_marker_adaptor<Source, agg::vcgen_markers_term> stroke_type;
00211 typedef agg::conv_marker<typename stroke_type::marker_type, agg::arrowhead> marker_type;
00212 typedef agg::conv_concat<stroke_type, marker_type> concat_type;
00213
00214 stroke_type s;
00215 agg::arrowhead ah;
00216 marker_type m;
00217 concat_type c;
00218
00219 stroke_draft_arrow(Source& src, double w) :
00220 s(src),
00221 ah(),
00222 m(s.markers(), ah),
00223 c(s, m)
00224 {
00225 ah.head(0, 10, 5, 0);
00226 s.shorten(10.0);
00227 }
00228
00229 void rewind(unsigned path_id) { c.rewind(path_id); }
00230 unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
00231 };
00232
00233
00234
00235
00236 template<class Source> struct stroke_fine_simple
00237 {
00238 typedef agg::conv_stroke<Source> stroke_type;
00239
00240 stroke_type s;
00241
00242 stroke_fine_simple(Source& src, double w) :
00243 s(src)
00244 {
00245 s.width(w);
00246 }
00247 void rewind(unsigned path_id) { s.rewind(path_id); }
00248 unsigned vertex(double* x, double* y) { return s.vertex(x, y); }
00249 };
00250
00251
00252
00253
00254 template<class Source> struct stroke_fine_arrow
00255 {
00256 typedef agg::conv_stroke<Source, agg::vcgen_markers_term> stroke_type;
00257 typedef agg::conv_marker<typename stroke_type::marker_type, agg::arrowhead> marker_type;
00258 typedef agg::conv_concat<stroke_type, marker_type> concat_type;
00259
00260 stroke_type s;
00261 agg::arrowhead ah;
00262 marker_type m;
00263 concat_type c;
00264
00265 stroke_fine_arrow(Source& src, double w) :
00266 s(src),
00267 ah(),
00268 m(s.markers(), ah),
00269 c(s, m)
00270 {
00271 s.width(w);
00272 ah.head(0, 10, 5, 0);
00273 s.shorten(w * 2.0);
00274 }
00275
00276 void rewind(unsigned path_id) { c.rewind(path_id); }
00277 unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
00278 };
00279
00280
00281
00282
00283 template<class Source> struct dash_stroke_draft_simple
00284 {
00285 typedef agg::conv_dash<Source, agg::vcgen_markers_term> dash_type;
00286
00287 dash_type d;
00288
00289 dash_stroke_draft_simple(Source& src,
00290 double dash_len,
00291 double gap_len,
00292 double w) :
00293 d(src)
00294 {
00295 d.add_dash(dash_len, gap_len);
00296 }
00297
00298 void rewind(unsigned path_id) { d.rewind(path_id); }
00299 unsigned vertex(double* x, double* y) { return d.vertex(x, y); }
00300 };
00301
00302
00303
00304 template<class Source> struct dash_stroke_draft_arrow
00305 {
00306 typedef agg::conv_dash<Source, agg::vcgen_markers_term> dash_type;
00307 typedef agg::conv_marker<typename dash_type::marker_type, agg::arrowhead> marker_type;
00308 typedef agg::conv_concat<dash_type, marker_type> concat_type;
00309
00310 dash_type d;
00311 agg::arrowhead ah;
00312 marker_type m;
00313 concat_type c;
00314
00315 dash_stroke_draft_arrow(Source& src,
00316 double dash_len, double gap_len, double w) :
00317 d(src),
00318 ah(),
00319 m(d.markers(), ah),
00320 c(d, m)
00321 {
00322 d.add_dash(dash_len, gap_len);
00323 ah.head(0, 10, 5, 0);
00324 d.shorten(10.0);
00325 }
00326
00327 void rewind(unsigned path_id) { c.rewind(path_id); }
00328 unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
00329 };
00330
00331
00332
00333
00334
00335 template<class Source> struct dash_stroke_fine_simple
00336 {
00337 typedef agg::conv_dash<Source> dash_type;
00338 typedef agg::conv_stroke<dash_type> stroke_type;
00339
00340 dash_type d;
00341 stroke_type s;
00342
00343 dash_stroke_fine_simple(Source& src,
00344 double dash_len, double gap_len, double w) :
00345 d(src),
00346 s(d)
00347 {
00348 d.add_dash(dash_len, gap_len);
00349 s.width(w);
00350 }
00351
00352 void rewind(unsigned path_id) { s.rewind(path_id); }
00353 unsigned vertex(double* x, double* y) { return s.vertex(x, y); }
00354 };
00355
00356
00357
00358
00359
00360
00361
00362 template<class Source> struct dash_stroke_fine_arrow
00363 {
00364 typedef agg::conv_dash<Source, agg::vcgen_markers_term> dash_type;
00365 typedef agg::conv_stroke<dash_type> stroke_type;
00366 typedef agg::conv_marker<typename dash_type::marker_type, agg::arrowhead> marker_type;
00367 typedef agg::conv_concat<stroke_type, marker_type> concat_type;
00368
00369 dash_type d;
00370 stroke_type s;
00371 agg::arrowhead ah;
00372 marker_type m;
00373 concat_type c;
00374
00375 dash_stroke_fine_arrow(Source& src,
00376 double dash_len, double gap_len, double w) :
00377 d(src),
00378 s(d),
00379 ah(),
00380 m(d.markers(), ah),
00381 c(s, m)
00382 {
00383 d.add_dash(dash_len, gap_len);
00384 s.width(w);
00385 ah.head(0, 10, 5, 0);
00386 d.shorten(w * 2.0);
00387 }
00388
00389 void rewind(unsigned path_id) { c.rewind(path_id); }
00390 unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
00391 };
00392
00393
00394
00395
00396
00397
00398
00399
00400 #define stroke_draft stroke_draft_arrow
00401 #define dash_stroke_draft dash_stroke_draft_arrow
00402 #define stroke_fine stroke_fine_arrow
00403 #define dash_stroke_fine dash_stroke_fine_arrow
00404
00405
00406
00407
00408
00409 class the_application : public agg::platform_support
00410 {
00411 agg::rbox_ctrl<agg::rgba> m_type;
00412 agg::slider_ctrl<agg::rgba> m_width;
00413 agg::cbox_ctrl<agg::rgba> m_benchmark;
00414 agg::cbox_ctrl<agg::rgba> m_draw_nodes;
00415 agg::cbox_ctrl<agg::rgba> m_draw_edges;
00416 agg::cbox_ctrl<agg::rgba> m_draft;
00417 agg::cbox_ctrl<agg::rgba> m_translucent;
00418 graph m_graph;
00419 color_array_type m_gradient_colors;
00420 int m_draw;
00421 agg::scanline_u8 m_sl;
00422
00423
00424 public:
00425 the_application(agg::pix_format_e format, bool flip_y) :
00426 agg::platform_support(format, flip_y),
00427 m_type(-1, -1, -1, -1, !flip_y),
00428 m_width(110+80, 8.0, 110+200.0+80, 8.0 + 7.0, !flip_y),
00429 m_benchmark(110+200+80+8, 8.0-2.0, "Benchmark", !flip_y),
00430 m_draw_nodes(110+200+80+8, 8.0-2.0+15.0, "Draw Nodes", !flip_y),
00431 m_draw_edges(200+200+80+8, 8.0-2.0+15.0, "Draw Edges", !flip_y),
00432 m_draft(200+200+80+8, 8.0-2.0, "Draft Mode", !flip_y),
00433 m_translucent(110+80, 8.0-2.0+15.0, "Translucent Mode", !flip_y),
00434 m_graph(200, 100),
00435 m_gradient_colors(),
00436 m_draw(3)
00437 {
00438 add_ctrl(m_type);
00439 m_type.text_size(8.0);
00440 m_type.add_item("Solid lines");
00441 m_type.add_item("Bezier curves");
00442 m_type.add_item("Dashed curves");
00443 m_type.add_item("Poygons AA");
00444 m_type.add_item("Poygons Bin");
00445 m_type.cur_item(0);
00446
00447 add_ctrl(m_width);
00448 m_width.num_steps(20);
00449 m_width.range(0.0, 5.0);
00450 m_width.value(2.0);
00451 m_width.label("Width=%1.2f");
00452
00453 m_benchmark.text_size(8.0);
00454 m_draw_nodes.text_size(8.0);
00455 m_draft.text_size(8.0);
00456 m_draw_nodes.status(true);
00457 m_draw_edges.status(true);
00458 add_ctrl(m_benchmark);
00459 add_ctrl(m_draw_nodes);
00460 add_ctrl(m_draw_edges);
00461 add_ctrl(m_draft);
00462 add_ctrl(m_translucent);
00463
00464 agg::rgba c1(1, 1, 0, 0.25);
00465 agg::rgba c2(0, 0, 1);
00466
00467 int i;
00468 for(i = 0; i < 256; i++)
00469 {
00470 m_gradient_colors[i] = c1.gradient(c2, double(i) / 255.0);
00471 }
00472 }
00473
00474
00475
00476
00477
00478
00479
00480 void draw_nodes_draft()
00481 {
00482 pixfmt pixf(rbuf_window());
00483 base_renderer rb(pixf);
00484 primitives_renderer prim(rb);
00485 int i;
00486 for(i = 0; i < m_graph.get_num_nodes(); i++)
00487 {
00488 graph::node n = m_graph.get_node(i, width(), height());
00489 prim.fill_color(m_gradient_colors[147]);
00490 prim.line_color(m_gradient_colors[255]);
00491 prim.outlined_ellipse(int(n.x), int(n.y), 10, 10);
00492 prim.fill_color(m_gradient_colors[50]);
00493 prim.solid_ellipse(int(n.x), int(n.y), 4, 4);
00494 }
00495 }
00496
00497
00498
00499
00500 void draw_nodes_fine(scanline_rasterizer& ras)
00501 {
00502 gradient_span_alloc sa;
00503 pixfmt pixf(rbuf_window());
00504 base_renderer rb(pixf);
00505 int i;
00506 for(i = 0; i < m_graph.get_num_nodes(); i++)
00507 {
00508 graph::node n = m_graph.get_node(i, width(), height());
00509 agg::ellipse ell(n.x, n.y, 5.0 * m_width.value(), 5.0 * m_width.value());
00510
00511 double x, y;
00512 switch(m_draw)
00513 {
00514 case 0:
00515 ell.rewind(0);
00516 while(!agg::is_stop(ell.vertex(&x, &y)));
00517 break;
00518
00519 case 1:
00520 ras.reset();
00521 ras.add_path(ell);
00522 break;
00523
00524 case 2:
00525 ras.reset();
00526 ras.add_path(ell);
00527 ras.sort();
00528 break;
00529
00530 case 3:
00531 {
00532 gradient_function gf;
00533 agg::trans_affine mtx;
00534 mtx *= agg::trans_affine_scaling(m_width.value() / 2.0);
00535 mtx *= agg::trans_affine_translation(n.x, n.y);
00536 mtx.invert();
00537 interpolator inter(mtx);
00538 gradient_span_gen sg(inter, gf, m_gradient_colors, 0.0, 10.0);
00539 gradient_renderer ren(rb, sa, sg);
00540 ras.add_path(ell);
00541 agg::render_scanlines(ras, m_sl, ren);
00542 }
00543 break;
00544 }
00545 }
00546 }
00547
00548
00549
00550
00551
00552
00553 template<class Source>
00554 void render_edge_fine(scanline_rasterizer& ras,
00555 solid_renderer& ren_fine,
00556 draft_renderer& ren_draft,
00557 Source& src)
00558 {
00559 double x, y;
00560 switch(m_draw)
00561 {
00562 case 0:
00563 src.rewind(0);
00564 while(!agg::is_stop(src.vertex(&x, &y)));
00565 break;
00566
00567 case 1:
00568 ras.reset();
00569 ras.add_path(src);
00570 break;
00571
00572 case 2:
00573 ras.reset();
00574 ras.add_path(src);
00575 ras.sort();
00576 break;
00577
00578 case 3:
00579 {
00580 int r = rand() & 0x7F;
00581 int g = rand() & 0x7F;
00582 int b = rand() & 0x7F;
00583 int a = 255;
00584 if(m_translucent.status()) a = 80;
00585 ras.add_path(src);
00586
00587 if(m_type.cur_item() < 4)
00588 {
00589 ren_fine.color(agg::rgba8(r, g, b, a));
00590 agg::render_scanlines(ras, m_sl, ren_fine);
00591 }
00592 else
00593 {
00594 ren_draft.color(agg::rgba8(r, g, b, a));
00595 agg::render_scanlines(ras, m_sl, ren_draft);
00596 }
00597 }
00598 break;
00599 }
00600 }
00601
00602
00603
00604
00605 void draw_lines_draft()
00606 {
00607 pixfmt pixf(rbuf_window());
00608 base_renderer rb(pixf);
00609 primitives_renderer prim(rb);
00610 outline_rasterizer ras(prim);
00611
00612 int i;
00613 for(i = 0; i < m_graph.get_num_edges(); i++)
00614 {
00615 graph::edge e = m_graph.get_edge(i);
00616 graph::node n1 = m_graph.get_node(e.node1, width(), height());
00617 graph::node n2 = m_graph.get_node(e.node2, width(), height());
00618 line l(n1.x, n1.y, n2.x, n2.y);
00619 stroke_draft<line> s(l, m_width.value());
00620
00621 int r = rand() & 0x7F;
00622 int g = rand() & 0x7F;
00623 int b = rand() & 0x7F;
00624 int a = 255;
00625 if(m_translucent.status()) a = 80;
00626 prim.line_color(agg::rgba8(r, g, b, a));
00627 ras.add_path(s);
00628 }
00629 }
00630
00631
00632
00633 void draw_curves_draft()
00634 {
00635 pixfmt pixf(rbuf_window());
00636 base_renderer rb(pixf);
00637 primitives_renderer prim(rb);
00638 outline_rasterizer ras(prim);
00639
00640 int i;
00641 for(i = 0; i < m_graph.get_num_edges(); i++)
00642 {
00643 graph::edge e = m_graph.get_edge(i);
00644 graph::node n1 = m_graph.get_node(e.node1, width(), height());
00645 graph::node n2 = m_graph.get_node(e.node2, width(), height());
00646 curve c(n1.x, n1.y, n2.x, n2.y);
00647 stroke_draft<curve> s(c, m_width.value());
00648
00649 int r = rand() & 0x7F;
00650 int g = rand() & 0x7F;
00651 int b = rand() & 0x7F;
00652 int a = 255;
00653 if(m_translucent.status()) a = 80;
00654 prim.line_color(agg::rgba8(r, g, b, a));
00655 ras.add_path(s);
00656 }
00657 }
00658
00659
00660
00661 void draw_dashes_draft()
00662 {
00663 pixfmt pixf(rbuf_window());
00664 base_renderer rb(pixf);
00665 primitives_renderer prim(rb);
00666 outline_rasterizer ras(prim);
00667
00668 int i;
00669 for(i = 0; i < m_graph.get_num_edges(); i++)
00670 {
00671 graph::edge e = m_graph.get_edge(i);
00672 graph::node n1 = m_graph.get_node(e.node1, width(), height());
00673 graph::node n2 = m_graph.get_node(e.node2, width(), height());
00674 curve c(n1.x, n1.y, n2.x, n2.y);
00675 dash_stroke_draft<curve> s(c, 6.0, 3.0, m_width.value());
00676
00677 int r = rand() & 0x7F;
00678 int g = rand() & 0x7F;
00679 int b = rand() & 0x7F;
00680 int a = 255;
00681 if(m_translucent.status()) a = 80;
00682 prim.line_color(agg::rgba8(r, g, b, a));
00683 ras.add_path(s);
00684 }
00685 }
00686
00687
00688
00689 void draw_lines_fine(scanline_rasterizer& ras,
00690 solid_renderer& solid,
00691 draft_renderer& draft)
00692 {
00693 int i;
00694 for(i = 0; i < m_graph.get_num_edges(); i++)
00695 {
00696 graph::edge b = m_graph.get_edge(i);
00697 graph::node n1 = m_graph.get_node(b.node1, width(), height());
00698 graph::node n2 = m_graph.get_node(b.node2, width(), height());
00699 line l(n1.x, n1.y, n2.x, n2.y);
00700 stroke_fine<line> s(l, m_width.value());
00701 render_edge_fine(ras, solid, draft, s);
00702 }
00703 }
00704
00705
00706
00707 void draw_curves_fine(scanline_rasterizer& ras,
00708 solid_renderer& solid,
00709 draft_renderer& draft)
00710
00711 {
00712 int i;
00713 for(i = 0; i < m_graph.get_num_edges(); i++)
00714 {
00715 graph::edge b = m_graph.get_edge(i);
00716 graph::node n1 = m_graph.get_node(b.node1, width(), height());
00717 graph::node n2 = m_graph.get_node(b.node2, width(), height());
00718 curve c(n1.x, n1.y, n2.x, n2.y);
00719 stroke_fine<curve> s(c, m_width.value());
00720 render_edge_fine(ras, solid, draft, s);
00721 }
00722 }
00723
00724
00725
00726 void draw_dashes_fine(scanline_rasterizer& ras,
00727 solid_renderer& solid,
00728 draft_renderer& draft)
00729 {
00730 int i;
00731 for(i = 0; i < m_graph.get_num_edges(); i++)
00732 {
00733 graph::edge b = m_graph.get_edge(i);
00734 graph::node n1 = m_graph.get_node(b.node1, width(), height());
00735 graph::node n2 = m_graph.get_node(b.node2, width(), height());
00736 curve c(n1.x, n1.y, n2.x, n2.y);
00737 dash_stroke_fine<curve> s(c, 6.0, 3.0, m_width.value());
00738 render_edge_fine(ras, solid, draft, s);
00739 }
00740 }
00741
00742
00743
00744 void draw_polygons(scanline_rasterizer& ras,
00745 solid_renderer& solid,
00746 draft_renderer& draft)
00747 {
00748 int i;
00749 if(m_type.cur_item() == 4)
00750 {
00751 ras.gamma(agg::gamma_threshold(0.5));
00752 }
00753 for(i = 0; i < m_graph.get_num_edges(); i++)
00754 {
00755 graph::edge b = m_graph.get_edge(i);
00756 graph::node n1 = m_graph.get_node(b.node1, width(), height());
00757 graph::node n2 = m_graph.get_node(b.node2, width(), height());
00758 curve c(n1.x, n1.y, n2.x, n2.y);
00759 render_edge_fine(ras, solid, draft, c);
00760 }
00761 ras.gamma(agg::gamma_none());
00762 }
00763
00764
00765
00766
00767 void draw_scene(scanline_rasterizer& ras,
00768 solid_renderer& solid,
00769 draft_renderer& draft)
00770 {
00771 ras.gamma(agg::gamma_none());
00772 srand(100);
00773 if(m_draw_nodes.status())
00774 {
00775 if(m_draft.status())
00776 {
00777 draw_nodes_draft();
00778 }
00779 else
00780 {
00781 draw_nodes_fine(ras);
00782 }
00783 }
00784
00785 if(m_draw_edges.status())
00786 {
00787 if(m_draft.status())
00788 {
00789 switch(m_type.cur_item())
00790 {
00791 case 0: draw_lines_draft(); break;
00792 case 1: draw_curves_draft(); break;
00793 case 2: draw_dashes_draft(); break;
00794 }
00795 }
00796 else
00797 {
00798 switch(m_type.cur_item())
00799 {
00800 case 0: draw_lines_fine(ras, solid, draft); break;
00801 case 1: draw_curves_fine(ras, solid, draft); break;
00802 case 2: draw_dashes_fine(ras, solid, draft); break;
00803 case 3:
00804 case 4: draw_polygons(ras, solid, draft); break;
00805 }
00806 }
00807 }
00808 }
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 virtual void on_draw()
00823 {
00824 scanline_rasterizer ras;
00825
00826 pixfmt pixf(rbuf_window());
00827 base_renderer rb(pixf);
00828 solid_renderer solid(rb);
00829 draft_renderer draft(rb);
00830
00831 rb.clear(agg::rgba(1, 1, 1));
00832 draw_scene(ras, solid, draft);
00833
00834 ras.filling_rule(agg::fill_non_zero);
00835 agg::render_ctrl(ras, m_sl, rb, m_type);
00836 agg::render_ctrl(ras, m_sl, rb, m_width);
00837 agg::render_ctrl(ras, m_sl, rb, m_benchmark);
00838 agg::render_ctrl(ras, m_sl, rb, m_draw_nodes);
00839 agg::render_ctrl(ras, m_sl, rb, m_draw_edges);
00840 agg::render_ctrl(ras, m_sl, rb, m_draft);
00841 agg::render_ctrl(ras, m_sl, rb, m_translucent);
00842 }
00843
00844
00845
00846
00847 virtual void on_ctrl_change()
00848 {
00849 if(m_benchmark.status())
00850 {
00851 int i;
00852 on_draw();
00853 update_window();
00854
00855 scanline_rasterizer ras;
00856
00857 pixfmt pixf(rbuf_window());
00858 base_renderer rb(pixf);
00859 solid_renderer solid(rb);
00860 draft_renderer draft(rb);
00861
00862 char buf[256];
00863 if(m_draft.status())
00864 {
00865 start_timer();
00866 for(i = 0; i < 10; i++)
00867 {
00868 draw_scene(ras, solid, draft);
00869 }
00870 sprintf(buf, "%3.3f milliseconds", elapsed_time());
00871 }
00872 else
00873 {
00874 double times[5];
00875 for(m_draw = 0; m_draw < 4; m_draw++)
00876 {
00877 start_timer();
00878 for(i = 0; i < 10; i++)
00879 {
00880 draw_scene(ras, solid, draft);
00881 }
00882 times[m_draw] = elapsed_time();
00883 }
00884 m_draw = 3;
00885
00886 times[4] = times[3];
00887 times[3] -= times[2];
00888 times[2] -= times[1];
00889 times[1] -= times[0];
00890
00891 FILE* fd = fopen(full_file_name("benchmark"), "a");
00892 fprintf(fd, "%10.3f %10.3f %10.3f %10.3f %10.3f\n",
00893 times[0], times[1], times[2], times[3], times[4]);
00894 fclose(fd);
00895
00896
00897 sprintf(buf, " pipeline add_path sort render total\n"
00898 "%10.3f %10.3f %10.3f %10.3f %10.3f",
00899 times[0], times[1], times[2], times[3], times[4]);
00900 }
00901 message(buf);
00902
00903 m_benchmark.status(false);
00904 force_redraw();
00905 }
00906 }
00907 };
00908
00909
00910
00911 int agg_main(int argc, char* argv[])
00912 {
00913 the_application app(agg::pix_format_bgr24, flip_y);
00914 app.caption("AGG Example. Line Join");
00915
00916 if(app.init(600+100, 500+30, agg::window_resize))
00917 {
00918 return app.run();
00919 }
00920 return 1;
00921 }
00922
00923