#include #include #include "agg_rendering_buffer.h" #include "agg_rasterizer_scanline_aa.h" #include "agg_scanline_u.h" #include "agg_scanline_p.h" #include "agg_conv_transform.h" #include "agg_color_rgba.h" #include "agg_color_gray.h" #include "agg_span_allocator.h" #include "agg_span_gradient.h" #include "agg_span_interpolator_linear.h" #include "agg_renderer_scanline.h" #include "ctrl/agg_rbox_ctrl.h" #include "ctrl/agg_spline_ctrl.h" #include "ctrl/agg_gamma_ctrl.h" #include "platform/agg_platform_support.h" //#define AGG_GRAY8 //#define AGG_GRAY16 //#define AGG_GRAY32 #define AGG_BGR24 //#define AGG_RGB24 //#define AGG_RGB_AAA //#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 = true }; const double center_x = 350; const double center_y = 280; class gradient_polymorphic_wrapper_base { public: virtual int calculate(int x, int y, int) const = 0; }; template class gradient_polymorphic_wrapper : public gradient_polymorphic_wrapper_base { public: gradient_polymorphic_wrapper() : m_adaptor(m_gradient) {} virtual int calculate(int x, int y, int d) const { return m_adaptor.calculate(x, y, d); } GradientF m_gradient; agg::gradient_reflect_adaptor m_adaptor; }; struct color_function_profile { color_function_profile() {} color_function_profile(const color_type* colors, const agg::int8u* profile) : m_colors(colors), m_profile(profile) {} static unsigned size() { return 256; } const color_type& operator [] (unsigned v) const { return m_colors[m_profile[v]]; } const color_type* m_colors; const agg::int8u* m_profile; }; class the_application : public agg::platform_support { agg::gamma_ctrl m_profile; agg::spline_ctrl m_spline_r; agg::spline_ctrl m_spline_g; agg::spline_ctrl m_spline_b; agg::spline_ctrl m_spline_a; agg::rbox_ctrl m_rbox; double m_pdx; double m_pdy; double m_center_x; double m_center_y; double m_scale; double m_prev_scale; double m_angle; double m_prev_angle; double m_scale_x; double m_prev_scale_x; double m_scale_y; double m_prev_scale_y; bool m_mouse_move; public: virtual ~the_application() { FILE* fd = fopen(full_file_name("settings.dat"), "w"); fprintf(fd, "%f\n", m_center_x); fprintf(fd, "%f\n", m_center_y); fprintf(fd, "%f\n", m_scale); fprintf(fd, "%f\n", m_angle); fprintf(fd, "%f\n", m_spline_r.x(0)); fprintf(fd, "%f\n", m_spline_r.y(0)); fprintf(fd, "%f\n", m_spline_r.x(1)); fprintf(fd, "%f\n", m_spline_r.y(1)); fprintf(fd, "%f\n", m_spline_r.x(2)); fprintf(fd, "%f\n", m_spline_r.y(2)); fprintf(fd, "%f\n", m_spline_r.x(3)); fprintf(fd, "%f\n", m_spline_r.y(3)); fprintf(fd, "%f\n", m_spline_r.x(4)); fprintf(fd, "%f\n", m_spline_r.y(4)); fprintf(fd, "%f\n", m_spline_r.x(5)); fprintf(fd, "%f\n", m_spline_r.y(5)); fprintf(fd, "%f\n", m_spline_g.x(0)); fprintf(fd, "%f\n", m_spline_g.y(0)); fprintf(fd, "%f\n", m_spline_g.x(1)); fprintf(fd, "%f\n", m_spline_g.y(1)); fprintf(fd, "%f\n", m_spline_g.x(2)); fprintf(fd, "%f\n", m_spline_g.y(2)); fprintf(fd, "%f\n", m_spline_g.x(3)); fprintf(fd, "%f\n", m_spline_g.y(3)); fprintf(fd, "%f\n", m_spline_g.x(4)); fprintf(fd, "%f\n", m_spline_g.y(4)); fprintf(fd, "%f\n", m_spline_g.x(5)); fprintf(fd, "%f\n", m_spline_g.y(5)); fprintf(fd, "%f\n", m_spline_b.x(0)); fprintf(fd, "%f\n", m_spline_b.y(0)); fprintf(fd, "%f\n", m_spline_b.x(1)); fprintf(fd, "%f\n", m_spline_b.y(1)); fprintf(fd, "%f\n", m_spline_b.x(2)); fprintf(fd, "%f\n", m_spline_b.y(2)); fprintf(fd, "%f\n", m_spline_b.x(3)); fprintf(fd, "%f\n", m_spline_b.y(3)); fprintf(fd, "%f\n", m_spline_b.x(4)); fprintf(fd, "%f\n", m_spline_b.y(4)); fprintf(fd, "%f\n", m_spline_b.x(5)); fprintf(fd, "%f\n", m_spline_b.y(5)); fprintf(fd, "%f\n", m_spline_a.x(0)); fprintf(fd, "%f\n", m_spline_a.y(0)); fprintf(fd, "%f\n", m_spline_a.x(1)); fprintf(fd, "%f\n", m_spline_a.y(1)); fprintf(fd, "%f\n", m_spline_a.x(2)); fprintf(fd, "%f\n", m_spline_a.y(2)); fprintf(fd, "%f\n", m_spline_a.x(3)); fprintf(fd, "%f\n", m_spline_a.y(3)); fprintf(fd, "%f\n", m_spline_a.x(4)); fprintf(fd, "%f\n", m_spline_a.y(4)); fprintf(fd, "%f\n", m_spline_a.x(5)); fprintf(fd, "%f\n", m_spline_a.y(5)); double x1,y1,x2,y2; m_profile.values(&x1, &y1, &x2, &y2); fprintf(fd, "%f\n", x1); fprintf(fd, "%f\n", y1); fprintf(fd, "%f\n", x2); fprintf(fd, "%f\n", y2); fclose(fd); } the_application(agg::pix_format_e format, bool flip_y) : agg::platform_support(format, flip_y), m_profile(10.0, 10.0, 200.0, 170.0-5.0, !flip_y), m_spline_r(210, 10, 210+250, 5+40, 6, !flip_y), m_spline_g(210, 10+40, 210+250, 5+80, 6, !flip_y), m_spline_b(210, 10+80, 210+250, 5+120, 6, !flip_y), m_spline_a(210, 10+120, 210+250, 5+160, 6, !flip_y), m_rbox(10.0, 180.0, 200.0, 300.0, !flip_y), m_pdx(0.0), m_pdy(0.0), m_center_x(center_x), m_center_y(center_y), m_scale(1.0), m_prev_scale(1.0), m_angle(0.0), m_prev_angle(0.0), m_scale_x(1.0), m_prev_scale_x(1.0), m_scale_y(1.0), m_prev_scale_y(1.0), m_mouse_move(false) { add_ctrl(m_profile); add_ctrl(m_spline_r); add_ctrl(m_spline_g); add_ctrl(m_spline_b); add_ctrl(m_spline_a); add_ctrl(m_rbox); m_profile.border_width(2.0, 2.0); m_spline_r.background_color(agg::rgba(1.0, 0.8, 0.8)); m_spline_g.background_color(agg::rgba(0.8, 1.0, 0.8)); m_spline_b.background_color(agg::rgba(0.8, 0.8, 1.0)); m_spline_a.background_color(agg::rgba(1.0, 1.0, 1.0)); m_spline_r.border_width(1.0, 2.0); m_spline_g.border_width(1.0, 2.0); m_spline_b.border_width(1.0, 2.0); m_spline_a.border_width(1.0, 2.0); m_rbox.border_width(2.0, 2.0); m_spline_r.point(0, 0.0, 1.0); m_spline_r.point(1, 1.0/5.0, 1.0 - 1.0/5.0); m_spline_r.point(2, 2.0/5.0, 1.0 - 2.0/5.0); m_spline_r.point(3, 3.0/5.0, 1.0 - 3.0/5.0); m_spline_r.point(4, 4.0/5.0, 1.0 - 4.0/5.0); m_spline_r.point(5, 1.0, 0.0); m_spline_r.update_spline(); m_spline_g.point(0, 0.0, 1.0); m_spline_g.point(1, 1.0/5.0, 1.0 - 1.0/5.0); m_spline_g.point(2, 2.0/5.0, 1.0 - 2.0/5.0); m_spline_g.point(3, 3.0/5.0, 1.0 - 3.0/5.0); m_spline_g.point(4, 4.0/5.0, 1.0 - 4.0/5.0); m_spline_g.point(5, 1.0, 0.0); m_spline_g.update_spline(); m_spline_b.point(0, 0.0, 1.0); m_spline_b.point(1, 1.0/5.0, 1.0 - 1.0/5.0); m_spline_b.point(2, 2.0/5.0, 1.0 - 2.0/5.0); m_spline_b.point(3, 3.0/5.0, 1.0 - 3.0/5.0); m_spline_b.point(4, 4.0/5.0, 1.0 - 4.0/5.0); m_spline_b.point(5, 1.0, 0.0); m_spline_b.update_spline(); m_spline_a.point(0, 0.0, 1.0); m_spline_a.point(1, 1.0/5.0, 1.0); m_spline_a.point(2, 2.0/5.0, 1.0); m_spline_a.point(3, 3.0/5.0, 1.0); m_spline_a.point(4, 4.0/5.0, 1.0); m_spline_a.point(5, 1.0, 1.0); m_spline_a.update_spline(); m_rbox.add_item("Circular"); m_rbox.add_item("Diamond"); m_rbox.add_item("Linear"); m_rbox.add_item("XY"); m_rbox.add_item("sqrt(XY)"); m_rbox.add_item("Conic"); m_rbox.cur_item(0); FILE* fd = fopen(full_file_name("settings.dat"), "r"); if(fd) { float x; float y; float x2; float y2; float t; fscanf(fd, "%f\n", &t); m_center_x = t; fscanf(fd, "%f\n", &t); m_center_y = t; fscanf(fd, "%f\n", &t); m_scale = t; fscanf(fd, "%f\n", &t); m_angle = t; fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_r.point(0, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_r.point(1, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_r.point(2, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_r.point(3, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_r.point(4, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_r.point(5, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_g.point(0, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_g.point(1, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_g.point(2, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_g.point(3, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_g.point(4, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_g.point(5, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_b.point(0, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_b.point(1, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_b.point(2, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_b.point(3, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_b.point(4, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_b.point(5, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_a.point(0, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_a.point(1, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_a.point(2, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_a.point(3, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_a.point(4, x, y); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); m_spline_a.point(5, x, y); m_spline_r.update_spline(); m_spline_g.update_spline(); m_spline_b.update_spline(); m_spline_a.update_spline(); fscanf(fd, "%f\n", &x); fscanf(fd, "%f\n", &y); fscanf(fd, "%f\n", &x2); fscanf(fd, "%f\n", &y2); m_profile.values(x, y, x2, y2); fclose(fd); } } virtual void on_draw() { agg::rasterizer_scanline_aa<> ras; typedef agg::renderer_base renderer_base; agg::scanline_u8 sl; pixfmt pixf(rbuf_window()); renderer_base rb(pixf); rb.clear(agg::rgba(0, 0, 0)); m_profile.text_size(8.0); agg::render_ctrl(ras, sl, rb, m_profile); agg::render_ctrl(ras, sl, rb, m_spline_r); agg::render_ctrl(ras, sl, rb, m_spline_g); agg::render_ctrl(ras, sl, rb, m_spline_b); agg::render_ctrl(ras, sl, rb, m_spline_a); agg::render_ctrl(ras, sl, rb, m_rbox); double ini_scale = 1.0; agg::trans_affine mtx1; mtx1 *= agg::trans_affine_scaling(ini_scale, ini_scale); mtx1 *= agg::trans_affine_rotation(agg::deg2rad(0.0)); mtx1 *= agg::trans_affine_translation(center_x, center_y); mtx1 *= trans_affine_resizing(); agg::ellipse e1; e1.init(0.0, 0.0, 110.0, 110.0, 64); agg::trans_affine mtx_g1; mtx_g1 *= agg::trans_affine_scaling(ini_scale, ini_scale); mtx_g1 *= agg::trans_affine_scaling(m_scale, m_scale); mtx_g1 *= agg::trans_affine_scaling(m_scale_x, m_scale_y); mtx_g1 *= agg::trans_affine_rotation(m_angle); mtx_g1 *= agg::trans_affine_translation(m_center_x, m_center_y); mtx_g1 *= trans_affine_resizing(); mtx_g1.invert(); color_type color_profile[256]; // color_type is defined in pixel_formats.h int i; for(i = 0; i < 256; i++) { color_profile[i] = color_type(agg::rgba(m_spline_r.spline()[i], m_spline_g.spline()[i], m_spline_b.spline()[i], m_spline_a.spline()[i])); } agg::conv_transform t1(e1, mtx1); gradient_polymorphic_wrapper gr_circle; gradient_polymorphic_wrapper gr_diamond; gradient_polymorphic_wrapper gr_x; gradient_polymorphic_wrapper gr_xy; gradient_polymorphic_wrapper gr_sqrt_xy; gradient_polymorphic_wrapper gr_conic; gradient_polymorphic_wrapper_base* gr_ptr = &gr_circle; // gr_circle.m_gradient.init(150, 80, 80); switch(m_rbox.cur_item()) { case 1: gr_ptr = &gr_diamond; break; case 2: gr_ptr = &gr_x; break; case 3: gr_ptr = &gr_xy; break; case 4: gr_ptr = &gr_sqrt_xy; break; case 5: gr_ptr = &gr_conic; break; } typedef agg::span_interpolator_linear<> interpolator_type; typedef agg::span_gradient gradient_span_gen; typedef agg::span_allocator gradient_span_alloc; gradient_span_alloc span_alloc; color_function_profile colors(color_profile, m_profile.gamma()); interpolator_type inter(mtx_g1); gradient_span_gen span_gen(inter, *gr_ptr, colors, 0, 150); ras.add_path(t1); agg::render_scanlines_aa(ras, sl, rb, span_alloc, span_gen); } virtual void on_mouse_move(int x, int y, unsigned flags) { if(m_mouse_move) { double x2 = x; double y2 = y; trans_affine_resizing().inverse_transform(&x2, &y2); if(flags & agg::kbd_ctrl) { double dx = x2 - m_center_x; double dy = y2 - m_center_y; m_scale_x = m_prev_scale_x * dx / m_pdx; m_scale_y = m_prev_scale_y * dy / m_pdy; force_redraw(); } else { if(flags & agg::mouse_left) { m_center_x = x2 + m_pdx; m_center_y = y2 + m_pdy; force_redraw(); } if(flags & agg::mouse_right) { double dx = x2 - m_center_x; double dy = y2 - m_center_y; m_scale = m_prev_scale * sqrt(dx * dx + dy * dy) / sqrt(m_pdx * m_pdx + m_pdy * m_pdy); m_angle = m_prev_angle + atan2(dy, dx) - atan2(m_pdy, m_pdx); force_redraw(); } } } } virtual void on_mouse_button_down(int x, int y, unsigned flags) { m_mouse_move = true; double x2 = x; double y2 = y; trans_affine_resizing().inverse_transform(&x2, &y2); m_pdx = m_center_x - x2; m_pdy = m_center_y - y2; m_prev_scale = m_scale; m_prev_angle = m_angle + agg::pi; m_prev_scale_x = m_scale_x; m_prev_scale_y = m_scale_y; force_redraw(); } virtual void on_mouse_button_up(int x, int y, unsigned flags) { m_mouse_move = false; } virtual void on_key(int x, int y, unsigned key, unsigned flags) { if(key == agg::key_f1) { FILE* fd = fopen(full_file_name("colors.dat"), "w"); int i; for(i = 0; i < 256; i++) { agg::srgba8 c = agg::rgba(m_spline_r.spline()[i], m_spline_g.spline()[i], m_spline_b.spline()[i], m_spline_a.spline()[i]); fprintf(fd, " %3d, %3d, %3d, %3d,\n", c.r, c.g, c.b, c.a); } fclose(fd); fd = fopen(full_file_name("profile.dat"), "w"); for(i = 0; i < 256; i++) { fprintf(fd, "%3d, ", unsigned(m_profile.gamma()[i])); if((i & 0xF) == 0xF) fprintf(fd, "\n"); } fclose(fd); } } }; int agg_main(int argc, char* argv[]) { //#ifdef _WIN32 // FILE* fd = fopen("stdout.txt", "w"); fclose(fd); //#endif //AGG_WATCHDOGGY(wd1, false); the_application app(pix_format, flip_y); app.caption("AGG gradients with Mach bands compensation"); if(app.init(512, 400, agg::window_resize | agg::window_hw_buffer)) { return app.run(); } return 1; }