#include <math.h> #include <stdio.h> #include "agg_basics.h" #include "agg_rendering_buffer.h" #include "agg_rasterizer_scanline_aa.h" #include "agg_conv_curve.h" #include "agg_conv_contour.h" #include "agg_conv_stroke.h" #include "agg_scanline_p.h" #include "agg_renderer_scanline.h" #include "agg_pixfmt_rgb.h" #include "agg_pixfmt_rgba.h" #include "agg_pixfmt_gray.h" #include "agg_bounding_rect.h" #include "agg_trans_perspective.h" #include "agg_blur.h" #include "ctrl/agg_slider_ctrl.h" #include "ctrl/agg_rbox_ctrl.h" #include "ctrl/agg_cbox_ctrl.h" #include "ctrl/agg_polygon_ctrl.h" #include "platform/agg_platform_support.h" //#define AGG_GRAY8 #define AGG_BGR24 //#define AGG_BGR48 //#define AGG_RGB_AAA //#define AGG_BGRA32 //#define AGG_RGBA32 //#define AGG_ARGB32 //#define AGG_ABGR32 //#define AGG_RGB565 //#define AGG_RGB555 #include "pixel_formats.h" static agg::int8u g_gradient_colors[] = { 255, 255, 255, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 254, 255, 255, 255, 253, 255, 255, 255, 253, 255, 255, 255, 252, 255, 255, 255, 251, 255, 255, 255, 250, 255, 255, 255, 248, 255, 255, 255, 246, 255, 255, 255, 244, 255, 255, 255, 241, 255, 255, 255, 238, 255, 255, 255, 235, 255, 255, 255, 231, 255, 255, 255, 227, 255, 255, 255, 222, 255, 255, 255, 217, 255, 255, 255, 211, 255, 255, 255, 206, 255, 255, 255, 200, 255, 255, 254, 194, 255, 255, 253, 188, 255, 255, 252, 182, 255, 255, 250, 176, 255, 255, 249, 170, 255, 255, 247, 164, 255, 255, 246, 158, 255, 255, 244, 152, 255, 254, 242, 146, 255, 254, 240, 141, 255, 254, 238, 136, 255, 254, 236, 131, 255, 253, 234, 126, 255, 253, 232, 121, 255, 253, 229, 116, 255, 252, 227, 112, 255, 252, 224, 108, 255, 251, 222, 104, 255, 251, 219, 100, 255, 251, 216, 96, 255, 250, 214, 93, 255, 250, 211, 89, 255, 249, 208, 86, 255, 249, 205, 83, 255, 248, 202, 80, 255, 247, 199, 77, 255, 247, 196, 74, 255, 246, 193, 72, 255, 246, 190, 69, 255, 245, 187, 67, 255, 244, 183, 64, 255, 244, 180, 62, 255, 243, 177, 60, 255, 242, 174, 58, 255, 242, 170, 56, 255, 241, 167, 54, 255, 240, 164, 52, 255, 239, 161, 51, 255, 239, 157, 49, 255, 238, 154, 47, 255, 237, 151, 46, 255, 236, 147, 44, 255, 235, 144, 43, 255, 235, 141, 41, 255, 234, 138, 40, 255, 233, 134, 39, 255, 232, 131, 37, 255, 231, 128, 36, 255, 230, 125, 35, 255, 229, 122, 34, 255, 228, 119, 33, 255, 227, 116, 31, 255, 226, 113, 30, 255, 225, 110, 29, 255, 224, 107, 28, 255, 223, 104, 27, 255, 222, 101, 26, 255, 221, 99, 25, 255, 220, 96, 24, 255, 219, 93, 23, 255, 218, 91, 22, 255, 217, 88, 21, 255, 216, 86, 20, 255, 215, 83, 19, 255, 214, 81, 18, 255, 213, 79, 17, 255, 212, 77, 17, 255, 211, 74, 16, 255, 210, 72, 15, 255, 209, 70, 14, 255, 207, 68, 13, 255, 206, 66, 13, 255, 205, 64, 12, 255, 204, 62, 11, 255, 203, 60, 10, 255, 202, 58, 10, 255, 201, 56, 9, 255, 199, 55, 9, 255, 198, 53, 8, 255, 197, 51, 7, 255, 196, 50, 7, 255, 195, 48, 6, 255, 193, 46, 6, 255, 192, 45, 5, 255, 191, 43, 5, 255, 190, 42, 4, 255, 188, 41, 4, 255, 187, 39, 3, 255, 186, 38, 3, 255, 185, 37, 2, 255, 183, 35, 2, 255, 182, 34, 1, 255, 181, 33, 1, 255, 179, 32, 1, 255, 178, 30, 0, 255, 177, 29, 0, 255, 175, 28, 0, 255, 174, 27, 0, 255, 173, 26, 0, 255, 171, 25, 0, 255, 170, 24, 0, 255, 168, 23, 0, 255, 167, 22, 0, 255, 165, 21, 0, 255, 164, 21, 0, 255, 163, 20, 0, 255, 161, 19, 0, 255, 160, 18, 0, 255, 158, 17, 0, 255, 156, 17, 0, 255, 155, 16, 0, 255, 153, 15, 0, 255, 152, 14, 0, 255, 150, 14, 0, 255, 149, 13, 0, 255, 147, 12, 0, 255, 145, 12, 0, 255, 144, 11, 0, 255, 142, 11, 0, 255, 140, 10, 0, 255, 139, 10, 0, 255, 137, 9, 0, 255, 135, 9, 0, 255, 134, 8, 0, 255, 132, 8, 0, 255, 130, 7, 0, 255, 128, 7, 0, 255, 126, 6, 0, 255, 125, 6, 0, 255, 123, 5, 0, 255, 121, 5, 0, 255, 119, 4, 0, 255, 117, 4, 0, 255, 115, 4, 0, 255, 113, 3, 0, 255, 111, 3, 0, 255, 109, 2, 0, 255, 107, 2, 0, 255, 105, 2, 0, 255, 103, 1, 0, 255, 101, 1, 0, 255, 99, 1, 0, 255, 97, 0, 0, 255, 95, 0, 0, 255, 93, 0, 0, 255, 91, 0, 0, 255, 90, 0, 0, 255, 88, 0, 0, 255, 86, 0, 0, 255, 84, 0, 0, 255, 82, 0, 0, 255, 80, 0, 0, 255, 78, 0, 0, 255, 77, 0, 0, 255, 75, 0, 0, 255, 73, 0, 0, 255, 72, 0, 0, 255, 70, 0, 0, 255, 68, 0, 0, 255, 67, 0, 0, 255, 65, 0, 0, 255, 64, 0, 0, 255, 63, 0, 0, 255, 61, 0, 0, 255, 60, 0, 0, 255, 59, 0, 0, 255, 58, 0, 0, 255, 57, 0, 0, 255, 56, 0, 0, 255, 55, 0, 0, 255, 54, 0, 0, 255, 53, 0, 0, 255, 53, 0, 0, 255, 52, 0, 0, 255, 52, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 51, 0, 0, 255, 52, 0, 0, 255, 52, 0, 0, 255, 53, 0, 0, 255, 54, 1, 0, 255, 55, 2, 0, 255, 56, 3, 0, 255, 57, 4, 0, 255, 58, 5, 0, 255, 59, 6, 0, 255, 60, 7, 0, 255, 62, 8, 0, 255, 63, 9, 0, 255, 64, 11, 0, 255, 66, 12, 0, 255, 68, 13, 0, 255, 69, 14, 0, 255, 71, 16, 0, 255, 73, 17, 0, 255, 75, 18, 0, 255, 77, 20, 0, 255, 79, 21, 0, 255, 81, 23, 0, 255, 83, 24, 0, 255, 85, 26, 0, 255, 87, 28, 0, 255, 90, 29, 0, 255, 92, 31, 0, 255, 94, 33, 0, 255, 97, 34, 0, 255, 99, 36, 0, 255, 102, 38, 0, 255, 104, 40, 0, 255, 107, 41, 0, 255, 109, 43, 0, 255, 112, 45, 0, 255, 115, 47, 0, 255, 117, 49, 0, 255, 120, 51, 0, 255, 123, 52, 0, 255, 126, 54, 0, 255, 128, 56, 0, 255, 131, 58, 0, 255, 134, 60, 0, 255, 137, 62, 0, 255, 140, 64, 0, 255, 143, 66, 0, 255, 145, 68, 0, 255, 148, 70, 0, 255, 151, 72, 0, 255, 154, 74, 0, 255 }; enum flip_y_e { flip_y = true }; class the_application : public agg::platform_support { agg::rbox_ctrl<agg::rgba8> m_method; agg::slider_ctrl<agg::rgba8> m_radius; agg::polygon_ctrl<agg::rgba8> m_shadow_ctrl; agg::path_storage m_path; typedef agg::conv_curve<agg::path_storage> shape_type; shape_type m_shape; agg::rasterizer_scanline_aa<> m_ras; agg::scanline_p8 m_sl; agg::rect_d m_shape_bounds; agg::pod_array<agg::int8u> m_gray8_buf; agg::rendering_buffer m_gray8_rbuf; agg::rendering_buffer m_gray8_rbuf2; agg::pod_array<color_type> m_color_lut; public: the_application(agg::pix_format_e format, bool flip_y) : agg::platform_support(format, flip_y), m_method (10.0, 10.0, 130.0, 55.0, !flip_y), m_radius (130 + 10.0, 10.0 + 4.0, 130 + 300.0, 10.0 + 8.0 + 4.0, !flip_y), m_shadow_ctrl(4), m_shape(m_path) { add_ctrl(m_method); m_method.text_size(8); m_method.add_item("Single Color"); m_method.add_item("Color LUT"); m_method.cur_item(1); add_ctrl(m_radius); m_radius.range(0.0, 40.0); m_radius.value(15.0); m_radius.label("Blur Radius=%1.2f"); add_ctrl(m_shadow_ctrl); m_path.remove_all(); m_path.move_to(28.47, 6.45); m_path.curve3(21.58, 1.12, 19.82, 0.29); m_path.curve3(17.19, -0.93, 14.21, -0.93); m_path.curve3(9.57, -0.93, 6.57, 2.25); m_path.curve3(3.56, 5.42, 3.56, 10.60); m_path.curve3(3.56, 13.87, 5.03, 16.26); m_path.curve3(7.03, 19.58, 11.99, 22.51); m_path.curve3(16.94, 25.44, 28.47, 29.64); m_path.line_to(28.47, 31.40); m_path.curve3(28.47, 38.09, 26.34, 40.58); m_path.curve3(24.22, 43.07, 20.17, 43.07); m_path.curve3(17.09, 43.07, 15.28, 41.41); m_path.curve3(13.43, 39.75, 13.43, 37.60); m_path.line_to(13.53, 34.77); m_path.curve3(13.53, 32.52, 12.38, 31.30); m_path.curve3(11.23, 30.08, 9.38, 30.08); m_path.curve3(7.57, 30.08, 6.42, 31.35); m_path.curve3(5.27, 32.62, 5.27, 34.81); m_path.curve3(5.27, 39.01, 9.57, 42.53); m_path.curve3(13.87, 46.04, 21.63, 46.04); m_path.curve3(27.59, 46.04, 31.40, 44.04); m_path.curve3(34.28, 42.53, 35.64, 39.31); m_path.curve3(36.52, 37.21, 36.52, 30.71); m_path.line_to(36.52, 15.53); m_path.curve3(36.52, 9.13, 36.77, 7.69); m_path.curve3(37.01, 6.25, 37.57, 5.76); m_path.curve3(38.13, 5.27, 38.87, 5.27); m_path.curve3(39.65, 5.27, 40.23, 5.62); m_path.curve3(41.26, 6.25, 44.19, 9.18); m_path.line_to(44.19, 6.45); m_path.curve3(38.72, -0.88, 33.74, -0.88); m_path.curve3(31.35, -0.88, 29.93, 0.78); m_path.curve3(28.52, 2.44, 28.47, 6.45); m_path.close_polygon(); m_path.move_to(28.47, 9.62); m_path.line_to(28.47, 26.66); m_path.curve3(21.09, 23.73, 18.95, 22.51); m_path.curve3(15.09, 20.36, 13.43, 18.02); m_path.curve3(11.77, 15.67, 11.77, 12.89); m_path.curve3(11.77, 9.38, 13.87, 7.06); m_path.curve3(15.97, 4.74, 18.70, 4.74); m_path.curve3(22.41, 4.74, 28.47, 9.62); m_path.close_polygon(); agg::trans_affine shape_mtx; shape_mtx *= agg::trans_affine_scaling(4.0); shape_mtx *= agg::trans_affine_translation(150, 100); m_path.transform(shape_mtx); agg::bounding_rect_single(m_shape, 0, &m_shape_bounds.x1, &m_shape_bounds.y1, &m_shape_bounds.x2, &m_shape_bounds.y2); m_shadow_ctrl.xn(0) = m_shape_bounds.x1; m_shadow_ctrl.yn(0) = m_shape_bounds.y1; m_shadow_ctrl.xn(1) = m_shape_bounds.x2; m_shadow_ctrl.yn(1) = m_shape_bounds.y1; m_shadow_ctrl.xn(2) = m_shape_bounds.x2; m_shadow_ctrl.yn(2) = m_shape_bounds.y2; m_shadow_ctrl.xn(3) = m_shape_bounds.x1; m_shadow_ctrl.yn(3) = m_shape_bounds.y2; m_shadow_ctrl.line_color(agg::rgba(0, 0.3, 0.5, 0.3)); m_color_lut.resize(256); unsigned i; const agg::int8u* p = g_gradient_colors; for(i = 0; i < 256; i++) { m_color_lut[i] = agg::rgba8(p[0], p[1], p[2], (i > 63) ? 255 : i * 4);//p[3]); //m_color_lut[i].premultiply(); p += 4; } } virtual void on_resize(int sx, int sy) { m_gray8_buf.resize(sx * sy); m_gray8_rbuf.attach(m_gray8_buf.data(), sx, sy, sx); } virtual void on_draw() { typedef agg::pixfmt_gray8 pixfmt_gray8; typedef agg::renderer_base<pixfmt_gray8> ren_base_gray8; m_ras.clip_box(0,0, width(), height()); pixfmt_gray8 pixf_gray8(m_gray8_rbuf); ren_base_gray8 renb_gray8(pixf_gray8); renb_gray8.clear(agg::gray8(0)); // Testing enhanced compositing operations. // Uncomment and replace renb.blend_from_* to renb_blend.blend_from_* //---------------- //typedef agg::comp_op_rgba_minus<color_type, component_order> blender_type; //typedef agg::comp_adaptor_rgba<blender_type> blend_adaptor_type; //typedef agg::pixfmt_custom_blend_rgba<blend_adaptor_type, agg::rendering_buffer> pixfmt_type; //typedef agg::renderer_base<pixfmt_type> ren_base; //pixfmt_type pixf_blend(rbuf_window()); //agg::renderer_base<pixfmt_type> renb_blend(pixf_blend); pixfmt pixf(rbuf_window()); agg::renderer_base<pixfmt> renb(pixf); renb.clear(agg::rgba(1, 0.95, 0.95)); agg::trans_perspective shadow_persp(m_shape_bounds.x1, m_shape_bounds.y1, m_shape_bounds.x2, m_shape_bounds.y2, m_shadow_ctrl.polygon()); agg::conv_transform<shape_type, agg::trans_perspective> shadow_trans(m_shape, shadow_persp); start_timer(); // Render shadow m_ras.add_path(shadow_trans); agg::render_scanlines_aa_solid(m_ras, m_sl, renb_gray8, agg::gray8(255)); // Calculate the bounding box and extend it by the blur radius agg::rect_d bbox; agg::bounding_rect_single(shadow_trans, 0, &bbox.x1, &bbox.y1, &bbox.x2, &bbox.y2); bbox.x1 -= m_radius.value(); bbox.y1 -= m_radius.value(); bbox.x2 += m_radius.value(); bbox.y2 += m_radius.value(); if(bbox.clip(agg::rect_d(0, 0, width(), height()))) { // Create a new pixel renderer and attach it to the main one as a child image. // It returns true if the attachment suceeded. It fails if the rectangle // (bbox) is fully clipped. //------------------ pixfmt_gray8 pixf2(m_gray8_rbuf2); if(pixf2.attach(pixf_gray8, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2))) { // Blur it agg::stack_blur_gray8(pixf2, agg::uround(m_radius.value()), agg::uround(m_radius.value())); } if(m_method.cur_item() == 0) { renb.blend_from_color(pixf2, agg::rgba8(0, 100, 0), 0, int(bbox.x1), int(bbox.y1)); } else { renb.blend_from_lut(pixf2, m_color_lut.data(), 0, int(bbox.x1), int(bbox.y1)); } } double tm = elapsed_time(); char buf[64]; agg::gsv_text t; t.size(10.0); agg::conv_stroke<agg::gsv_text> st(t); st.width(1.5); sprintf(buf, "%3.2f ms", tm); t.start_point(140.0, 30.0); t.text(buf); m_ras.add_path(st); agg::render_scanlines_aa_solid(m_ras, m_sl, renb, agg::rgba(0,0,0)); agg::render_ctrl(m_ras, m_sl, renb, m_method); agg::render_ctrl(m_ras, m_sl, renb, m_radius); agg::render_ctrl(m_ras, m_sl, renb, m_shadow_ctrl); } }; int agg_main(int argc, char* argv[]) { the_application app(pix_format, flip_y); app.caption("AGG Example. Gaussian and Stack Blur"); if(app.init(440, 330, 0)) { return app.run(); } return 1; } |