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_conv_curve.h"
7 #include "agg_conv_contour.h"
8 #include "agg_conv_stroke.h"
9 #include "agg_scanline_p.h"
10 #include "agg_renderer_scanline.h"
11 #include "agg_pixfmt_rgb.h"
12 #include "agg_pixfmt_rgba.h"
13 #include "agg_pixfmt_gray.h"
14 #include "agg_bounding_rect.h"
15 #include "agg_trans_perspective.h"
16 #include "agg_blur.h"
17 #include "ctrl/agg_slider_ctrl.h"
18 #include "ctrl/agg_rbox_ctrl.h"
19 #include "ctrl/agg_cbox_ctrl.h"
20 #include "ctrl/agg_polygon_ctrl.h"
21 #include "platform/agg_platform_support.h"
22
23 //#define AGG_GRAY8
24 #define AGG_BGR24
25 //#define AGG_BGR48
26 //#define AGG_RGB_AAA
27 //#define AGG_BGRA32
28 //#define AGG_RGBA32
29 //#define AGG_ARGB32
30 //#define AGG_ABGR32
31 //#define AGG_RGB565
32 //#define AGG_RGB555
33 #include "pixel_formats.h"
34
35
36 static agg::int8u g_gradient_colors[] =
37 {
38 255, 255, 255, 255,
39 255, 255, 254, 255,
40 255, 255, 254, 255,
41 255, 255, 254, 255,
42 255, 255, 253, 255,
43 255, 255, 253, 255,
44 255, 255, 252, 255,
45 255, 255, 251, 255,
46 255, 255, 250, 255,
47 255, 255, 248, 255,
48 255, 255, 246, 255,
49 255, 255, 244, 255,
50 255, 255, 241, 255,
51 255, 255, 238, 255,
52 255, 255, 235, 255,
53 255, 255, 231, 255,
54 255, 255, 227, 255,
55 255, 255, 222, 255,
56 255, 255, 217, 255,
57 255, 255, 211, 255,
58 255, 255, 206, 255,
59 255, 255, 200, 255,
60 255, 254, 194, 255,
61 255, 253, 188, 255,
62 255, 252, 182, 255,
63 255, 250, 176, 255,
64 255, 249, 170, 255,
65 255, 247, 164, 255,
66 255, 246, 158, 255,
67 255, 244, 152, 255,
68 254, 242, 146, 255,
69 254, 240, 141, 255,
70 254, 238, 136, 255,
71 254, 236, 131, 255,
72 253, 234, 126, 255,
73 253, 232, 121, 255,
74 253, 229, 116, 255,
75 252, 227, 112, 255,
76 252, 224, 108, 255,
77 251, 222, 104, 255,
78 251, 219, 100, 255,
79 251, 216, 96, 255,
80 250, 214, 93, 255,
81 250, 211, 89, 255,
82 249, 208, 86, 255,
83 249, 205, 83, 255,
84 248, 202, 80, 255,
85 247, 199, 77, 255,
86 247, 196, 74, 255,
87 246, 193, 72, 255,
88 246, 190, 69, 255,
89 245, 187, 67, 255,
90 244, 183, 64, 255,
91 244, 180, 62, 255,
92 243, 177, 60, 255,
93 242, 174, 58, 255,
94 242, 170, 56, 255,
95 241, 167, 54, 255,
96 240, 164, 52, 255,
97 239, 161, 51, 255,
98 239, 157, 49, 255,
99 238, 154, 47, 255,
100 237, 151, 46, 255,
101 236, 147, 44, 255,
102 235, 144, 43, 255,
103 235, 141, 41, 255,
104 234, 138, 40, 255,
105 233, 134, 39, 255,
106 232, 131, 37, 255,
107 231, 128, 36, 255,
108 230, 125, 35, 255,
109 229, 122, 34, 255,
110 228, 119, 33, 255,
111 227, 116, 31, 255,
112 226, 113, 30, 255,
113 225, 110, 29, 255,
114 224, 107, 28, 255,
115 223, 104, 27, 255,
116 222, 101, 26, 255,
117 221, 99, 25, 255,
118 220, 96, 24, 255,
119 219, 93, 23, 255,
120 218, 91, 22, 255,
121 217, 88, 21, 255,
122 216, 86, 20, 255,
123 215, 83, 19, 255,
124 214, 81, 18, 255,
125 213, 79, 17, 255,
126 212, 77, 17, 255,
127 211, 74, 16, 255,
128 210, 72, 15, 255,
129 209, 70, 14, 255,
130 207, 68, 13, 255,
131 206, 66, 13, 255,
132 205, 64, 12, 255,
133 204, 62, 11, 255,
134 203, 60, 10, 255,
135 202, 58, 10, 255,
136 201, 56, 9, 255,
137 199, 55, 9, 255,
138 198, 53, 8, 255,
139 197, 51, 7, 255,
140 196, 50, 7, 255,
141 195, 48, 6, 255,
142 193, 46, 6, 255,
143 192, 45, 5, 255,
144 191, 43, 5, 255,
145 190, 42, 4, 255,
146 188, 41, 4, 255,
147 187, 39, 3, 255,
148 186, 38, 3, 255,
149 185, 37, 2, 255,
150 183, 35, 2, 255,
151 182, 34, 1, 255,
152 181, 33, 1, 255,
153 179, 32, 1, 255,
154 178, 30, 0, 255,
155 177, 29, 0, 255,
156 175, 28, 0, 255,
157 174, 27, 0, 255,
158 173, 26, 0, 255,
159 171, 25, 0, 255,
160 170, 24, 0, 255,
161 168, 23, 0, 255,
162 167, 22, 0, 255,
163 165, 21, 0, 255,
164 164, 21, 0, 255,
165 163, 20, 0, 255,
166 161, 19, 0, 255,
167 160, 18, 0, 255,
168 158, 17, 0, 255,
169 156, 17, 0, 255,
170 155, 16, 0, 255,
171 153, 15, 0, 255,
172 152, 14, 0, 255,
173 150, 14, 0, 255,
174 149, 13, 0, 255,
175 147, 12, 0, 255,
176 145, 12, 0, 255,
177 144, 11, 0, 255,
178 142, 11, 0, 255,
179 140, 10, 0, 255,
180 139, 10, 0, 255,
181 137, 9, 0, 255,
182 135, 9, 0, 255,
183 134, 8, 0, 255,
184 132, 8, 0, 255,
185 130, 7, 0, 255,
186 128, 7, 0, 255,
187 126, 6, 0, 255,
188 125, 6, 0, 255,
189 123, 5, 0, 255,
190 121, 5, 0, 255,
191 119, 4, 0, 255,
192 117, 4, 0, 255,
193 115, 4, 0, 255,
194 113, 3, 0, 255,
195 111, 3, 0, 255,
196 109, 2, 0, 255,
197 107, 2, 0, 255,
198 105, 2, 0, 255,
199 103, 1, 0, 255,
200 101, 1, 0, 255,
201 99, 1, 0, 255,
202 97, 0, 0, 255,
203 95, 0, 0, 255,
204 93, 0, 0, 255,
205 91, 0, 0, 255,
206 90, 0, 0, 255,
207 88, 0, 0, 255,
208 86, 0, 0, 255,
209 84, 0, 0, 255,
210 82, 0, 0, 255,
211 80, 0, 0, 255,
212 78, 0, 0, 255,
213 77, 0, 0, 255,
214 75, 0, 0, 255,
215 73, 0, 0, 255,
216 72, 0, 0, 255,
217 70, 0, 0, 255,
218 68, 0, 0, 255,
219 67, 0, 0, 255,
220 65, 0, 0, 255,
221 64, 0, 0, 255,
222 63, 0, 0, 255,
223 61, 0, 0, 255,
224 60, 0, 0, 255,
225 59, 0, 0, 255,
226 58, 0, 0, 255,
227 57, 0, 0, 255,
228 56, 0, 0, 255,
229 55, 0, 0, 255,
230 54, 0, 0, 255,
231 53, 0, 0, 255,
232 53, 0, 0, 255,
233 52, 0, 0, 255,
234 52, 0, 0, 255,
235 51, 0, 0, 255,
236 51, 0, 0, 255,
237 51, 0, 0, 255,
238 50, 0, 0, 255,
239 50, 0, 0, 255,
240 51, 0, 0, 255,
241 51, 0, 0, 255,
242 51, 0, 0, 255,
243 51, 0, 0, 255,
244 52, 0, 0, 255,
245 52, 0, 0, 255,
246 53, 0, 0, 255,
247 54, 1, 0, 255,
248 55, 2, 0, 255,
249 56, 3, 0, 255,
250 57, 4, 0, 255,
251 58, 5, 0, 255,
252 59, 6, 0, 255,
253 60, 7, 0, 255,
254 62, 8, 0, 255,
255 63, 9, 0, 255,
256 64, 11, 0, 255,
257 66, 12, 0, 255,
258 68, 13, 0, 255,
259 69, 14, 0, 255,
260 71, 16, 0, 255,
261 73, 17, 0, 255,
262 75, 18, 0, 255,
263 77, 20, 0, 255,
264 79, 21, 0, 255,
265 81, 23, 0, 255,
266 83, 24, 0, 255,
267 85, 26, 0, 255,
268 87, 28, 0, 255,
269 90, 29, 0, 255,
270 92, 31, 0, 255,
271 94, 33, 0, 255,
272 97, 34, 0, 255,
273 99, 36, 0, 255,
274 102, 38, 0, 255,
275 104, 40, 0, 255,
276 107, 41, 0, 255,
277 109, 43, 0, 255,
278 112, 45, 0, 255,
279 115, 47, 0, 255,
280 117, 49, 0, 255,
281 120, 51, 0, 255,
282 123, 52, 0, 255,
283 126, 54, 0, 255,
284 128, 56, 0, 255,
285 131, 58, 0, 255,
286 134, 60, 0, 255,
287 137, 62, 0, 255,
288 140, 64, 0, 255,
289 143, 66, 0, 255,
290 145, 68, 0, 255,
291 148, 70, 0, 255,
292 151, 72, 0, 255,
293 154, 74, 0, 255
294 };
295
296
297 enum flip_y_e { flip_y = true };
298
299
300 class the_application : public agg::platform_support
301 {
302 agg::rbox_ctrl<agg::rgba8> m_method;
303 agg::slider_ctrl<agg::rgba8> m_radius;
304 agg::polygon_ctrl<agg::rgba8> m_shadow_ctrl;
305
306 agg::path_storage m_path;
307 typedef agg::conv_curve<agg::path_storage> shape_type;
308 shape_type m_shape;
309
310 agg::rasterizer_scanline_aa<> m_ras;
311 agg::scanline_p8 m_sl;
312
313 agg::rect_d m_shape_bounds;
314
315 agg::pod_array<agg::int8u> m_gray8_buf;
316 agg::rendering_buffer m_gray8_rbuf;
317 agg::rendering_buffer m_gray8_rbuf2;
318
319 agg::pod_array<color_type> m_color_lut;
320 public:
321
the_application(agg::pix_format_e format,bool flip_y)322 the_application(agg::pix_format_e format, bool flip_y) :
323 agg::platform_support(format, flip_y),
324 m_method (10.0, 10.0, 130.0, 55.0, !flip_y),
325 m_radius (130 + 10.0, 10.0 + 4.0, 130 + 300.0, 10.0 + 8.0 + 4.0, !flip_y),
326 m_shadow_ctrl(4),
327 m_shape(m_path)
328 {
329 add_ctrl(m_method);
330 m_method.text_size(8);
331 m_method.add_item("Single Color");
332 m_method.add_item("Color LUT");
333 m_method.cur_item(1);
334
335 add_ctrl(m_radius);
336 m_radius.range(0.0, 40.0);
337 m_radius.value(15.0);
338 m_radius.label("Blur Radius=%1.2f");
339
340 add_ctrl(m_shadow_ctrl);
341
342 m_path.remove_all();
343 m_path.move_to(28.47, 6.45);
344 m_path.curve3(21.58, 1.12, 19.82, 0.29);
345 m_path.curve3(17.19, -0.93, 14.21, -0.93);
346 m_path.curve3(9.57, -0.93, 6.57, 2.25);
347 m_path.curve3(3.56, 5.42, 3.56, 10.60);
348 m_path.curve3(3.56, 13.87, 5.03, 16.26);
349 m_path.curve3(7.03, 19.58, 11.99, 22.51);
350 m_path.curve3(16.94, 25.44, 28.47, 29.64);
351 m_path.line_to(28.47, 31.40);
352 m_path.curve3(28.47, 38.09, 26.34, 40.58);
353 m_path.curve3(24.22, 43.07, 20.17, 43.07);
354 m_path.curve3(17.09, 43.07, 15.28, 41.41);
355 m_path.curve3(13.43, 39.75, 13.43, 37.60);
356 m_path.line_to(13.53, 34.77);
357 m_path.curve3(13.53, 32.52, 12.38, 31.30);
358 m_path.curve3(11.23, 30.08, 9.38, 30.08);
359 m_path.curve3(7.57, 30.08, 6.42, 31.35);
360 m_path.curve3(5.27, 32.62, 5.27, 34.81);
361 m_path.curve3(5.27, 39.01, 9.57, 42.53);
362 m_path.curve3(13.87, 46.04, 21.63, 46.04);
363 m_path.curve3(27.59, 46.04, 31.40, 44.04);
364 m_path.curve3(34.28, 42.53, 35.64, 39.31);
365 m_path.curve3(36.52, 37.21, 36.52, 30.71);
366 m_path.line_to(36.52, 15.53);
367 m_path.curve3(36.52, 9.13, 36.77, 7.69);
368 m_path.curve3(37.01, 6.25, 37.57, 5.76);
369 m_path.curve3(38.13, 5.27, 38.87, 5.27);
370 m_path.curve3(39.65, 5.27, 40.23, 5.62);
371 m_path.curve3(41.26, 6.25, 44.19, 9.18);
372 m_path.line_to(44.19, 6.45);
373 m_path.curve3(38.72, -0.88, 33.74, -0.88);
374 m_path.curve3(31.35, -0.88, 29.93, 0.78);
375 m_path.curve3(28.52, 2.44, 28.47, 6.45);
376 m_path.close_polygon();
377
378 m_path.move_to(28.47, 9.62);
379 m_path.line_to(28.47, 26.66);
380 m_path.curve3(21.09, 23.73, 18.95, 22.51);
381 m_path.curve3(15.09, 20.36, 13.43, 18.02);
382 m_path.curve3(11.77, 15.67, 11.77, 12.89);
383 m_path.curve3(11.77, 9.38, 13.87, 7.06);
384 m_path.curve3(15.97, 4.74, 18.70, 4.74);
385 m_path.curve3(22.41, 4.74, 28.47, 9.62);
386 m_path.close_polygon();
387
388 agg::trans_affine shape_mtx;
389 shape_mtx *= agg::trans_affine_scaling(4.0);
390 shape_mtx *= agg::trans_affine_translation(150, 100);
391 m_path.transform(shape_mtx);
392
393 agg::bounding_rect_single(m_shape, 0,
394 &m_shape_bounds.x1, &m_shape_bounds.y1,
395 &m_shape_bounds.x2, &m_shape_bounds.y2);
396
397 m_shadow_ctrl.xn(0) = m_shape_bounds.x1;
398 m_shadow_ctrl.yn(0) = m_shape_bounds.y1;
399 m_shadow_ctrl.xn(1) = m_shape_bounds.x2;
400 m_shadow_ctrl.yn(1) = m_shape_bounds.y1;
401 m_shadow_ctrl.xn(2) = m_shape_bounds.x2;
402 m_shadow_ctrl.yn(2) = m_shape_bounds.y2;
403 m_shadow_ctrl.xn(3) = m_shape_bounds.x1;
404 m_shadow_ctrl.yn(3) = m_shape_bounds.y2;
405 m_shadow_ctrl.line_color(agg::rgba(0, 0.3, 0.5, 0.3));
406
407
408 m_color_lut.resize(256);
409 unsigned i;
410 const agg::int8u* p = g_gradient_colors;
411 for(i = 0; i < 256; i++)
412 {
413 m_color_lut[i] = agg::rgba8(p[0], p[1], p[2], (i > 63) ? 255 : i * 4);//p[3]);
414 //m_color_lut[i].premultiply();
415 p += 4;
416 }
417 }
418
419
on_resize(int sx,int sy)420 virtual void on_resize(int sx, int sy)
421 {
422 m_gray8_buf.resize(sx * sy);
423 m_gray8_rbuf.attach(m_gray8_buf.data(), sx, sy, sx);
424 }
425
426
on_draw()427 virtual void on_draw()
428 {
429 typedef agg::pixfmt_gray8 pixfmt_gray8;
430 typedef agg::renderer_base<pixfmt_gray8> ren_base_gray8;
431
432 m_ras.clip_box(0,0, width(), height());
433
434 pixfmt_gray8 pixf_gray8(m_gray8_rbuf);
435 ren_base_gray8 renb_gray8(pixf_gray8);
436 renb_gray8.clear(agg::gray8(0));
437
438 // Testing enhanced compositing operations.
439 // Uncomment and replace renb.blend_from_* to renb_blend.blend_from_*
440 //----------------
441 //typedef agg::comp_op_rgba_minus<color_type, component_order> blender_type;
442 //typedef agg::comp_adaptor_rgba<blender_type> blend_adaptor_type;
443 //typedef agg::pixfmt_custom_blend_rgba<blend_adaptor_type, agg::rendering_buffer> pixfmt_type;
444 //typedef agg::renderer_base<pixfmt_type> ren_base;
445 //pixfmt_type pixf_blend(rbuf_window());
446 //agg::renderer_base<pixfmt_type> renb_blend(pixf_blend);
447
448 pixfmt pixf(rbuf_window());
449 agg::renderer_base<pixfmt> renb(pixf);
450 renb.clear(agg::rgba(1, 0.95, 0.95));
451
452 agg::trans_perspective shadow_persp(m_shape_bounds.x1, m_shape_bounds.y1,
453 m_shape_bounds.x2, m_shape_bounds.y2,
454 m_shadow_ctrl.polygon());
455
456 agg::conv_transform<shape_type,
457 agg::trans_perspective> shadow_trans(m_shape,
458 shadow_persp);
459
460 start_timer();
461
462 // Render shadow
463 m_ras.add_path(shadow_trans);
464 agg::render_scanlines_aa_solid(m_ras, m_sl, renb_gray8, agg::gray8(255));
465
466 // Calculate the bounding box and extend it by the blur radius
467 agg::rect_d bbox;
468 agg::bounding_rect_single(shadow_trans, 0, &bbox.x1, &bbox.y1, &bbox.x2, &bbox.y2);
469
470 bbox.x1 -= m_radius.value();
471 bbox.y1 -= m_radius.value();
472 bbox.x2 += m_radius.value();
473 bbox.y2 += m_radius.value();
474
475 if(bbox.clip(agg::rect_d(0, 0, width(), height())))
476 {
477 // Create a new pixel renderer and attach it to the main one as a child image.
478 // It returns true if the attachment suceeded. It fails if the rectangle
479 // (bbox) is fully clipped.
480 //------------------
481 pixfmt_gray8 pixf2(m_gray8_rbuf2);
482 if(pixf2.attach(pixf_gray8, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2)))
483 {
484 // Blur it
485 agg::stack_blur_gray8(pixf2, agg::uround(m_radius.value()),
486 agg::uround(m_radius.value()));
487 }
488 if(m_method.cur_item() == 0)
489 {
490 renb.blend_from_color(pixf2,
491 agg::rgba8(0, 100, 0),
492 0,
493 int(bbox.x1),
494 int(bbox.y1));
495 }
496 else
497 {
498 renb.blend_from_lut(pixf2,
499 m_color_lut.data(),
500 0,
501 int(bbox.x1),
502 int(bbox.y1));
503 }
504 }
505 double tm = elapsed_time();
506
507 char buf[64];
508 agg::gsv_text t;
509 t.size(10.0);
510
511 agg::conv_stroke<agg::gsv_text> st(t);
512 st.width(1.5);
513
514 sprintf(buf, "%3.2f ms", tm);
515 t.start_point(140.0, 30.0);
516 t.text(buf);
517
518 m_ras.add_path(st);
519 agg::render_scanlines_aa_solid(m_ras, m_sl, renb, agg::rgba(0,0,0));
520
521 agg::render_ctrl(m_ras, m_sl, renb, m_method);
522 agg::render_ctrl(m_ras, m_sl, renb, m_radius);
523 agg::render_ctrl(m_ras, m_sl, renb, m_shadow_ctrl);
524 }
525
526 };
527
528
529
agg_main(int argc,char * argv[])530 int agg_main(int argc, char* argv[])
531 {
532 the_application app(pix_format, flip_y);
533 app.caption("AGG Example. Gaussian and Stack Blur");
534
535 if(app.init(440, 330, 0))
536 {
537 return app.run();
538 }
539 return 1;
540 }
541
542
543