#include "agg_basics.h" #include "agg_rendering_buffer.h" #include "agg_rasterizer_scanline_aa.h" #include "agg_scanline_p.h" #include "agg_renderer_scanline.h" #include "agg_trans_affine.h" #include "agg_conv_stroke.h" #include "agg_conv_transform.h" #include "ctrl/agg_cbox_ctrl.h" #include "ctrl/agg_slider_ctrl.h" #include "platform/agg_platform_support.h" #define AGG_BGR24 //#define AGG_RGB24 //#define AGG_BGRA32 //#define AGG_RGBA32 //#define AGG_ARGB32 //#define AGG_ABGR32 //#define AGG_BGR96 //#define AGG_BGRA128 //#define AGG_RGB565 //#define AGG_RGB555 #include "pixel_formats.h" enum flip_y_e { flip_y = false }; struct path_attributes { unsigned index; agg::srgba8 fill_color; agg::srgba8 stroke_color; double stroke_width; path_attributes() {} path_attributes(unsigned idx, const agg::srgba8& fill, const agg::srgba8& stroke, double width) : index(idx), fill_color(fill), stroke_color(stroke), stroke_width(width) { } }; static double g_poly_bulb[] = { -6,-67, -6,-71, -7,-74, -8,-76, -10,-79, -10,-82, -9,-84, -6,-86, -4,-87, -2,-86, -1,-86, 1,-84, 2,-82, 2,-79, 0,-77, -2,-73, -2,-71, -2,-69, -3,-67, -4,-65 }; static double g_poly_beam1[] = { -14,-84,-22,-85,-23,-87,-22,-88,-21,-88 }; static double g_poly_beam2[] = { -10,-92, -14,-96, -14,-98, -12,-99, -11,-97 }; static double g_poly_beam3[] = { -1,-92, -2,-98, 0,-100, 2,-100, 1,-98 }; static double g_poly_beam4[] = { 5,-89, 11,-94, 13,-93, 13,-92, 12,-91 }; static double g_poly_fig1[] = { 1,-48,-3,-54,-7,-58,-12,-58,-17,-55,-20,-52,-21,-47, -20,-40,-17,-33,-11,-28,-6,-26,-2,-25,2,-26,4,-28,5, -33,5,-39,3,-44,12,-48,12,-50,12,-51,3,-46 }; static double g_poly_fig2[] = { 11,-27,6,-23,4,-22,3,-19,5, -16,6,-15,11,-17,19,-23,25,-30,32,-38,32,-41,32,-50,30,-64,32,-72, 32,-75,31,-77,28,-78,26,-80,28,-87,27,-89,25,-88,24,-79,24,-76,23, -75,20,-76,17,-76,17,-74,19,-73,22,-73,24,-71,26,-69,27,-64,28,-55, 28,-47,28,-40,26,-38,20,-33,14,-30 }; static double g_poly_fig3[] = { -6,-20,-9,-21,-15,-21,-20,-17, -28,-8,-32,-1,-32,1,-30,6,-26,8,-20,10,-16,12,-14,14,-15,16,-18,20, -22,20,-25,19,-27,20,-26,22,-23,23,-18,23,-14,22,-11,20,-10,17,-9,14, -11,11,-16,9,-22,8,-26,5,-28,2,-27,-2,-23,-8,-19,-11,-12,-14,-6,-15, -6,-18 }; static double g_poly_fig4[] = { 11,-6,8,-16,5,-21,-1,-23,-7, -22,-10,-17,-9,-10,-8,0,-8,10,-10,18,-11,22,-10,26,-7,28,-3,30,0,31, 5,31,10,27,14,18,14,11,11,2 }; static double g_poly_fig5[] = { 0,22,-5,21,-8,22,-9,26,-8,49, -8,54,-10,64,-10,75,-9,81,-10,84,-16,89,-18,95,-18,97,-13,100,-12,99, -12,95,-10,90,-8,87,-6,86,-4,83,-3,82,-5,80,-6,79,-7,74,-6,63,-3,52, 0,42,1,31 }; static double g_poly_fig6[] = { 12,31,12,24,8,21,3,21,2,24,3, 30,5,40,8,47,10,56,11,64,11,71,10,76,8,77,8,79,10,81,13,82,17,82,26, 84,28,87,32,86,33,81,32,80,25,79,17,79,14,79,13,76,14,72,14,64,13,55, 12,44,12,34 }; static path_attributes g_attr[3]; static agg::path_storage g_path; static unsigned g_npaths = 0; static agg::filling_rule_e g_pflag = agg::fill_non_zero; static agg::rasterizer_scanline_aa<> g_rasterizer; static agg::scanline_p8 g_scanline; static double g_angle = 0.0; #define AGG_POLY_SIZE(p) (sizeof(p) / (sizeof(*p) * 2)) struct trans_roundoff { static void transform(double* x, double* y) { *x = floor(*x + 0.5); *y = floor(*y + 0.5); } }; class the_application : public agg::platform_support { double m_dx; double m_dy; agg::cbox_ctrl m_rotate; agg::cbox_ctrl m_even_odd; agg::cbox_ctrl m_draft; agg::cbox_ctrl m_roundoff; agg::slider_ctrl m_angle_delta; bool m_redraw_flag; public: the_application(agg::pix_format_e format, bool flip_y) : agg::platform_support(format, flip_y), m_rotate(10, 3, "Rotate", !flip_y), m_even_odd(60, 3, "Even-Odd", !flip_y), m_draft(130, 3, "Draft", !flip_y), m_roundoff(175, 3, "Roundoff", !flip_y), m_angle_delta(10, 21, 250-10, 27, !flip_y), m_redraw_flag(true) { m_angle_delta.label("Step=%4.3f degree"); g_attr[g_npaths++] = path_attributes(g_path.start_new_path(), agg::srgba8(255, 255, 0), agg::srgba8(0, 0, 0), 1.0); g_path.concat_poly(g_poly_bulb, AGG_POLY_SIZE(g_poly_bulb), true); g_attr[g_npaths++] = path_attributes(g_path.start_new_path(), agg::srgba8(255, 255, 200), agg::srgba8(90, 0, 0), 0.7); g_path.concat_poly(g_poly_beam1, AGG_POLY_SIZE(g_poly_beam1), true); g_path.concat_poly(g_poly_beam2, AGG_POLY_SIZE(g_poly_beam2), true); g_path.concat_poly(g_poly_beam3, AGG_POLY_SIZE(g_poly_beam3), true); g_path.concat_poly(g_poly_beam4, AGG_POLY_SIZE(g_poly_beam4), true); g_attr[g_npaths++] = path_attributes(g_path.start_new_path(), agg::srgba8(0, 0, 0), agg::srgba8(0, 0, 0), 0.0); g_path.concat_poly(g_poly_fig1, AGG_POLY_SIZE(g_poly_fig1), true); g_path.concat_poly(g_poly_fig2, AGG_POLY_SIZE(g_poly_fig2), true); g_path.concat_poly(g_poly_fig3, AGG_POLY_SIZE(g_poly_fig3), true); g_path.concat_poly(g_poly_fig4, AGG_POLY_SIZE(g_poly_fig4), true); g_path.concat_poly(g_poly_fig5, AGG_POLY_SIZE(g_poly_fig5), true); g_path.concat_poly(g_poly_fig6, AGG_POLY_SIZE(g_poly_fig6), true); m_rotate.text_size(7); m_even_odd.text_size(7); m_draft.text_size(7); m_roundoff.text_size(7); add_ctrl(m_rotate); add_ctrl(m_even_odd); add_ctrl(m_draft); add_ctrl(m_roundoff); add_ctrl(m_angle_delta); m_angle_delta.value(0.01); } virtual void on_init() { m_dx = rbuf_window().width(); m_dy = rbuf_window().height(); } virtual void on_resize(int, int) { m_redraw_flag = true; } virtual void on_draw() { typedef agg::renderer_base 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::srgba8(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::srgba8(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 fill(g_path, mtx); agg::conv_transform < agg::conv_transform, trans_roundoff > fill_roundoff(fill, roundoff); agg::conv_stroke < agg::conv_transform > stroke(fill); agg::conv_stroke < agg::conv_transform < agg::conv_transform, 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_idle() { g_angle += m_angle_delta.value(); if(g_angle > 360.0) g_angle -= 360.0; force_redraw(); } virtual void on_ctrl_change() { wait_mode(!m_rotate.status()); m_redraw_flag = true; } }; int agg_main(int argc, char* argv[]) { the_application app(pix_format, flip_y); app.caption("AGG Example. Idea"); if(app.init(250, 280, agg::window_resize)) { return app.run(); } return 1; }