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 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 (); } }
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() { 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; } } }
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); }
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; } }
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; }
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); }