template<class VertexSource> void generate_alpha_mask(VertexSource& vs) { unsigned cx = (unsigned)width(); unsigned cy = (unsigned)height(); delete [] m_alpha_buf; m_alpha_buf = new unsigned char[cx * cy]; m_alpha_mask_rbuf.attach(m_alpha_buf, cx, cy, cx); typedef agg::renderer_base<agg::pixfmt_gray8> ren_base; typedef agg::renderer_scanline_aa_solid<ren_base> renderer; agg::pixfmt_gray8 pixf(m_alpha_mask_rbuf); ren_base rb(pixf); renderer ren(rb); start_timer(); if(m_operation.cur_item() == 0) { rb.clear(agg::gray8(0)); ren.color(agg::gray8(255)); } else { rb.clear(agg::gray8(255)); ren.color(agg::gray8(0)); } m_ras.add_path(vs); agg::render_scanlines(m_ras, m_sl, ren); double t1 = elapsed_time(); char buf[100]; sprintf(buf, "Generate AlphaMask: %.3fms", t1); draw_text(250, 20, buf); }
void pathAttr::addPath<agg::rasterizer_scanline_aa<> >(agg::rasterizer_scanline_aa<>& ras, agg::path_storage* path, const agg::trans_affine& tr) { apply(path, tr, 1.0); if (mCommand == stroke) { if (mIsoWidthFlag) { ras.add_path(transCurvedStroked, mIndex); } else { ras.add_path(curvedStrokedTrans, mIndex); } } else { ras.add_path(transCurved, mIndex); } }
void perform_rendering(VertexSource& vs) { pixfmt_type pixf(rbuf_window()); typedef agg::pixfmt_amask_adaptor<pixfmt_type, alpha_mask_type> pixfmt_amask_type; typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type; pixfmt_amask_type pixfa(pixf, m_alpha_mask); amask_ren_type rbase(pixfa); agg::renderer_scanline_aa_solid<amask_ren_type> ren(rbase); ren.color(agg::rgba(0.5, 0.0, 0, 0.5)); start_timer(); m_ras.reset(); m_ras.add_path(vs); agg::render_scanlines(m_ras, m_sl, ren); double t1 = elapsed_time(); char buf[100]; sprintf(buf, "Render with AlphaMask: %.3fms", t1); draw_text(250, 5, buf); }
void draw_aliased() { pixfmt pixf(rbuf_window()); renderer_base rb(pixf); renderer_bin ren_bin(rb); agg::path_storage path; path.move_to(m_x[0] - 200, m_y[0]); path.line_to(m_x[1] - 200, m_y[1]); path.line_to(m_x[2] - 200, m_y[2]); path.close_polygon(); ren_bin.color(agg::rgba(0.1, 0.5, 0.7, m_alpha.value())); m_ras.gamma(agg::gamma_threshold(m_gamma.value())); m_ras.add_path(path); agg::render_scanlines(m_ras, m_sl_bin, ren_bin); //-- Drawing an outline with subpixel accuracy (aliased) //typedef agg::renderer_primitives<renderer_base> renderer_pr; //renderer_pr ren_pr(rb); //agg::rasterizer_outline<renderer_pr> ras_line(ren_pr); //ren_pr.line_color(agg::rgba(0.0, 0.0, 0.0)); //ras_line.add_path(path); }
void generate_alpha_mask(int cx, int cy) { delete [] m_alpha_buf; m_alpha_buf = new unsigned char[cx * cy]; g_alpha_mask_rbuf.attach(m_alpha_buf, cx, cy, cx); typedef agg::renderer_base<agg::pixfmt_gray8> ren_base; typedef agg::renderer_scanline_aa_solid<ren_base> renderer; agg::pixfmt_gray8 pixf(g_alpha_mask_rbuf); ren_base rb(pixf); renderer r(rb); agg::scanline_p8 sl; rb.clear(agg::gray8(0)); agg::ellipse ell; int i; for(i = 0; i < 10; i++) { ell.init(rand() % cx, rand() % cy, rand() % 100 + 20, rand() % 100 + 20, 100); g_rasterizer.add_path(ell); r.color(agg::gray8(rand() & 0xFF, rand() & 0xFF)); agg::render_scanlines(g_rasterizer, sl, r); } }
//------------------------------------------------------------------------ void generate_pattern() { unsigned size = unsigned(m_pattern_size.value()); create_star(m_pattern_size.value() / 2.0, m_pattern_size.value() / 2.0, m_pattern_size.value() / 2.5, m_pattern_size.value() / 6.0, 6, m_pattern_angle.value()); agg::conv_smooth_poly1_curve<agg::path_storage> smooth(m_ps); agg::conv_stroke<agg::conv_smooth_poly1_curve<agg::path_storage> > stroke(smooth); smooth.smooth_value(1.0); smooth.approximation_scale(4.0); stroke.width(m_pattern_size.value() / 15.0); delete [] m_pattern; m_pattern = new agg::int8u[size * size * pixfmt::pix_width]; m_pattern_rbuf.attach(m_pattern, size, size, size * pixfmt::pix_width); pixfmt pixf(m_pattern_rbuf); agg::renderer_base<pixfmt> rb(pixf); agg::renderer_scanline_aa_solid<agg::renderer_base<pixfmt> > rs(rb); rb.clear(agg::rgba_pre(0.4, 0.0, 0.1, m_pattern_alpha.value())); // Pattern background color m_ras.add_path(smooth); rs.color(agg::srgba8(110,130,50)); agg::render_scanlines(m_ras, m_sl, rs); m_ras.add_path(stroke); rs.color(agg::srgba8(0,50,80)); agg::render_scanlines(m_ras, m_sl, rs); }
void draw_text(double x, double y, const char* str) { pixfmt_type pf(rbuf_window()); agg::renderer_base<pixfmt_type> rb(pf); agg::renderer_scanline_aa_solid<agg::renderer_base<pixfmt_type> > ren(rb); agg::gsv_text txt; agg::conv_stroke<agg::gsv_text> txt_stroke(txt); txt_stroke.width(1.5); txt_stroke.line_cap(agg::round_cap); txt.size(10.0); txt.start_point(x, y); txt.text(str); m_ras.add_path(txt_stroke); ren.color(agg::rgba(0.0, 0.0, 0.0)); agg::render_scanlines(m_ras, m_sl, ren); }
void draw_anti_aliased() { pixfmt pixf(rbuf_window()); renderer_base rb(pixf); renderer_aa ren_aa(rb); agg::path_storage path; path.move_to(m_x[0], m_y[0]); path.line_to(m_x[1], m_y[1]); path.line_to(m_x[2], m_y[2]); path.close_polygon(); ren_aa.color(agg::rgba(0.7, 0.5, 0.1, m_alpha.value())); m_ras.gamma(agg::gamma_power(m_gamma.value() * 2.0)); m_ras.add_path(path); agg::render_scanlines(m_ras, m_sl_p8, ren_aa); }
void roadmap_canvas_draw_multiple_circles (int count, RoadMapGuiPoint *centers, int *radius, int filled, int fast_draw) { int i; static agg::path_storage path; for (i = 0; i < count; ++i) { int r = radius[i]; int x = centers[i].x; int y = centers[i].y; agg::ellipse e( x, y, r, r); path.concat_path(e); if (filled) { ras.reset(); ras.add_path(path); ren_solid.color(CurrentPen->color); agg::render_scanlines( ras, sl, ren_solid); /* } else if (fast_draw) { renderer_pr ren_pr(agg_renb); agg::rasterizer_outline<renderer_pr> ras_line(ren_pr); ren_pr.line_color(CurrentPen->color); ras_line.add_path(path); */ } else { raso.add_path(path); } path.remove_all (); } }
void radial_shape(RenBase& rbase, const ColorRamp& colors, double x1, double y1, double x2, double y2) { typedef RenBase renderer_base_type; typedef agg::gradient_radial gradient_func_type; typedef ColorRamp color_func_type; typedef agg::span_interpolator_linear<> interpolator_type; typedef agg::span_allocator<color> span_allocator_type; typedef agg::span_gradient<color, interpolator_type, gradient_func_type, color_func_type> span_gradient_type; gradient_func_type gradient_func; // The gradient function agg::trans_affine gradient_mtx; interpolator_type span_interpolator(gradient_mtx); // Span interpolator span_allocator_type span_allocator; // Span Allocator span_gradient_type span_gradient(span_interpolator, gradient_func, colors, 0, 100); double cx = (x1 + x2) / 2.0; double cy = (y1 + y2) / 2.0; double r = 0.5 * (((x2 - x1) < (y2 - y1)) ? (x2 - x1) : (y2 - y1)); gradient_mtx *= agg::trans_affine_scaling(r / 100.0); gradient_mtx *= agg::trans_affine_translation(cx, cy); gradient_mtx *= trans_affine_resizing(); gradient_mtx.invert(); agg::ellipse ell(cx, cy, r, r, 100); agg::conv_transform<agg::ellipse> trans(ell, trans_affine_resizing()); m_ras.add_path(trans); agg::render_scanlines_aa(m_ras, m_sl, rbase, span_allocator, span_gradient); }
//------------------------------------------------------------------------ virtual void on_mouse_button_down(int x, int y, unsigned flags) { if(flags & agg::mouse_left) { agg::trans_affine polygon_mtx; polygon_mtx *= agg::trans_affine_translation(-m_polygon_cx, -m_polygon_cy); polygon_mtx *= agg::trans_affine_rotation(m_polygon_angle.value() * agg::pi / 180.0); polygon_mtx *= agg::trans_affine_scaling(m_polygon_scale.value(), m_polygon_scale.value()); polygon_mtx *= agg::trans_affine_translation(m_polygon_cx, m_polygon_cy); double r = initial_width() / 3.0 - 8.0; create_star(m_polygon_cx, m_polygon_cy, r, r / 1.45, 14); agg::conv_transform<agg::path_storage> tr(m_ps, polygon_mtx); m_ras.add_path(tr); if(m_ras.hit_test(x, y)) { m_dx = x - m_polygon_cx; m_dy = y - m_polygon_cy; m_flag = 1; } } }
void roadmap_canvas_draw_formated_string_angle (const RoadMapGuiPoint *position, RoadMapGuiPoint *center, int angle, int size, int font_type, const char *text) { font_manager_type *fman; font_manager_type *image_fman; font_engine_type *feng; font_engine_type *image_feng; if ((font_type & FONT_TYPE_NORMAL) && (!RoadMapCanvasNormalFontLoaded)) font_type = FONT_TYPE_BOLD; if (font_type & FONT_TYPE_NORMAL){ fman = &m_fman_nor; feng = &m_feng_nor; image_feng = &m_image_feng_nor; image_fman = &m_image_fman_nor; } else{ fman = &m_fman; feng = &m_feng; image_feng = &m_image_feng; image_fman = &m_image_fman; } if ((font_type & FONT_TYPE_BOLD) && (RoadMapCanvasFontLoaded != 1)) return; dbg_time_start(DBG_TIME_TEXT_FULL); dbg_time_start(DBG_TIME_TEXT_CNV); wchar_t wstr[255]; int length = roadmap_canvas_agg_to_wchar (text, wstr, 255); if (length <=0) return; #ifdef USE_FRIBIDI wchar_t *bidi_text = bidi_string(wstr); const wchar_t* p = bidi_text; #else const wchar_t* p = wstr; #endif ren_solid.color(CurrentPen->color); dbg_time_end(DBG_TIME_TEXT_CNV); double x = 0; double y = 0; if (size < 0) size = 15; if ( roadmap_screen_is_hd_screen() ) { size = (int)(size * CANVAS_HD_FONT_FACTOR); } else{ #ifdef _WIN32 size = (int) (size * 0.9); #endif } if (angle == 0) { /* Use faster drawing for text with no angle */ x = position->x; y = position->y; // ren_solid.color(agg::rgba8(0, 0, 0)); image_feng->height(size); image_feng->width(size); while(*p) { const agg::glyph_cache* glyph = image_fman->glyph(*p); if(glyph) { image_fman->init_embedded_adaptors(glyph, x, y); agg::render_scanlines(image_fman->gray8_adaptor(), image_fman->gray8_scanline(), ren_solid); // increment pen position x += glyph->advance_x; y += glyph->advance_y; } ++p; } } else{ feng->height(size); feng->width(size); } while(*p) { dbg_time_start(DBG_TIME_TEXT_ONE_LETTER); dbg_time_start(DBG_TIME_TEXT_GET_GLYPH); const agg::glyph_cache* glyph = fman->glyph(*p); dbg_time_end(DBG_TIME_TEXT_GET_GLYPH); if(glyph) { fman->init_embedded_adaptors(glyph, x, y); //agg::conv_curve<font_manager_type::path_adaptor_type> stroke(fman->path_adaptor()); agg::trans_affine mtx; if (abs(angle) > 0) { mtx *= agg::trans_affine_rotation(agg::deg2rad(angle)); } mtx *= agg::trans_affine_translation(position->x, position->y); agg::conv_transform<font_manager_type::path_adaptor_type> tr(fman->path_adaptor(), mtx); agg::conv_curve<agg::conv_transform<font_manager_type::path_adaptor_type> > fill(tr); //agg::conv_stroke< //agg::conv_curve<agg::conv_transform<font_manager_type::path_adaptor_type> > > //stroke(fill); //agg::conv_contour<agg::conv_transform<font_manager_type::path_adaptor_type> >contour(tr); //contour.width(2); //agg::conv_stroke< agg::conv_contour<agg::conv_transform<font_manager_type::path_adaptor_type> > > stroke(contour); //agg::conv_stroke< agg::conv_transform<font_manager_type::path_adaptor_type> > stroke(tr); dbg_time_start(DBG_TIME_TEXT_ONE_RAS); #ifdef WIN32_PROFILE ResumeCAPAll(); #endif ras.reset(); ras.add_path(tr); agg::render_scanlines(ras, sl, ren_solid); //ras.add_path(fill); //ras.add_path(stroke); //ren_solid.color(agg::rgba8(255, 255, 255)); //agg::render_scanlines(ras, sl, ren_solid); //ras.add_path(tr); //ren_solid.color(agg::rgba8(0, 0, 0)); //agg::render_scanlines(ras, sl, ren_solid); #ifdef WIN32_PROFILE SuspendCAPAll(); #endif dbg_time_end(DBG_TIME_TEXT_ONE_RAS); // increment pen position x += glyph->advance_x; y += glyph->advance_y; dbg_time_end(DBG_TIME_TEXT_ONE_LETTER); } ++p; } #ifdef USE_FRIBIDI free(bidi_text); #endif dbg_time_end(DBG_TIME_TEXT_FULL); }
virtual void on_draw() { pixfmt pixf(rbuf_window()); renderer_base rb(pixf); renderer_solid r(rb); rb.clear(agg::rgba(1, 1, 1)); g_rasterizer.clip_box(0, 0, width(), height()); if(m_trans_type.cur_item() == 0) { agg::trans_bilinear tr(g_x1, g_y1, g_x2, g_y2, m_quad.polygon()); if(tr.is_valid()) { //-------------------------- // Render transformed lion // agg::conv_transform<agg::path_storage, agg::trans_bilinear> trans(g_path, tr); agg::render_all_paths(g_rasterizer, g_scanline, r, trans, g_colors, g_path_idx, g_npaths); //-------------------------- //-------------------------- // Render transformed ellipse // agg::ellipse ell((g_x1 + g_x2) * 0.5, (g_y1 + g_y2) * 0.5, (g_x2 - g_x1) * 0.5, (g_y2 - g_y1) * 0.5, 200); agg::conv_stroke<agg::ellipse> ell_stroke(ell); ell_stroke.width(3.0); agg::conv_transform<agg::ellipse, agg::trans_bilinear> trans_ell(ell, tr); agg::conv_transform<agg::conv_stroke<agg::ellipse>, agg::trans_bilinear> trans_ell_stroke(ell_stroke, tr); g_rasterizer.add_path(trans_ell); r.color(agg::rgba(0.5, 0.3, 0.0, 0.3)); agg::render_scanlines(g_rasterizer, g_scanline, r); g_rasterizer.add_path(trans_ell_stroke); r.color(agg::rgba(0.0, 0.3, 0.2, 1.0)); agg::render_scanlines(g_rasterizer, g_scanline, r); //-------------------------- } } else { agg::trans_perspective tr(g_x1, g_y1, g_x2, g_y2, m_quad.polygon()); if(tr.is_valid()) { //-------------------------- // Render transformed lion // agg::conv_transform<agg::path_storage, agg::trans_perspective> trans(g_path, tr); agg::render_all_paths(g_rasterizer, g_scanline, r, trans, g_colors, g_path_idx, g_npaths); //-------------------------- //-------------------------- // Render transformed ellipse // agg::ellipse ell((g_x1 + g_x2) * 0.5, (g_y1 + g_y2) * 0.5, (g_x2 - g_x1) * 0.5, (g_y2 - g_y1) * 0.5, 200); agg::conv_stroke<agg::ellipse> ell_stroke(ell); ell_stroke.width(3.0); agg::conv_transform<agg::ellipse, agg::trans_perspective> trans_ell(ell, tr); agg::conv_transform<agg::conv_stroke<agg::ellipse>, agg::trans_perspective> trans_ell_stroke(ell_stroke, tr); g_rasterizer.add_path(trans_ell); r.color(agg::rgba(0.5, 0.3, 0.0, 0.3)); agg::render_scanlines(g_rasterizer, g_scanline, r); g_rasterizer.add_path(trans_ell_stroke); r.color(agg::rgba(0.0, 0.3, 0.2, 1.0)); agg::render_scanlines(g_rasterizer, g_scanline, r); //-------------------------- // Testing the reverse transformations //agg::trans_perspective tr2(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); //if(tr2.is_valid()) //{ // double x, y; // x = m_quad.xn(0); y = m_quad.yn(0); tr2.transform(&x, &y); // g_rasterizer.move_to_d(x, y); // x = m_quad.xn(1); y = m_quad.yn(1); tr2.transform(&x, &y); // g_rasterizer.line_to_d(x, y); // x = m_quad.xn(2); y = m_quad.yn(2); tr2.transform(&x, &y); // g_rasterizer.line_to_d(x, y); // x = m_quad.xn(3); y = m_quad.yn(3); tr2.transform(&x, &y); // g_rasterizer.line_to_d(x, y); // r.color(agg::rgba(0.5, 0.0, 0.0, 0.5)); // agg::render_scanlines(g_rasterizer, g_scanline, r); //} //else //{ // message("Singularity..."); //} } } //-------------------------- // Render the "quad" tool and controls g_rasterizer.add_path(m_quad); r.color(agg::rgba(0, 0.3, 0.5, 0.6)); agg::render_scanlines(g_rasterizer, g_scanline, r); agg::render_ctrl(g_rasterizer, g_scanline, rb, m_trans_type); //-------------------------- }
virtual void on_draw() { pixfmt pixf(rbuf_window()); pixfmt_pre pixf_pre(rbuf_window()); renderer_base rb(pixf); renderer_base_pre rb_pre(pixf_pre); if(!m_test_flag) { rb.clear(agg::rgba(1, 1, 1)); } if(m_trans_type.cur_item() == 0) { // For the affine parallelogram transformations we // calculate the 4-th (implicit) point of the parallelogram m_quad.xn(3) = m_quad.xn(0) + (m_quad.xn(2) - m_quad.xn(1)); m_quad.yn(3) = m_quad.yn(0) + (m_quad.yn(2) - m_quad.yn(1)); } if(!m_test_flag) { //-------------------------- // Render the "quad" tool and controls g_rasterizer.add_path(m_quad); agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rb, agg::rgba(0, 0.3, 0.5, 0.6)); //-------------------------- agg::render_ctrl(g_rasterizer, g_scanline, rb, m_trans_type); } // Prepare the polygon to rasterize. Here we need to fill // the destination (transformed) polygon. g_rasterizer.clip_box(0, 0, width(), height()); g_rasterizer.reset(); g_rasterizer.move_to_d(m_quad.xn(0), m_quad.yn(0)); g_rasterizer.line_to_d(m_quad.xn(1), m_quad.yn(1)); g_rasterizer.line_to_d(m_quad.xn(2), m_quad.yn(2)); g_rasterizer.line_to_d(m_quad.xn(3), m_quad.yn(3)); typedef agg::span_allocator<color_type> span_alloc_type; span_alloc_type sa; agg::image_filter<agg::image_filter_hanning> filter; typedef agg::wrap_mode_reflect_auto_pow2 remainder_type; typedef agg::image_accessor_wrap<pixfmt, remainder_type, remainder_type> img_source_type; pixfmt img_pixf(rbuf_img(0)); img_source_type img_src(img_pixf); enum subdiv_shift_e { subdiv_shift = 2 }; switch(m_trans_type.cur_item()) { case 0: { // Note that we consruct an affine matrix that transforms // a parallelogram to a rectangle, i.e., it's inverted. // It's actually the same as: // tr(g_x1, g_y1, g_x2, g_y2, m_triangle.polygon()); // tr.invert(); agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); // Also note that we can use the linear interpolator instead of // arbitrary span_interpolator_trans. It works much faster, // but the transformations must be linear and parellel. typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type; interpolator_type interpolator(tr); typedef span_image_filter_2x2<img_source_type, interpolator_type> span_gen_type; span_gen_type sg(img_src, interpolator, filter); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); break; } case 1: { agg::trans_bilinear tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); if(tr.is_valid()) { typedef agg::span_interpolator_linear<agg::trans_bilinear> interpolator_type; interpolator_type interpolator(tr); typedef span_image_filter_2x2<img_source_type, interpolator_type> span_gen_type; span_gen_type sg(img_src, interpolator, filter); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); } break; } case 2: { agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); if(tr.is_valid()) { typedef agg::span_interpolator_linear_subdiv<agg::trans_perspective, 8> interpolator_type; interpolator_type interpolator(tr); typedef span_image_filter_2x2<img_source_type, interpolator_type> span_gen_type; span_gen_type sg(img_src, interpolator, filter); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); } break; } } }
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); }
virtual void on_draw() { if(m_gamma.value() != m_old_gamma) { m_gamma_lut.gamma(m_gamma.value()); load_img(0, "spheres"); pixfmt pixf(rbuf_img(0)); pixf.apply_gamma_dir(m_gamma_lut); m_old_gamma = m_gamma.value(); } pixfmt pixf(rbuf_window()); pixfmt_pre pixf_pre(rbuf_window()); renderer_base rb(pixf); renderer_base_pre rb_pre(pixf_pre); renderer_solid r(rb); rb.clear(agg::rgba(1, 1, 1)); if(m_trans_type.cur_item() < 2) { // For the affine parallelogram transformations we // calculate the 4-th (implicit) point of the parallelogram m_quad.xn(3) = m_quad.xn(0) + (m_quad.xn(2) - m_quad.xn(1)); m_quad.yn(3) = m_quad.yn(0) + (m_quad.yn(2) - m_quad.yn(1)); } //-------------------------- // Render the "quad" tool and controls g_rasterizer.add_path(m_quad); r.color(agg::rgba(0, 0.3, 0.5, 0.1)); agg::render_scanlines(g_rasterizer, g_scanline, r); // Prepare the polygon to rasterize. Here we need to fill // the destination (transformed) polygon. g_rasterizer.clip_box(0, 0, width(), height()); g_rasterizer.reset(); int b = 0; g_rasterizer.move_to_d(m_quad.xn(0)-b, m_quad.yn(0)-b); g_rasterizer.line_to_d(m_quad.xn(1)+b, m_quad.yn(1)-b); g_rasterizer.line_to_d(m_quad.xn(2)+b, m_quad.yn(2)+b); g_rasterizer.line_to_d(m_quad.xn(3)-b, m_quad.yn(3)+b); typedef agg::span_allocator<color_type> span_alloc_type; span_alloc_type sa; agg::image_filter_bilinear filter_kernel; agg::image_filter_lut filter(filter_kernel, true); pixfmt pixf_img(rbuf_img(0)); typedef agg::image_accessor_clone<pixfmt> source_type; source_type source(pixf_img); start_timer(); switch(m_trans_type.cur_item()) { case 0: { agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type; interpolator_type interpolator(tr); typedef image_filter_2x2_type<source_type, interpolator_type> span_gen_type; span_gen_type sg(source, interpolator, filter); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); break; } case 1: { agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type; typedef image_resample_affine_type<source_type> span_gen_type; interpolator_type interpolator(tr); span_gen_type sg(source, interpolator, filter); sg.blur(m_blur.value()); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); break; } case 2: { agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); if(tr.is_valid()) { typedef agg::span_interpolator_linear_subdiv<agg::trans_perspective> interpolator_type; interpolator_type interpolator(tr); typedef image_filter_2x2_type<source_type, interpolator_type> span_gen_type; span_gen_type sg(source, interpolator, filter); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); } break; } case 3: { agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); if(tr.is_valid()) { typedef agg::span_interpolator_trans<agg::trans_perspective> interpolator_type; interpolator_type interpolator(tr); typedef image_filter_2x2_type<source_type, interpolator_type> span_gen_type; span_gen_type sg(source, interpolator, filter); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); } break; } case 4: { typedef agg::span_interpolator_persp_lerp<> interpolator_type; typedef agg::span_subdiv_adaptor<interpolator_type> subdiv_adaptor_type; interpolator_type interpolator(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); subdiv_adaptor_type subdiv_adaptor(interpolator); if(interpolator.is_valid()) { typedef image_resample_type<source_type, subdiv_adaptor_type> span_gen_type; span_gen_type sg(source, subdiv_adaptor, filter); sg.blur(m_blur.value()); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); } break; } case 5: { typedef agg::span_interpolator_persp_exact<> interpolator_type; typedef agg::span_subdiv_adaptor<interpolator_type> subdiv_adaptor_type; interpolator_type interpolator(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); subdiv_adaptor_type subdiv_adaptor(interpolator); if(interpolator.is_valid()) { typedef image_resample_type<source_type, subdiv_adaptor_type> span_gen_type; span_gen_type sg(source, subdiv_adaptor, filter); sg.blur(m_blur.value()); agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); } break; } } double tm = elapsed_time(); pixf.apply_gamma_inv(m_gamma_lut); char buf[64]; agg::gsv_text t; t.size(10.0); agg::conv_stroke<agg::gsv_text> pt(t); pt.width(1.5); sprintf(buf, "%3.2f ms", tm); t.start_point(10.0, 70.0); t.text(buf); g_rasterizer.add_path(pt); r.color(agg::rgba(0,0,0)); agg::render_scanlines(g_rasterizer, g_scanline, r); //-------------------------- agg::render_ctrl(g_rasterizer, g_scanline, rb, m_trans_type); agg::render_ctrl(g_rasterizer, g_scanline, rb, m_gamma); agg::render_ctrl(g_rasterizer, g_scanline, rb, m_blur); }
//------------------------------------------------------------------------ virtual void on_draw() { double width = rbuf_window().width(); double height = rbuf_window().height(); typedef agg::renderer_base<pixfmt> renderer_base; typedef agg::renderer_base<pixfmt_pre> renderer_base_pre; pixfmt pixf(rbuf_window()); pixfmt_pre pixf_pre(rbuf_window()); renderer_base rb(pixf); renderer_base_pre rb_pre(pixf_pre); rb.clear(agg::rgba(1.0, 1.0, 1.0)); agg::trans_affine polygon_mtx; polygon_mtx *= agg::trans_affine_translation(-m_polygon_cx, -m_polygon_cy); polygon_mtx *= agg::trans_affine_rotation(m_polygon_angle.value() * agg::pi / 180.0); polygon_mtx *= agg::trans_affine_scaling(m_polygon_scale.value()); polygon_mtx *= agg::trans_affine_translation(m_polygon_cx, m_polygon_cy); double r = initial_width() / 3.0 - 8.0; create_star(m_polygon_cx, m_polygon_cy, r, r / 1.45, 14); agg::conv_transform<agg::path_storage> tr(m_ps, polygon_mtx); typedef agg::wrap_mode_reflect_auto_pow2 wrap_x_type; typedef agg::wrap_mode_reflect_auto_pow2 wrap_y_type; typedef agg::image_accessor_wrap<pixfmt, wrap_x_type, wrap_y_type> img_source_type; typedef agg::span_pattern_rgba<img_source_type> span_gen_type; unsigned offset_x = 0; unsigned offset_y = 0; if(m_tie_pattern.status()) { offset_x = unsigned(width-m_polygon_cx); offset_y = unsigned(height-m_polygon_cy); } agg::span_allocator<color_type> sa; pixfmt img_pixf(m_pattern_rbuf); img_source_type img_src(img_pixf); span_gen_type sg(img_src, offset_x, offset_y); // Alpha is meaningful for RGB only because RGBA has its own sg.alpha(span_gen_type::value_type(m_pattern_alpha.value() * 255.0)); m_ras.add_path(tr); agg::render_scanlines_aa(m_ras, m_sl, rb_pre, sa, sg); agg::render_ctrl(m_ras, m_sl, rb, m_polygon_angle); agg::render_ctrl(m_ras, m_sl, rb, m_polygon_scale); agg::render_ctrl(m_ras, m_sl, rb, m_pattern_angle); agg::render_ctrl(m_ras, m_sl, rb, m_pattern_size); agg::render_ctrl(m_ras, m_sl, rb, m_pattern_alpha); agg::render_ctrl(m_ras, m_sl, rb, m_rotate_polygon); agg::render_ctrl(m_ras, m_sl, rb, m_rotate_pattern); agg::render_ctrl(m_ras, m_sl, rb, m_tie_pattern); }
unsigned render() { pixfmt_type pf(rbuf_window()); agg::renderer_base<pixfmt_type> rb(pf); agg::renderer_scanline_aa_solid<agg::renderer_base<pixfmt_type> > ren(rb); switch(m_polygons.cur_item()) { case 0: { //------------------------------------ // Two simple paths // agg::path_storage ps1; agg::path_storage ps2; double x = m_x - initial_width()/2 + 100; double y = m_y - initial_height()/2 + 100; ps1.move_to(x+140, y+145); ps1.line_to(x+225, y+44); ps1.line_to(x+296, y+219); ps1.close_polygon(); ps1.line_to(x+226, y+289); ps1.line_to(x+82, y+292); ps1.move_to(x+220, y+222); ps1.line_to(x+363, y+249); ps1.line_to(x+265, y+331); ps1.move_to(x+242, y+243); ps1.line_to(x+268, y+309); ps1.line_to(x+325, y+261); ps1.move_to(x+259, y+259); ps1.line_to(x+273, y+288); ps1.line_to(x+298, y+266); ps2.move_to(100+32, 100+77); ps2.line_to(100+473, 100+263); ps2.line_to(100+351, 100+290); ps2.line_to(100+354, 100+374); m_ras.reset(); m_ras.add_path(ps1); ren.color(agg::rgba(0, 0, 0, 0.1)); agg::render_scanlines(m_ras, m_sl, ren); m_ras.reset(); m_ras.add_path(ps2); ren.color(agg::rgba(0, 0.6, 0, 0.1)); agg::render_scanlines(m_ras, m_sl, ren); generate_alpha_mask(ps1); perform_rendering(ps2); } break; case 1: { //------------------------------------ // Closed stroke // agg::path_storage ps1; agg::path_storage ps2; agg::conv_stroke<agg::path_storage> stroke(ps2); stroke.width(10.0); double x = m_x - initial_width()/2 + 100; double y = m_y - initial_height()/2 + 100; ps1.move_to(x+140, y+145); ps1.line_to(x+225, y+44); ps1.line_to(x+296, y+219); ps1.close_polygon(); ps1.line_to(x+226, y+289); ps1.line_to(x+82, y+292); ps1.move_to(x+220-50, y+222); ps1.line_to(x+265-50, y+331); ps1.line_to(x+363-50, y+249); ps1.close_polygon(agg::path_flags_ccw); ps2.move_to(100+32, 100+77); ps2.line_to(100+473, 100+263); ps2.line_to(100+351, 100+290); ps2.line_to(100+354, 100+374); ps2.close_polygon(); m_ras.reset(); m_ras.add_path(ps1); ren.color(agg::rgba(0, 0, 0, 0.1)); agg::render_scanlines(m_ras, m_sl, ren); m_ras.reset(); m_ras.add_path(stroke); ren.color(agg::rgba(0, 0.6, 0, 0.1)); agg::render_scanlines(m_ras, m_sl, ren); generate_alpha_mask(ps1); perform_rendering(stroke); } break; case 2: { //------------------------------------ // Great Britain and Arrows // agg::path_storage gb_poly; agg::path_storage arrows; make_gb_poly(gb_poly); make_arrows(arrows); agg::trans_affine mtx1; agg::trans_affine mtx2; mtx1 *= agg::trans_affine_translation(-1150, -1150); mtx1 *= agg::trans_affine_scaling(2.0); mtx2 = mtx1; mtx2 *= agg::trans_affine_translation(m_x - initial_width()/2, m_y - initial_height()/2); agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx1); agg::conv_transform<agg::path_storage> trans_arrows(arrows, mtx2); m_ras.add_path(trans_gb_poly); ren.color(agg::rgba(0.5, 0.5, 0, 0.1)); agg::render_scanlines(m_ras, m_sl, ren); agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly); stroke_gb_poly.width(0.1); m_ras.add_path(stroke_gb_poly); ren.color(agg::rgba(0, 0, 0)); agg::render_scanlines(m_ras, m_sl, ren); m_ras.add_path(trans_arrows); ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1)); agg::render_scanlines(m_ras, m_sl, ren); generate_alpha_mask(trans_gb_poly); perform_rendering(trans_arrows); } break; case 3: { //------------------------------------ // Great Britain and a Spiral // spiral sp(m_x, m_y, 10, 150, 30, 0.0); agg::conv_stroke<spiral> stroke(sp); stroke.width(15.0); agg::path_storage gb_poly; make_gb_poly(gb_poly); agg::trans_affine mtx; mtx *= agg::trans_affine_translation(-1150, -1150); mtx *= agg::trans_affine_scaling(2.0); agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx); m_ras.add_path(trans_gb_poly); ren.color(agg::rgba(0.5, 0.5, 0, 0.1)); agg::render_scanlines(m_ras, m_sl, ren); agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly); stroke_gb_poly.width(0.1); m_ras.add_path(stroke_gb_poly); ren.color(agg::rgba(0, 0, 0)); agg::render_scanlines(m_ras, m_sl, ren); m_ras.add_path(stroke); ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1)); agg::render_scanlines(m_ras, m_sl, ren); generate_alpha_mask(trans_gb_poly); perform_rendering(stroke); } break; case 4: { //------------------------------------ // Spiral and glyph // spiral sp(m_x, m_y, 10, 150, 30, 0.0); agg::conv_stroke<spiral> stroke(sp); stroke.width(15.0); agg::path_storage glyph; glyph.move_to(28.47, 6.45); glyph.curve3(21.58, 1.12, 19.82, 0.29); glyph.curve3(17.19, -0.93, 14.21, -0.93); glyph.curve3(9.57, -0.93, 6.57, 2.25); glyph.curve3(3.56, 5.42, 3.56, 10.60); glyph.curve3(3.56, 13.87, 5.03, 16.26); glyph.curve3(7.03, 19.58, 11.99, 22.51); glyph.curve3(16.94, 25.44, 28.47, 29.64); glyph.line_to(28.47, 31.40); glyph.curve3(28.47, 38.09, 26.34, 40.58); glyph.curve3(24.22, 43.07, 20.17, 43.07); glyph.curve3(17.09, 43.07, 15.28, 41.41); glyph.curve3(13.43, 39.75, 13.43, 37.60); glyph.line_to(13.53, 34.77); glyph.curve3(13.53, 32.52, 12.38, 31.30); glyph.curve3(11.23, 30.08, 9.38, 30.08); glyph.curve3(7.57, 30.08, 6.42, 31.35); glyph.curve3(5.27, 32.62, 5.27, 34.81); glyph.curve3(5.27, 39.01, 9.57, 42.53); glyph.curve3(13.87, 46.04, 21.63, 46.04); glyph.curve3(27.59, 46.04, 31.40, 44.04); glyph.curve3(34.28, 42.53, 35.64, 39.31); glyph.curve3(36.52, 37.21, 36.52, 30.71); glyph.line_to(36.52, 15.53); glyph.curve3(36.52, 9.13, 36.77, 7.69); glyph.curve3(37.01, 6.25, 37.57, 5.76); glyph.curve3(38.13, 5.27, 38.87, 5.27); glyph.curve3(39.65, 5.27, 40.23, 5.62); glyph.curve3(41.26, 6.25, 44.19, 9.18); glyph.line_to(44.19, 6.45); glyph.curve3(38.72, -0.88, 33.74, -0.88); glyph.curve3(31.35, -0.88, 29.93, 0.78); glyph.curve3(28.52, 2.44, 28.47, 6.45); glyph.close_polygon(); glyph.move_to(28.47, 9.62); glyph.line_to(28.47, 26.66); glyph.curve3(21.09, 23.73, 18.95, 22.51); glyph.curve3(15.09, 20.36, 13.43, 18.02); glyph.curve3(11.77, 15.67, 11.77, 12.89); glyph.curve3(11.77, 9.38, 13.87, 7.06); glyph.curve3(15.97, 4.74, 18.70, 4.74); glyph.curve3(22.41, 4.74, 28.47, 9.62); glyph.close_polygon(); agg::trans_affine mtx; mtx *= agg::trans_affine_scaling(4.0); mtx *= agg::trans_affine_translation(220, 200); agg::conv_transform<agg::path_storage> trans(glyph, mtx); agg::conv_curve<agg::conv_transform<agg::path_storage> > curve(trans); m_ras.reset(); m_ras.add_path(stroke); ren.color(agg::rgba(0, 0, 0, 0.1)); agg::render_scanlines(m_ras, m_sl, ren); m_ras.reset(); m_ras.add_path(curve); ren.color(agg::rgba(0, 0.6, 0, 0.1)); agg::render_scanlines(m_ras, m_sl, ren); generate_alpha_mask(stroke); perform_rendering(curve); } break; } return 0; }
void roadmap_canvas_draw_multiple_lines (int count, int *lines, RoadMapGuiPoint *points, int fast_draw) { int i; int count_of_points; dbg_time_start(DBG_TIME_DRAW_LINES); #ifdef WIN32_PROFILE ResumeCAPAll(); #endif #ifdef _WIN32_ if (fast_draw) { roadmap_canvas_native_draw_multiple_lines (count, lines, points, CurrentPen->color.r, CurrentPen->color.g, CurrentPen->color.b, CurrentPen->thickness); return; } #endif if (!fast_draw) { raso.round_cap(true); raso.line_join(agg::outline_miter_accurate_join); } else { raso.round_cap(false); raso.line_join(agg::outline_no_join); } // raso.accurate_join(true); static agg::path_storage path; for (i = 0; i < count; ++i) { int first = 1; count_of_points = *lines; if (count_of_points < 2) continue; dbg_time_start(DBG_TIME_CREATE_PATH); for (int j=0; j<count_of_points; j++) { if (first) { first = 0; path.move_to(points->x, points->y); } else { path.line_to(points->x, points->y); } points++; } dbg_time_end(DBG_TIME_CREATE_PATH); dbg_time_start(DBG_TIME_ADD_PATH); #if 0 if (fast_draw) { renderer_pr ren_pr(agg_renb); agg::rasterizer_outline<renderer_pr> ras_line(ren_pr); ren_pr.line_color(CurrentPen->color); ras_line.add_path(path); } else { #endif raso.add_path(path); //} path.remove_all (); dbg_time_end(DBG_TIME_ADD_PATH); lines += 1; } #ifdef WIN32_PROFILE SuspendCAPAll(); #endif return; dbg_time_end(DBG_TIME_DRAW_LINES); } void roadmap_canvas_draw_multiple_polygons (int count, int *polygons, RoadMapGuiPoint *points, int filled, int fast_draw) { int i; int count_of_points; static agg::path_storage path; for (i = 0; i < count; ++i) { count_of_points = *polygons; int first = 1; for (int j=0; j<count_of_points; j++) { if (first) { first = 0; path.move_to(points->x, points->y); } else { path.line_to(points->x, points->y); } points++; } path.close_polygon(); if (filled) { ras.reset(); ras.add_path(path); ren_solid.color(CurrentPen->color); agg::render_scanlines( ras, sl, ren_solid); } else if (fast_draw) { renderer_pr ren_pr(agg_renb); agg::rasterizer_outline<renderer_pr> ras_line(ren_pr); ren_pr.line_color(CurrentPen->color); ras_line.add_path(path); } else { raso.add_path(path); } path.remove_all (); polygons += 1; } }
virtual void on_draw() { pixfmt pixf(rbuf_window()); renderer_base rb(pixf); renderer_solid rs(rb); rb.clear(agg::rgba(1, 1, 1)); // When Gamma changes rebuild the gamma and gradient LUTs //------------------ if(m_old_gamma != m_gamma.value()) { m_gamma_lut.gamma(m_gamma.value()); build_gradient_lut(); m_old_gamma = m_gamma.value(); } // Gradient center. All gradient functions assume the // center being in the origin (0,0) and you can't // change it. But you can apply arbitrary transformations // to the gradient (see below). //------------------ double cx = initial_width() / 2; double cy = initial_height() / 2; double r = 100; // Focal center. Defined in the gradient coordinates, // that is, with respect to the origin (0,0) //------------------ double fx = m_mouse_x - cx; double fy = m_mouse_y - cy; gradient_func_type gradient_func(r, fx, fy); gradient_adaptor_type gradient_adaptor(gradient_func); agg::trans_affine gradient_mtx; // Making the affine matrix. Move to (cx,cy), // apply the resizing transformations and invert // the matrix. Gradients and images always assume the // inverse transformations. //------------------ gradient_mtx.translate(cx, cy); gradient_mtx *= trans_affine_resizing(); gradient_mtx.invert(); interpolator_type span_interpolator(gradient_mtx); span_gradient_type span_gradient(span_interpolator, gradient_adaptor, m_gradient_lut, 0, r); // Form the simple rectangle //------------------ m_rasterizer.reset(); m_rasterizer.move_to_d(0,0); m_rasterizer.line_to_d(width(), 0); m_rasterizer.line_to_d(width(), height()); m_rasterizer.line_to_d(0, height()); // Render the gradient to the whole screen and measure the time //------------------ start_timer(); agg::render_scanlines_aa(m_rasterizer, m_scanline, rb, m_alloc, span_gradient); double tm = elapsed_time(); // Draw the transformed circle that shows the gradient boundary //------------------ agg::ellipse e(cx, cy, r, r); agg::conv_stroke<agg::ellipse> estr(e); agg::conv_transform< agg::conv_stroke< agg::ellipse> > etrans(estr, trans_affine_resizing()); m_rasterizer.add_path(etrans); agg::render_scanlines_aa_solid(m_rasterizer, m_scanline, rb, agg::rgba(1,1,1)); // Show the gradient time //------------------ char buf[64]; agg::gsv_text t; t.size(10.0); agg::conv_stroke<agg::gsv_text> pt(t); pt.width(1.5); sprintf(buf, "%3.2f ms", tm); t.start_point(10.0, 35.0); t.text(buf); m_rasterizer.add_path(pt); agg::render_scanlines_aa_solid(m_rasterizer, m_scanline, rb, agg::rgba(0,0,0)); #if !LINEAR_RGB // Show the controls //------------------ agg::render_ctrl(m_rasterizer, m_scanline, rb, m_gamma); // Apply the inverse gamma to the whole buffer // (transform the colors to the perceptually uniform space) //------------------ pixf.apply_gamma_inv(m_gamma_lut); #endif }
virtual void on_draw() { typedef agg::renderer_base<pixfmt> ren_base; pixfmt pixf(rbuf_window()); ren_base rbase(pixf); trans_roundoff roundoff; if(m_redraw_flag) { g_rasterizer.gamma(agg::gamma_none()); rbase.clear(agg::rgba8(255,255,255)); g_rasterizer.filling_rule(agg::fill_non_zero); agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_rotate); agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_even_odd); agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_draft); agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_roundoff); agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_angle_delta); m_redraw_flag = false; } else { rbase.copy_bar(0, int(32.0 * rbuf_window().height() / m_dy), rbuf_window().width(), rbuf_window().height(), agg::rgba8(255,255,255)); } if(m_draft.status()) { g_rasterizer.gamma(agg::gamma_threshold(0.4)); } agg::trans_affine mtx; mtx.reset(); mtx *= agg::trans_affine_rotation(g_angle * agg::pi / 180.0); mtx *= agg::trans_affine_translation(m_dx / 2, m_dy / 2 + 10); mtx *= agg::trans_affine_scaling(rbuf_window().width() / m_dx, rbuf_window().height() / m_dy); agg::conv_transform<agg::path_storage> fill(g_path, mtx); agg::conv_transform < agg::conv_transform<agg::path_storage>, trans_roundoff > fill_roundoff(fill, roundoff); agg::conv_stroke < agg::conv_transform<agg::path_storage> > stroke(fill); agg::conv_stroke < agg::conv_transform < agg::conv_transform<agg::path_storage>, trans_roundoff > > stroke_roundoff(fill_roundoff); g_pflag = m_even_odd.status() ? agg::fill_even_odd : agg::fill_non_zero; unsigned i; for(i = 0; i < g_npaths; i++) { g_rasterizer.filling_rule(g_pflag); if(m_roundoff.status()) g_rasterizer.add_path(fill_roundoff, g_attr[i].index); else g_rasterizer.add_path(fill, g_attr[i].index); if(m_draft.status()) { agg::render_scanlines_bin_solid(g_rasterizer, g_scanline, rbase, g_attr[i].fill_color); } else { agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rbase, g_attr[i].fill_color); } if(g_attr[i].stroke_width > 0.001) { stroke.width(g_attr[i].stroke_width * mtx.scale()); stroke_roundoff.width(g_attr[i].stroke_width * mtx.scale()); if(m_roundoff.status()) g_rasterizer.add_path(stroke_roundoff, g_attr[i].index); else g_rasterizer.add_path(stroke, g_attr[i].index); if(m_draft.status()) { agg::render_scanlines_bin_solid(g_rasterizer, g_scanline, rbase, g_attr[i].stroke_color); } else { agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rbase, g_attr[i].stroke_color); } } } }
virtual void on_draw() { typedef agg::renderer_base<agg::pixfmt_bgr24> ren_base; agg::pixfmt_bgr24 pixf(rbuf_window()); ren_base renb(pixf); renb.clear(agg::rgba(1, 1, 1)); m_ras.clip_box(0,0, width(), height()); 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); // Render shadow m_ras.add_path(shadow_trans); agg::render_scanlines_aa_solid(m_ras, m_sl, renb, agg::rgba(0.2,0.3,0)); // 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(m_method.cur_item() == 1) { // The recursive blur method represents the true Gussian Blur, // with theoretically infinite kernel. The restricted window size // results in extra influence of edge pixels. It's impossible to // solve correctly, but extending the right and top areas to another // radius value produces fair result. //------------------ bbox.x2 += m_radius.value(); bbox.y2 += m_radius.value(); } start_timer(); if(m_method.cur_item() != 2) { // 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. //------------------ agg::pixfmt_bgr24 pixf2(m_rbuf2); if(pixf2.attach(pixf, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2))) { // Blur it if(m_method.cur_item() == 0) { // More general method, but 30-40% slower. //------------------ //m_stack_blur.blur(pixf2, agg::uround(m_radius.value())); // Faster, but bore specific. // Works only for 8 bits per channel and only with radii <= 254. //------------------ agg::stack_blur_rgb24(pixf2, agg::uround(m_radius.value()), agg::uround(m_radius.value())); } else { // True Gaussian Blur, 3-5 times slower than Stack Blur, // but still constant time of radius. Very sensitive // to precision, doubles are must here. //------------------ m_recursive_blur.blur(pixf2, m_radius.value()); } } } else { // Blur separate channels //------------------ if(m_channel_r.status()) { typedef agg::pixfmt_alpha_blend_gray< agg::blender_gray8, agg::rendering_buffer, 3, 2> pixfmt_gray8r; pixfmt_gray8r pixf2r(m_rbuf2); if(pixf2r.attach(pixf, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2))) { agg::stack_blur_gray8(pixf2r, agg::uround(m_radius.value()), agg::uround(m_radius.value())); } } if(m_channel_g.status()) { typedef agg::pixfmt_alpha_blend_gray< agg::blender_gray8, agg::rendering_buffer, 3, 1> pixfmt_gray8g; pixfmt_gray8g pixf2g(m_rbuf2); if(pixf2g.attach(pixf, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2))) { agg::stack_blur_gray8(pixf2g, agg::uround(m_radius.value()), agg::uround(m_radius.value())); } } if(m_channel_b.status()) { typedef agg::pixfmt_alpha_blend_gray< agg::blender_gray8, agg::rendering_buffer, 3, 0> pixfmt_gray8b; pixfmt_gray8b pixf2b(m_rbuf2); if(pixf2b.attach(pixf, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2))) { agg::stack_blur_gray8(pixf2b, agg::uround(m_radius.value()), agg::uround(m_radius.value())); } } } double tm = elapsed_time(); agg::render_ctrl(m_ras, m_sl, renb, m_shadow_ctrl); // Render the shape itself //------------------ m_ras.add_path(m_shape); agg::render_scanlines_aa_solid(m_ras, m_sl, renb, agg::rgba(0.6,0.9,0.7, 0.8)); 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_channel_r); agg::render_ctrl(m_ras, m_sl, renb, m_channel_g); agg::render_ctrl(m_ras, m_sl, renb, m_channel_b); }