1 #include <math.h>
2 #include <stdio.h>
3 #include "agg_basics.h"
4 #include "agg_rendering_buffer.h"
5 #include "agg_rasterizer_scanline_aa.h"
6 #include "agg_rasterizer_outline.h"
7 #include "agg_conv_stroke.h"
8 #include "agg_conv_dash.h"
9 #include "agg_conv_curve.h"
10 #include "agg_conv_contour.h"
11 #include "agg_conv_marker.h"
12 #include "agg_conv_shorten_path.h"
13 #include "agg_conv_marker_adaptor.h"
14 #include "agg_conv_concat.h"
15 #include "agg_arrowhead.h"
16 #include "agg_vcgen_markers_term.h"
17 #include "agg_scanline_p.h"
18 #include "agg_scanline_u.h"
19 #include "agg_renderer_scanline.h"
20 #include "agg_renderer_primitives.h"
21 #include "agg_span_allocator.h"
22 #include "agg_span_gradient.h"
23 #include "agg_span_interpolator_linear.h"
24 #include "agg_pixfmt_rgb.h"
25 #include "ctrl/agg_slider_ctrl.h"
26 #include "ctrl/agg_rbox_ctrl.h"
27 #include "ctrl/agg_cbox_ctrl.h"
28 #include "platform/agg_platform_support.h"
29
30 enum flip_y_e { flip_y = true };
31
32
33 typedef agg::pixfmt_bgr24 pixfmt;
34 typedef pixfmt::color_type color_type;
35 typedef agg::renderer_base<pixfmt> base_renderer;
36 typedef agg::renderer_primitives<base_renderer> primitives_renderer;
37
38 typedef agg::renderer_scanline_aa_solid<base_renderer> solid_renderer;
39 typedef agg::renderer_scanline_bin_solid<base_renderer> draft_renderer;
40
41 typedef agg::gradient_radial_d gradient_function;
42 typedef agg::span_interpolator_linear<> interpolator;
43 typedef agg::pod_auto_array<color_type, 256> color_array_type;
44 typedef agg::span_gradient<color_type,
45 interpolator,
46 gradient_function,
47 color_array_type> gradient_span_gen;
48 typedef agg::span_allocator<color_type> gradient_span_alloc;
49
50 typedef agg::renderer_scanline_aa<base_renderer,
51 gradient_span_alloc,
52 gradient_span_gen> gradient_renderer;
53
54 typedef agg::rasterizer_scanline_aa<> scanline_rasterizer;
55 typedef agg::rasterizer_outline<primitives_renderer> outline_rasterizer;
56
57
58
59 //============================================================================
60 class graph
61 {
62 public:
63 struct node
64 {
65 double x, y;
nodegraph::node66 node() {}
nodegraph::node67 node(double x_, double y_) : x(x_), y(y_) {}
68 };
69
70 struct edge
71 {
72 int node1;
73 int node2;
edgegraph::edge74 edge() {}
edgegraph::edge75 edge(int n1, int n2) : node1(n1), node2(n2) {}
76 };
77
~graph()78 ~graph()
79 {
80 delete [] m_edges;
81 delete [] m_nodes;
82 }
83
graph(int num_nodes,int num_edges)84 graph(int num_nodes, int num_edges) :
85 m_num_nodes(num_nodes),
86 m_num_edges(num_edges),
87 m_nodes(new node[num_nodes]),
88 m_edges(new edge[num_edges])
89 {
90 int i;
91
92 srand(100);
93
94 for(i = 0; i < m_num_nodes; i++)
95 {
96 m_nodes[i].x = (double(rand()) / RAND_MAX) * 0.75 + 0.2;
97 m_nodes[i].y = (double(rand()) / RAND_MAX) * 0.85 + 0.1;
98 }
99
100 for(i = 0; i < m_num_edges; i++)
101 {
102 m_edges[i].node1 = rand() % m_num_nodes;
103 m_edges[i].node2 = rand() % m_num_nodes;
104 if(m_edges[i].node1 == m_edges[i].node2) i--;
105 }
106 }
107
get_num_nodes() const108 int get_num_nodes() const { return m_num_nodes; }
get_num_edges() const109 int get_num_edges() const { return m_num_edges; }
110
get_node(int idx,double w,double h) const111 node get_node(int idx, double w, double h) const
112 {
113 node p(0.0, 0.0);
114 if(idx < m_num_nodes)
115 {
116 p = m_nodes[idx];
117 p.x = p.x * w;
118 p.y = p.y * h;
119 }
120 return p;
121 }
122
get_edge(int idx) const123 edge get_edge(int idx) const
124 {
125 edge b(0,0);
126 if(idx < m_num_edges)
127 {
128 b = m_edges[idx];
129 }
130 return b;
131 }
132
133 private:
134 graph(const graph&);
135 const graph& operator = (const graph&);
136
137 int m_num_nodes;
138 int m_num_edges;
139 node* m_nodes;
140 edge* m_edges;
141 };
142
143
144
145
146
147
148
149
150
151 //============================================================================
152 struct line
153 {
154 double x1, y1, x2, y2;
155 int f;
156
lineline157 line(double x1_, double y1_, double x2_, double y2_) :
158 x1(x1_), y1(y1_), x2(x2_), y2(y2_), f(0) {}
159
rewindline160 void rewind(unsigned) { f = 0; }
vertexline161 unsigned vertex(double* x, double* y)
162 {
163 if(f == 0) { ++f; *x = x1; *y = y1; return agg::path_cmd_move_to; }
164 if(f == 1) { ++f; *x = x2; *y = y2; return agg::path_cmd_line_to; }
165 return agg::path_cmd_stop;
166 }
167 };
168
169
170
171
172 //============================================================================
173 struct curve
174 {
175 agg::curve4 c;
176
curvecurve177 curve(double x1, double y1, double x2, double y2, double k=0.5)
178 {
179 c.init(x1, y1,
180 x1 - (y2 - y1) * k,
181 y1 + (x2 - x1) * k,
182 x2 + (y2 - y1) * k,
183 y2 - (x2 - x1) * k,
184 x2, y2);
185 }
186
rewindcurve187 void rewind(unsigned path_id) { c.rewind(path_id); }
vertexcurve188 unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
189 };
190
191
192
193 //============================================================================
194 template<class Source> struct stroke_draft_simple
195 {
196 Source& s;
stroke_draft_simplestroke_draft_simple197 stroke_draft_simple(Source& src, double w) :
198 s(src)
199 {
200 }
201
rewindstroke_draft_simple202 void rewind(unsigned path_id) { s.rewind(path_id); }
vertexstroke_draft_simple203 unsigned vertex(double* x, double* y) { return s.vertex(x, y); }
204 };
205
206
207 //============================================================================
208 template<class Source> struct stroke_draft_arrow
209 {
210 typedef agg::conv_marker_adaptor<Source, agg::vcgen_markers_term> stroke_type;
211 typedef agg::conv_marker<typename stroke_type::marker_type, agg::arrowhead> marker_type;
212 typedef agg::conv_concat<stroke_type, marker_type> concat_type;
213
214 stroke_type s;
215 agg::arrowhead ah;
216 marker_type m;
217 concat_type c;
218
stroke_draft_arrowstroke_draft_arrow219 stroke_draft_arrow(Source& src, double w) :
220 s(src),
221 ah(),
222 m(s.markers(), ah),
223 c(s, m)
224 {
225 ah.head(0, 10, 5, 0);
226 s.shorten(10.0);
227 }
228
rewindstroke_draft_arrow229 void rewind(unsigned path_id) { c.rewind(path_id); }
vertexstroke_draft_arrow230 unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
231 };
232
233
234
235 //============================================================================
236 template<class Source> struct stroke_fine_simple
237 {
238 typedef agg::conv_stroke<Source> stroke_type;
239
240 stroke_type s;
241
stroke_fine_simplestroke_fine_simple242 stroke_fine_simple(Source& src, double w) :
243 s(src)
244 {
245 s.width(w);
246 }
rewindstroke_fine_simple247 void rewind(unsigned path_id) { s.rewind(path_id); }
vertexstroke_fine_simple248 unsigned vertex(double* x, double* y) { return s.vertex(x, y); }
249 };
250
251
252
253 //============================================================================
254 template<class Source> struct stroke_fine_arrow
255 {
256 typedef agg::conv_stroke<Source, agg::vcgen_markers_term> stroke_type;
257 typedef agg::conv_marker<typename stroke_type::marker_type, agg::arrowhead> marker_type;
258 typedef agg::conv_concat<stroke_type, marker_type> concat_type;
259
260 stroke_type s;
261 agg::arrowhead ah;
262 marker_type m;
263 concat_type c;
264
stroke_fine_arrowstroke_fine_arrow265 stroke_fine_arrow(Source& src, double w) :
266 s(src),
267 ah(),
268 m(s.markers(), ah),
269 c(s, m)
270 {
271 s.width(w);
272 ah.head(0, 10, 5, 0);
273 s.shorten(w * 2.0);
274 }
275
rewindstroke_fine_arrow276 void rewind(unsigned path_id) { c.rewind(path_id); }
vertexstroke_fine_arrow277 unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
278 };
279
280
281
282 //============================================================================
283 template<class Source> struct dash_stroke_draft_simple
284 {
285 typedef agg::conv_dash<Source, agg::vcgen_markers_term> dash_type;
286
287 dash_type d;
288
dash_stroke_draft_simpledash_stroke_draft_simple289 dash_stroke_draft_simple(Source& src,
290 double dash_len,
291 double gap_len,
292 double w) :
293 d(src)
294 {
295 d.add_dash(dash_len, gap_len);
296 }
297
rewinddash_stroke_draft_simple298 void rewind(unsigned path_id) { d.rewind(path_id); }
vertexdash_stroke_draft_simple299 unsigned vertex(double* x, double* y) { return d.vertex(x, y); }
300 };
301
302
303 //============================================================================
304 template<class Source> struct dash_stroke_draft_arrow
305 {
306 typedef agg::conv_dash<Source, agg::vcgen_markers_term> dash_type;
307 typedef agg::conv_marker<typename dash_type::marker_type, agg::arrowhead> marker_type;
308 typedef agg::conv_concat<dash_type, marker_type> concat_type;
309
310 dash_type d;
311 agg::arrowhead ah;
312 marker_type m;
313 concat_type c;
314
dash_stroke_draft_arrowdash_stroke_draft_arrow315 dash_stroke_draft_arrow(Source& src,
316 double dash_len, double gap_len, double w) :
317 d(src),
318 ah(),
319 m(d.markers(), ah),
320 c(d, m)
321 {
322 d.add_dash(dash_len, gap_len);
323 ah.head(0, 10, 5, 0);
324 d.shorten(10.0);
325 }
326
rewinddash_stroke_draft_arrow327 void rewind(unsigned path_id) { c.rewind(path_id); }
vertexdash_stroke_draft_arrow328 unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
329 };
330
331
332
333
334 //============================================================================
335 template<class Source> struct dash_stroke_fine_simple
336 {
337 typedef agg::conv_dash<Source> dash_type;
338 typedef agg::conv_stroke<dash_type> stroke_type;
339
340 dash_type d;
341 stroke_type s;
342
dash_stroke_fine_simpledash_stroke_fine_simple343 dash_stroke_fine_simple(Source& src,
344 double dash_len, double gap_len, double w) :
345 d(src),
346 s(d)
347 {
348 d.add_dash(dash_len, gap_len);
349 s.width(w);
350 }
351
rewinddash_stroke_fine_simple352 void rewind(unsigned path_id) { s.rewind(path_id); }
vertexdash_stroke_fine_simple353 unsigned vertex(double* x, double* y) { return s.vertex(x, y); }
354 };
355
356
357
358
359
360
361 //============================================================================
362 template<class Source> struct dash_stroke_fine_arrow
363 {
364 typedef agg::conv_dash<Source, agg::vcgen_markers_term> dash_type;
365 typedef agg::conv_stroke<dash_type> stroke_type;
366 typedef agg::conv_marker<typename dash_type::marker_type, agg::arrowhead> marker_type;
367 typedef agg::conv_concat<stroke_type, marker_type> concat_type;
368
369 dash_type d;
370 stroke_type s;
371 agg::arrowhead ah;
372 marker_type m;
373 concat_type c;
374
dash_stroke_fine_arrowdash_stroke_fine_arrow375 dash_stroke_fine_arrow(Source& src,
376 double dash_len, double gap_len, double w) :
377 d(src),
378 s(d),
379 ah(),
380 m(d.markers(), ah),
381 c(s, m)
382 {
383 d.add_dash(dash_len, gap_len);
384 s.width(w);
385 ah.head(0, 10, 5, 0);
386 d.shorten(w * 2.0);
387 }
388
rewinddash_stroke_fine_arrow389 void rewind(unsigned path_id) { c.rewind(path_id); }
vertexdash_stroke_fine_arrow390 unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
391 };
392
393
394
395 //#define stroke_draft stroke_draft_simple
396 //#define dash_stroke_draft dash_stroke_draft_simple
397 //#define stroke_fine stroke_fine_simple
398 //#define dash_stroke_fine dash_stroke_fine_simple
399
400 #define stroke_draft stroke_draft_arrow
401 #define dash_stroke_draft dash_stroke_draft_arrow
402 #define stroke_fine stroke_fine_arrow
403 #define dash_stroke_fine dash_stroke_fine_arrow
404
405
406
407
408
409 class the_application : public agg::platform_support
410 {
411 agg::rbox_ctrl<agg::rgba> m_type;
412 agg::slider_ctrl<agg::rgba> m_width;
413 agg::cbox_ctrl<agg::rgba> m_benchmark;
414 agg::cbox_ctrl<agg::rgba> m_draw_nodes;
415 agg::cbox_ctrl<agg::rgba> m_draw_edges;
416 agg::cbox_ctrl<agg::rgba> m_draft;
417 agg::cbox_ctrl<agg::rgba> m_translucent;
418 graph m_graph;
419 color_array_type m_gradient_colors;
420 int m_draw;
421 agg::scanline_u8 m_sl;
422
423
424 public:
the_application(agg::pix_format_e format,bool flip_y)425 the_application(agg::pix_format_e format, bool flip_y) :
426 agg::platform_support(format, flip_y),
427 m_type(-1, -1, -1, -1, !flip_y),
428 m_width(110+80, 8.0, 110+200.0+80, 8.0 + 7.0, !flip_y),
429 m_benchmark(110+200+80+8, 8.0-2.0, "Benchmark", !flip_y),
430 m_draw_nodes(110+200+80+8, 8.0-2.0+15.0, "Draw Nodes", !flip_y),
431 m_draw_edges(200+200+80+8, 8.0-2.0+15.0, "Draw Edges", !flip_y),
432 m_draft(200+200+80+8, 8.0-2.0, "Draft Mode", !flip_y),
433 m_translucent(110+80, 8.0-2.0+15.0, "Translucent Mode", !flip_y),
434 m_graph(200, 100),
435 m_gradient_colors(),
436 m_draw(3)
437 {
438 add_ctrl(m_type);
439 m_type.text_size(8.0);
440 m_type.add_item("Solid lines");
441 m_type.add_item("Bezier curves");
442 m_type.add_item("Dashed curves");
443 m_type.add_item("Poygons AA");
444 m_type.add_item("Poygons Bin");
445 m_type.cur_item(0);
446
447 add_ctrl(m_width);
448 m_width.num_steps(20);
449 m_width.range(0.0, 5.0);
450 m_width.value(2.0);
451 m_width.label("Width=%1.2f");
452
453 m_benchmark.text_size(8.0);
454 m_draw_nodes.text_size(8.0);
455 m_draft.text_size(8.0);
456 m_draw_nodes.status(true);
457 m_draw_edges.status(true);
458 add_ctrl(m_benchmark);
459 add_ctrl(m_draw_nodes);
460 add_ctrl(m_draw_edges);
461 add_ctrl(m_draft);
462 add_ctrl(m_translucent);
463
464 agg::rgba c1(1, 1, 0, 0.25);
465 agg::rgba c2(0, 0, 1);
466
467 int i;
468 for(i = 0; i < 256; i++)
469 {
470 m_gradient_colors[i] = c1.gradient(c2, double(i) / 255.0);
471 }
472 }
473
474
475
476
477
478
479 //------------------------------------------------------------------------
draw_nodes_draft()480 void draw_nodes_draft()
481 {
482 pixfmt pixf(rbuf_window());
483 base_renderer rb(pixf);
484 primitives_renderer prim(rb);
485 int i;
486 for(i = 0; i < m_graph.get_num_nodes(); i++)
487 {
488 graph::node n = m_graph.get_node(i, width(), height());
489 prim.fill_color(m_gradient_colors[147]);
490 prim.line_color(m_gradient_colors[255]);
491 prim.outlined_ellipse(int(n.x), int(n.y), 10, 10);
492 prim.fill_color(m_gradient_colors[50]);
493 prim.solid_ellipse(int(n.x), int(n.y), 4, 4);
494 }
495 }
496
497
498
499 //------------------------------------------------------------------------
draw_nodes_fine(scanline_rasterizer & ras)500 void draw_nodes_fine(scanline_rasterizer& ras)
501 {
502 gradient_span_alloc sa;
503 pixfmt pixf(rbuf_window());
504 base_renderer rb(pixf);
505 int i;
506 for(i = 0; i < m_graph.get_num_nodes(); i++)
507 {
508 graph::node n = m_graph.get_node(i, width(), height());
509 agg::ellipse ell(n.x, n.y, 5.0 * m_width.value(), 5.0 * m_width.value());
510
511 double x, y;
512 switch(m_draw)
513 {
514 case 0:
515 ell.rewind(0);
516 while(!agg::is_stop(ell.vertex(&x, &y)));
517 break;
518
519 case 1:
520 ras.reset();
521 ras.add_path(ell);
522 break;
523
524 case 2:
525 ras.reset();
526 ras.add_path(ell);
527 ras.sort();
528 break;
529
530 case 3:
531 {
532 gradient_function gf;
533 agg::trans_affine mtx;
534 mtx *= agg::trans_affine_scaling(m_width.value() / 2.0);
535 mtx *= agg::trans_affine_translation(n.x, n.y);
536 mtx.invert();
537 interpolator inter(mtx);
538 gradient_span_gen sg(inter, gf, m_gradient_colors, 0.0, 10.0);
539 gradient_renderer ren(rb, sa, sg);
540 ras.add_path(ell);
541 agg::render_scanlines(ras, m_sl, ren);
542 }
543 break;
544 }
545 }
546 }
547
548
549
550
551
552 //------------------------------------------------------------------------
553 template<class Source>
render_edge_fine(scanline_rasterizer & ras,solid_renderer & ren_fine,draft_renderer & ren_draft,Source & src)554 void render_edge_fine(scanline_rasterizer& ras,
555 solid_renderer& ren_fine,
556 draft_renderer& ren_draft,
557 Source& src)
558 {
559 double x, y;
560 switch(m_draw)
561 {
562 case 0:
563 src.rewind(0);
564 while(!agg::is_stop(src.vertex(&x, &y)));
565 break;
566
567 case 1:
568 ras.reset();
569 ras.add_path(src);
570 break;
571
572 case 2:
573 ras.reset();
574 ras.add_path(src);
575 ras.sort();
576 break;
577
578 case 3:
579 {
580 int r = rand() & 0x7F;
581 int g = rand() & 0x7F;
582 int b = rand() & 0x7F;
583 int a = 255;
584 if(m_translucent.status()) a = 80;
585 ras.add_path(src);
586
587 if(m_type.cur_item() < 4)
588 {
589 ren_fine.color(agg::rgba8(r, g, b, a));
590 agg::render_scanlines(ras, m_sl, ren_fine);
591 }
592 else
593 {
594 ren_draft.color(agg::rgba8(r, g, b, a));
595 agg::render_scanlines(ras, m_sl, ren_draft);
596 }
597 }
598 break;
599 }
600 }
601
602
603
604 //------------------------------------------------------------------------
draw_lines_draft()605 void draw_lines_draft()
606 {
607 pixfmt pixf(rbuf_window());
608 base_renderer rb(pixf);
609 primitives_renderer prim(rb);
610 outline_rasterizer ras(prim);
611
612 int i;
613 for(i = 0; i < m_graph.get_num_edges(); i++)
614 {
615 graph::edge e = m_graph.get_edge(i);
616 graph::node n1 = m_graph.get_node(e.node1, width(), height());
617 graph::node n2 = m_graph.get_node(e.node2, width(), height());
618 line l(n1.x, n1.y, n2.x, n2.y);
619 stroke_draft<line> s(l, m_width.value());
620
621 int r = rand() & 0x7F;
622 int g = rand() & 0x7F;
623 int b = rand() & 0x7F;
624 int a = 255;
625 if(m_translucent.status()) a = 80;
626 prim.line_color(agg::rgba8(r, g, b, a));
627 ras.add_path(s);
628 }
629 }
630
631
632 //------------------------------------------------------------------------
draw_curves_draft()633 void draw_curves_draft()
634 {
635 pixfmt pixf(rbuf_window());
636 base_renderer rb(pixf);
637 primitives_renderer prim(rb);
638 outline_rasterizer ras(prim);
639
640 int i;
641 for(i = 0; i < m_graph.get_num_edges(); i++)
642 {
643 graph::edge e = m_graph.get_edge(i);
644 graph::node n1 = m_graph.get_node(e.node1, width(), height());
645 graph::node n2 = m_graph.get_node(e.node2, width(), height());
646 curve c(n1.x, n1.y, n2.x, n2.y);
647 stroke_draft<curve> s(c, m_width.value());
648
649 int r = rand() & 0x7F;
650 int g = rand() & 0x7F;
651 int b = rand() & 0x7F;
652 int a = 255;
653 if(m_translucent.status()) a = 80;
654 prim.line_color(agg::rgba8(r, g, b, a));
655 ras.add_path(s);
656 }
657 }
658
659
660 //------------------------------------------------------------------------
draw_dashes_draft()661 void draw_dashes_draft()
662 {
663 pixfmt pixf(rbuf_window());
664 base_renderer rb(pixf);
665 primitives_renderer prim(rb);
666 outline_rasterizer ras(prim);
667
668 int i;
669 for(i = 0; i < m_graph.get_num_edges(); i++)
670 {
671 graph::edge e = m_graph.get_edge(i);
672 graph::node n1 = m_graph.get_node(e.node1, width(), height());
673 graph::node n2 = m_graph.get_node(e.node2, width(), height());
674 curve c(n1.x, n1.y, n2.x, n2.y);
675 dash_stroke_draft<curve> s(c, 6.0, 3.0, m_width.value());
676
677 int r = rand() & 0x7F;
678 int g = rand() & 0x7F;
679 int b = rand() & 0x7F;
680 int a = 255;
681 if(m_translucent.status()) a = 80;
682 prim.line_color(agg::rgba8(r, g, b, a));
683 ras.add_path(s);
684 }
685 }
686
687
688 //------------------------------------------------------------------------
draw_lines_fine(scanline_rasterizer & ras,solid_renderer & solid,draft_renderer & draft)689 void draw_lines_fine(scanline_rasterizer& ras,
690 solid_renderer& solid,
691 draft_renderer& draft)
692 {
693 int i;
694 for(i = 0; i < m_graph.get_num_edges(); i++)
695 {
696 graph::edge b = m_graph.get_edge(i);
697 graph::node n1 = m_graph.get_node(b.node1, width(), height());
698 graph::node n2 = m_graph.get_node(b.node2, width(), height());
699 line l(n1.x, n1.y, n2.x, n2.y);
700 stroke_fine<line> s(l, m_width.value());
701 render_edge_fine(ras, solid, draft, s);
702 }
703 }
704
705
706 //------------------------------------------------------------------------
draw_curves_fine(scanline_rasterizer & ras,solid_renderer & solid,draft_renderer & draft)707 void draw_curves_fine(scanline_rasterizer& ras,
708 solid_renderer& solid,
709 draft_renderer& draft)
710
711 {
712 int i;
713 for(i = 0; i < m_graph.get_num_edges(); i++)
714 {
715 graph::edge b = m_graph.get_edge(i);
716 graph::node n1 = m_graph.get_node(b.node1, width(), height());
717 graph::node n2 = m_graph.get_node(b.node2, width(), height());
718 curve c(n1.x, n1.y, n2.x, n2.y);
719 stroke_fine<curve> s(c, m_width.value());
720 render_edge_fine(ras, solid, draft, s);
721 }
722 }
723
724
725 //------------------------------------------------------------------------
draw_dashes_fine(scanline_rasterizer & ras,solid_renderer & solid,draft_renderer & draft)726 void draw_dashes_fine(scanline_rasterizer& ras,
727 solid_renderer& solid,
728 draft_renderer& draft)
729 {
730 int i;
731 for(i = 0; i < m_graph.get_num_edges(); i++)
732 {
733 graph::edge b = m_graph.get_edge(i);
734 graph::node n1 = m_graph.get_node(b.node1, width(), height());
735 graph::node n2 = m_graph.get_node(b.node2, width(), height());
736 curve c(n1.x, n1.y, n2.x, n2.y);
737 dash_stroke_fine<curve> s(c, 6.0, 3.0, m_width.value());
738 render_edge_fine(ras, solid, draft, s);
739 }
740 }
741
742
743 //------------------------------------------------------------------------
draw_polygons(scanline_rasterizer & ras,solid_renderer & solid,draft_renderer & draft)744 void draw_polygons(scanline_rasterizer& ras,
745 solid_renderer& solid,
746 draft_renderer& draft)
747 {
748 int i;
749 if(m_type.cur_item() == 4)
750 {
751 ras.gamma(agg::gamma_threshold(0.5));
752 }
753 for(i = 0; i < m_graph.get_num_edges(); i++)
754 {
755 graph::edge b = m_graph.get_edge(i);
756 graph::node n1 = m_graph.get_node(b.node1, width(), height());
757 graph::node n2 = m_graph.get_node(b.node2, width(), height());
758 curve c(n1.x, n1.y, n2.x, n2.y);
759 render_edge_fine(ras, solid, draft, c);
760 }
761 ras.gamma(agg::gamma_none());
762 }
763
764
765
766 //------------------------------------------------------------------------
draw_scene(scanline_rasterizer & ras,solid_renderer & solid,draft_renderer & draft)767 void draw_scene(scanline_rasterizer& ras,
768 solid_renderer& solid,
769 draft_renderer& draft)
770 {
771 ras.gamma(agg::gamma_none());
772 srand(100);
773 if(m_draw_nodes.status())
774 {
775 if(m_draft.status())
776 {
777 draw_nodes_draft();
778 }
779 else
780 {
781 draw_nodes_fine(ras);
782 }
783 }
784
785 if(m_draw_edges.status())
786 {
787 if(m_draft.status())
788 {
789 switch(m_type.cur_item())
790 {
791 case 0: draw_lines_draft(); break;
792 case 1: draw_curves_draft(); break;
793 case 2: draw_dashes_draft(); break;
794 }
795 }
796 else
797 {
798 switch(m_type.cur_item())
799 {
800 case 0: draw_lines_fine(ras, solid, draft); break;
801 case 1: draw_curves_fine(ras, solid, draft); break;
802 case 2: draw_dashes_fine(ras, solid, draft); break;
803 case 3:
804 case 4: draw_polygons(ras, solid, draft); break;
805 }
806 }
807 }
808 }
809
810
811
812
813
814
815
816
817
818
819
820
821 //------------------------------------------------------------------------
on_draw()822 virtual void on_draw()
823 {
824 scanline_rasterizer ras;
825
826 pixfmt pixf(rbuf_window());
827 base_renderer rb(pixf);
828 solid_renderer solid(rb);
829 draft_renderer draft(rb);
830
831 rb.clear(agg::rgba(1, 1, 1));
832 draw_scene(ras, solid, draft);
833
834 ras.filling_rule(agg::fill_non_zero);
835 agg::render_ctrl(ras, m_sl, rb, m_type);
836 agg::render_ctrl(ras, m_sl, rb, m_width);
837 agg::render_ctrl(ras, m_sl, rb, m_benchmark);
838 agg::render_ctrl(ras, m_sl, rb, m_draw_nodes);
839 agg::render_ctrl(ras, m_sl, rb, m_draw_edges);
840 agg::render_ctrl(ras, m_sl, rb, m_draft);
841 agg::render_ctrl(ras, m_sl, rb, m_translucent);
842 }
843
844
845
846
on_ctrl_change()847 virtual void on_ctrl_change()
848 {
849 if(m_benchmark.status())
850 {
851 int i;
852 on_draw();
853 update_window();
854
855 scanline_rasterizer ras;
856
857 pixfmt pixf(rbuf_window());
858 base_renderer rb(pixf);
859 solid_renderer solid(rb);
860 draft_renderer draft(rb);
861
862 char buf[256];
863 if(m_draft.status())
864 {
865 start_timer();
866 for(i = 0; i < 10; i++)
867 {
868 draw_scene(ras, solid, draft);
869 }
870 sprintf(buf, "%3.3f milliseconds", elapsed_time());
871 }
872 else
873 {
874 double times[5];
875 for(m_draw = 0; m_draw < 4; m_draw++)
876 {
877 start_timer();
878 for(i = 0; i < 10; i++)
879 {
880 draw_scene(ras, solid, draft);
881 }
882 times[m_draw] = elapsed_time();
883 }
884 m_draw = 3;
885
886 times[4] = times[3];
887 times[3] -= times[2];
888 times[2] -= times[1];
889 times[1] -= times[0];
890
891 FILE* fd = fopen(full_file_name("benchmark"), "a");
892 fprintf(fd, "%10.3f %10.3f %10.3f %10.3f %10.3f\n",
893 times[0], times[1], times[2], times[3], times[4]);
894 fclose(fd);
895
896
897 sprintf(buf, " pipeline add_path sort render total\n"
898 "%10.3f %10.3f %10.3f %10.3f %10.3f",
899 times[0], times[1], times[2], times[3], times[4]);
900 }
901 message(buf);
902
903 m_benchmark.status(false);
904 force_redraw();
905 }
906 }
907 };
908
909
910
agg_main(int argc,char * argv[])911 int agg_main(int argc, char* argv[])
912 {
913 the_application app(agg::pix_format_bgr24, flip_y);
914 app.caption("AGG Example. Line Join");
915
916 if(app.init(600+100, 500+30, agg::window_resize))
917 {
918 return app.run();
919 }
920 return 1;
921 }
922
923
924