00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include "agg_rendering_buffer.h"
00004 #include "agg_rasterizer_scanline_aa.h"
00005 #include "agg_scanline_u.h"
00006 #include "agg_scanline_p.h"
00007 #include "agg_conv_transform.h"
00008 #include "agg_color_rgba.h"
00009 #include "agg_color_gray.h"
00010 #include "agg_span_allocator.h"
00011 #include "agg_span_gradient.h"
00012 #include "agg_span_interpolator_linear.h"
00013 #include "agg_renderer_scanline.h"
00014 #include "ctrl/agg_rbox_ctrl.h"
00015 #include "ctrl/agg_spline_ctrl.h"
00016 #include "ctrl/agg_gamma_ctrl.h"
00017 #include "platform/agg_platform_support.h"
00018
00019
00020
00021 #define AGG_BGR24
00022
00023
00024
00025
00026
00027
00028
00029 #include "pixel_formats.h"
00030
00031 enum flip_y_e { flip_y = true };
00032
00033 const double center_x = 350;
00034 const double center_y = 280;
00035
00036
00037
00038
00039 class gradient_polymorphic_wrapper_base
00040 {
00041 public:
00042 virtual int calculate(int x, int y, int) const = 0;
00043 };
00044
00045 template<class GradientF>
00046 class gradient_polymorphic_wrapper : public gradient_polymorphic_wrapper_base
00047 {
00048 public:
00049 gradient_polymorphic_wrapper() : m_adaptor(m_gradient) {}
00050
00051 virtual int calculate(int x, int y, int d) const
00052 {
00053 return m_adaptor.calculate(x, y, d);
00054 }
00055 GradientF m_gradient;
00056 agg::gradient_reflect_adaptor<GradientF> m_adaptor;
00057 };
00058
00059
00060
00061 struct color_function_profile
00062 {
00063 color_function_profile() {}
00064 color_function_profile(const color_type* colors, const agg::int8u* profile) :
00065 m_colors(colors), m_profile(profile) {}
00066
00067 static unsigned size() { return 256; }
00068 const color_type& operator [] (unsigned v) const
00069 {
00070 return m_colors[m_profile[v]];
00071 }
00072
00073 const color_type* m_colors;
00074 const agg::int8u* m_profile;
00075 };
00076
00077
00078 class the_application : public agg::platform_support
00079 {
00080 agg::gamma_ctrl<agg::rgba8> m_profile;
00081 agg::spline_ctrl<agg::rgba8> m_spline_r;
00082 agg::spline_ctrl<agg::rgba8> m_spline_g;
00083 agg::spline_ctrl<agg::rgba8> m_spline_b;
00084 agg::spline_ctrl<agg::rgba8> m_spline_a;
00085 agg::rbox_ctrl<agg::rgba8> m_rbox;
00086
00087 double m_pdx;
00088 double m_pdy;
00089 double m_center_x;
00090 double m_center_y;
00091 double m_scale;
00092 double m_prev_scale;
00093 double m_angle;
00094 double m_prev_angle;
00095 double m_scale_x;
00096 double m_prev_scale_x;
00097 double m_scale_y;
00098 double m_prev_scale_y;
00099 bool m_mouse_move;
00100
00101 public:
00102 virtual ~the_application()
00103 {
00104 FILE* fd = fopen(full_file_name("settings.dat"), "w");
00105 fprintf(fd, "%f\n", m_center_x);
00106 fprintf(fd, "%f\n", m_center_y);
00107 fprintf(fd, "%f\n", m_scale);
00108 fprintf(fd, "%f\n", m_angle);
00109 fprintf(fd, "%f\n", m_spline_r.x(0));
00110 fprintf(fd, "%f\n", m_spline_r.y(0));
00111 fprintf(fd, "%f\n", m_spline_r.x(1));
00112 fprintf(fd, "%f\n", m_spline_r.y(1));
00113 fprintf(fd, "%f\n", m_spline_r.x(2));
00114 fprintf(fd, "%f\n", m_spline_r.y(2));
00115 fprintf(fd, "%f\n", m_spline_r.x(3));
00116 fprintf(fd, "%f\n", m_spline_r.y(3));
00117 fprintf(fd, "%f\n", m_spline_r.x(4));
00118 fprintf(fd, "%f\n", m_spline_r.y(4));
00119 fprintf(fd, "%f\n", m_spline_r.x(5));
00120 fprintf(fd, "%f\n", m_spline_r.y(5));
00121 fprintf(fd, "%f\n", m_spline_g.x(0));
00122 fprintf(fd, "%f\n", m_spline_g.y(0));
00123 fprintf(fd, "%f\n", m_spline_g.x(1));
00124 fprintf(fd, "%f\n", m_spline_g.y(1));
00125 fprintf(fd, "%f\n", m_spline_g.x(2));
00126 fprintf(fd, "%f\n", m_spline_g.y(2));
00127 fprintf(fd, "%f\n", m_spline_g.x(3));
00128 fprintf(fd, "%f\n", m_spline_g.y(3));
00129 fprintf(fd, "%f\n", m_spline_g.x(4));
00130 fprintf(fd, "%f\n", m_spline_g.y(4));
00131 fprintf(fd, "%f\n", m_spline_g.x(5));
00132 fprintf(fd, "%f\n", m_spline_g.y(5));
00133 fprintf(fd, "%f\n", m_spline_b.x(0));
00134 fprintf(fd, "%f\n", m_spline_b.y(0));
00135 fprintf(fd, "%f\n", m_spline_b.x(1));
00136 fprintf(fd, "%f\n", m_spline_b.y(1));
00137 fprintf(fd, "%f\n", m_spline_b.x(2));
00138 fprintf(fd, "%f\n", m_spline_b.y(2));
00139 fprintf(fd, "%f\n", m_spline_b.x(3));
00140 fprintf(fd, "%f\n", m_spline_b.y(3));
00141 fprintf(fd, "%f\n", m_spline_b.x(4));
00142 fprintf(fd, "%f\n", m_spline_b.y(4));
00143 fprintf(fd, "%f\n", m_spline_b.x(5));
00144 fprintf(fd, "%f\n", m_spline_b.y(5));
00145 fprintf(fd, "%f\n", m_spline_a.x(0));
00146 fprintf(fd, "%f\n", m_spline_a.y(0));
00147 fprintf(fd, "%f\n", m_spline_a.x(1));
00148 fprintf(fd, "%f\n", m_spline_a.y(1));
00149 fprintf(fd, "%f\n", m_spline_a.x(2));
00150 fprintf(fd, "%f\n", m_spline_a.y(2));
00151 fprintf(fd, "%f\n", m_spline_a.x(3));
00152 fprintf(fd, "%f\n", m_spline_a.y(3));
00153 fprintf(fd, "%f\n", m_spline_a.x(4));
00154 fprintf(fd, "%f\n", m_spline_a.y(4));
00155 fprintf(fd, "%f\n", m_spline_a.x(5));
00156 fprintf(fd, "%f\n", m_spline_a.y(5));
00157 double x1,y1,x2,y2;
00158 m_profile.values(&x1, &y1, &x2, &y2);
00159 fprintf(fd, "%f\n", x1);
00160 fprintf(fd, "%f\n", y1);
00161 fprintf(fd, "%f\n", x2);
00162 fprintf(fd, "%f\n", y2);
00163 fclose(fd);
00164 }
00165
00166 the_application(agg::pix_format_e format, bool flip_y) :
00167 agg::platform_support(format, flip_y),
00168 m_profile(10.0, 10.0, 200.0, 170.0-5.0, !flip_y),
00169 m_spline_r(210, 10, 210+250, 5+40, 6, !flip_y),
00170 m_spline_g(210, 10+40, 210+250, 5+80, 6, !flip_y),
00171 m_spline_b(210, 10+80, 210+250, 5+120, 6, !flip_y),
00172 m_spline_a(210, 10+120, 210+250, 5+160, 6, !flip_y),
00173 m_rbox(10.0, 180.0, 200.0, 300.0, !flip_y),
00174
00175 m_pdx(0.0),
00176 m_pdy(0.0),
00177 m_center_x(center_x),
00178 m_center_y(center_y),
00179 m_scale(1.0),
00180 m_prev_scale(1.0),
00181 m_angle(0.0),
00182 m_prev_angle(0.0),
00183 m_scale_x(1.0),
00184 m_prev_scale_x(1.0),
00185 m_scale_y(1.0),
00186 m_prev_scale_y(1.0),
00187 m_mouse_move(false)
00188 {
00189 add_ctrl(m_profile);
00190 add_ctrl(m_spline_r);
00191 add_ctrl(m_spline_g);
00192 add_ctrl(m_spline_b);
00193 add_ctrl(m_spline_a);
00194 add_ctrl(m_rbox);
00195
00196 m_profile.border_width(2.0, 2.0);
00197
00198 m_spline_r.background_color(agg::rgba(1.0, 0.8, 0.8));
00199 m_spline_g.background_color(agg::rgba(0.8, 1.0, 0.8));
00200 m_spline_b.background_color(agg::rgba(0.8, 0.8, 1.0));
00201 m_spline_a.background_color(agg::rgba(1.0, 1.0, 1.0));
00202
00203 m_spline_r.border_width(1.0, 2.0);
00204 m_spline_g.border_width(1.0, 2.0);
00205 m_spline_b.border_width(1.0, 2.0);
00206 m_spline_a.border_width(1.0, 2.0);
00207 m_rbox.border_width(2.0, 2.0);
00208
00209 m_spline_r.point(0, 0.0, 1.0);
00210 m_spline_r.point(1, 1.0/5.0, 1.0 - 1.0/5.0);
00211 m_spline_r.point(2, 2.0/5.0, 1.0 - 2.0/5.0);
00212 m_spline_r.point(3, 3.0/5.0, 1.0 - 3.0/5.0);
00213 m_spline_r.point(4, 4.0/5.0, 1.0 - 4.0/5.0);
00214 m_spline_r.point(5, 1.0, 0.0);
00215 m_spline_r.update_spline();
00216
00217 m_spline_g.point(0, 0.0, 1.0);
00218 m_spline_g.point(1, 1.0/5.0, 1.0 - 1.0/5.0);
00219 m_spline_g.point(2, 2.0/5.0, 1.0 - 2.0/5.0);
00220 m_spline_g.point(3, 3.0/5.0, 1.0 - 3.0/5.0);
00221 m_spline_g.point(4, 4.0/5.0, 1.0 - 4.0/5.0);
00222 m_spline_g.point(5, 1.0, 0.0);
00223 m_spline_g.update_spline();
00224
00225 m_spline_b.point(0, 0.0, 1.0);
00226 m_spline_b.point(1, 1.0/5.0, 1.0 - 1.0/5.0);
00227 m_spline_b.point(2, 2.0/5.0, 1.0 - 2.0/5.0);
00228 m_spline_b.point(3, 3.0/5.0, 1.0 - 3.0/5.0);
00229 m_spline_b.point(4, 4.0/5.0, 1.0 - 4.0/5.0);
00230 m_spline_b.point(5, 1.0, 0.0);
00231 m_spline_b.update_spline();
00232
00233 m_spline_a.point(0, 0.0, 1.0);
00234 m_spline_a.point(1, 1.0/5.0, 1.0);
00235 m_spline_a.point(2, 2.0/5.0, 1.0);
00236 m_spline_a.point(3, 3.0/5.0, 1.0);
00237 m_spline_a.point(4, 4.0/5.0, 1.0);
00238 m_spline_a.point(5, 1.0, 1.0);
00239 m_spline_a.update_spline();
00240
00241 m_rbox.add_item("Circular");
00242 m_rbox.add_item("Diamond");
00243 m_rbox.add_item("Linear");
00244 m_rbox.add_item("XY");
00245 m_rbox.add_item("sqrt(XY)");
00246 m_rbox.add_item("Conic");
00247 m_rbox.cur_item(0);
00248
00249 FILE* fd = fopen(full_file_name("settings.dat"), "r");
00250 if(fd)
00251 {
00252 float x;
00253 float y;
00254 float x2;
00255 float y2;
00256 float t;
00257
00258 fscanf(fd, "%f\n", &t); m_center_x = t;
00259 fscanf(fd, "%f\n", &t); m_center_y = t;
00260 fscanf(fd, "%f\n", &t); m_scale = t;
00261 fscanf(fd, "%f\n", &t); m_angle = t;
00262 fscanf(fd, "%f\n", &x);
00263 fscanf(fd, "%f\n", &y); m_spline_r.point(0, x, y);
00264 fscanf(fd, "%f\n", &x);
00265 fscanf(fd, "%f\n", &y); m_spline_r.point(1, x, y);
00266 fscanf(fd, "%f\n", &x);
00267 fscanf(fd, "%f\n", &y); m_spline_r.point(2, x, y);
00268 fscanf(fd, "%f\n", &x);
00269 fscanf(fd, "%f\n", &y); m_spline_r.point(3, x, y);
00270 fscanf(fd, "%f\n", &x);
00271 fscanf(fd, "%f\n", &y); m_spline_r.point(4, x, y);
00272 fscanf(fd, "%f\n", &x);
00273 fscanf(fd, "%f\n", &y); m_spline_r.point(5, x, y);
00274 fscanf(fd, "%f\n", &x);
00275 fscanf(fd, "%f\n", &y); m_spline_g.point(0, x, y);
00276 fscanf(fd, "%f\n", &x);
00277 fscanf(fd, "%f\n", &y); m_spline_g.point(1, x, y);
00278 fscanf(fd, "%f\n", &x);
00279 fscanf(fd, "%f\n", &y); m_spline_g.point(2, x, y);
00280 fscanf(fd, "%f\n", &x);
00281 fscanf(fd, "%f\n", &y); m_spline_g.point(3, x, y);
00282 fscanf(fd, "%f\n", &x);
00283 fscanf(fd, "%f\n", &y); m_spline_g.point(4, x, y);
00284 fscanf(fd, "%f\n", &x);
00285 fscanf(fd, "%f\n", &y); m_spline_g.point(5, x, y);
00286 fscanf(fd, "%f\n", &x);
00287 fscanf(fd, "%f\n", &y); m_spline_b.point(0, x, y);
00288 fscanf(fd, "%f\n", &x);
00289 fscanf(fd, "%f\n", &y); m_spline_b.point(1, x, y);
00290 fscanf(fd, "%f\n", &x);
00291 fscanf(fd, "%f\n", &y); m_spline_b.point(2, x, y);
00292 fscanf(fd, "%f\n", &x);
00293 fscanf(fd, "%f\n", &y); m_spline_b.point(3, x, y);
00294 fscanf(fd, "%f\n", &x);
00295 fscanf(fd, "%f\n", &y); m_spline_b.point(4, x, y);
00296 fscanf(fd, "%f\n", &x);
00297 fscanf(fd, "%f\n", &y); m_spline_b.point(5, x, y);
00298 fscanf(fd, "%f\n", &x);
00299 fscanf(fd, "%f\n", &y); m_spline_a.point(0, x, y);
00300 fscanf(fd, "%f\n", &x);
00301 fscanf(fd, "%f\n", &y); m_spline_a.point(1, x, y);
00302 fscanf(fd, "%f\n", &x);
00303 fscanf(fd, "%f\n", &y); m_spline_a.point(2, x, y);
00304 fscanf(fd, "%f\n", &x);
00305 fscanf(fd, "%f\n", &y); m_spline_a.point(3, x, y);
00306 fscanf(fd, "%f\n", &x);
00307 fscanf(fd, "%f\n", &y); m_spline_a.point(4, x, y);
00308 fscanf(fd, "%f\n", &x);
00309 fscanf(fd, "%f\n", &y); m_spline_a.point(5, x, y);
00310 m_spline_r.update_spline();
00311 m_spline_g.update_spline();
00312 m_spline_b.update_spline();
00313 m_spline_a.update_spline();
00314 fscanf(fd, "%f\n", &x);
00315 fscanf(fd, "%f\n", &y);
00316 fscanf(fd, "%f\n", &x2);
00317 fscanf(fd, "%f\n", &y2);
00318 m_profile.values(x, y, x2, y2);
00319 fclose(fd);
00320 }
00321
00322 }
00323
00324
00325 virtual void on_draw()
00326 {
00327 agg::rasterizer_scanline_aa<> ras;
00328
00329 typedef agg::renderer_base<pixfmt> renderer_base;
00330 agg::scanline_u8 sl;
00331
00332 pixfmt pixf(rbuf_window());
00333 renderer_base rb(pixf);
00334 rb.clear(agg::rgba(0, 0, 0));
00335
00336 m_profile.text_size(8.0);
00337
00338 agg::render_ctrl(ras, sl, rb, m_profile);
00339 agg::render_ctrl(ras, sl, rb, m_spline_r);
00340 agg::render_ctrl(ras, sl, rb, m_spline_g);
00341 agg::render_ctrl(ras, sl, rb, m_spline_b);
00342 agg::render_ctrl(ras, sl, rb, m_spline_a);
00343 agg::render_ctrl(ras, sl, rb, m_rbox);
00344
00345 double ini_scale = 1.0;
00346
00347 agg::trans_affine mtx1;
00348 mtx1 *= agg::trans_affine_scaling(ini_scale, ini_scale);
00349 mtx1 *= agg::trans_affine_rotation(agg::deg2rad(0.0));
00350 mtx1 *= agg::trans_affine_translation(center_x, center_y);
00351 mtx1 *= trans_affine_resizing();
00352
00353 agg::ellipse e1;
00354 e1.init(0.0, 0.0, 110.0, 110.0, 64);
00355
00356 agg::trans_affine mtx_g1;
00357 mtx_g1 *= agg::trans_affine_scaling(ini_scale, ini_scale);
00358 mtx_g1 *= agg::trans_affine_scaling(m_scale, m_scale);
00359 mtx_g1 *= agg::trans_affine_scaling(m_scale_x, m_scale_y);
00360 mtx_g1 *= agg::trans_affine_rotation(m_angle);
00361 mtx_g1 *= agg::trans_affine_translation(m_center_x, m_center_y);
00362 mtx_g1 *= trans_affine_resizing();
00363 mtx_g1.invert();
00364
00365
00366 color_type color_profile[256];
00367 int i;
00368 for(i = 0; i < 256; i++)
00369 {
00370 color_profile[i] = color_type(agg::rgba(m_spline_r.spline()[i],
00371 m_spline_g.spline()[i],
00372 m_spline_b.spline()[i],
00373 m_spline_a.spline()[i]));
00374 }
00375
00376 agg::conv_transform<agg::ellipse, agg::trans_affine> t1(e1, mtx1);
00377
00378 gradient_polymorphic_wrapper<agg::gradient_radial> gr_circle;
00379 gradient_polymorphic_wrapper<agg::gradient_diamond> gr_diamond;
00380 gradient_polymorphic_wrapper<agg::gradient_x> gr_x;
00381 gradient_polymorphic_wrapper<agg::gradient_xy> gr_xy;
00382 gradient_polymorphic_wrapper<agg::gradient_sqrt_xy> gr_sqrt_xy;
00383 gradient_polymorphic_wrapper<agg::gradient_conic> gr_conic;
00384
00385 gradient_polymorphic_wrapper_base* gr_ptr = &gr_circle;
00386
00387
00388
00389 switch(m_rbox.cur_item())
00390 {
00391 case 1: gr_ptr = &gr_diamond; break;
00392 case 2: gr_ptr = &gr_x; break;
00393 case 3: gr_ptr = &gr_xy; break;
00394 case 4: gr_ptr = &gr_sqrt_xy; break;
00395 case 5: gr_ptr = &gr_conic; break;
00396 }
00397
00398 typedef agg::span_interpolator_linear<> interpolator_type;
00399 typedef agg::span_gradient<color_type,
00400 interpolator_type,
00401 gradient_polymorphic_wrapper_base,
00402 color_function_profile> gradient_span_gen;
00403 typedef agg::span_allocator<gradient_span_gen::color_type> gradient_span_alloc;
00404
00405 gradient_span_alloc span_alloc;
00406 color_function_profile colors(color_profile, m_profile.gamma());
00407 interpolator_type inter(mtx_g1);
00408 gradient_span_gen span_gen(inter, *gr_ptr, colors, 0, 150);
00409
00410 ras.add_path(t1);
00411 agg::render_scanlines_aa(ras, sl, rb, span_alloc, span_gen);
00412 }
00413
00414
00415 virtual void on_mouse_move(int x, int y, unsigned flags)
00416 {
00417 if(m_mouse_move)
00418 {
00419 double x2 = x;
00420 double y2 = y;
00421 trans_affine_resizing().inverse_transform(&x2, &y2);
00422
00423 if(flags & agg::kbd_ctrl)
00424 {
00425 double dx = x2 - m_center_x;
00426 double dy = y2 - m_center_y;
00427 m_scale_x = m_prev_scale_x * dx / m_pdx;
00428 m_scale_y = m_prev_scale_y * dy / m_pdy;
00429 force_redraw();
00430 }
00431 else
00432 {
00433 if(flags & agg::mouse_left)
00434 {
00435 m_center_x = x2 + m_pdx;
00436 m_center_y = y2 + m_pdy;
00437 force_redraw();
00438 }
00439
00440 if(flags & agg::mouse_right)
00441 {
00442 double dx = x2 - m_center_x;
00443 double dy = y2 - m_center_y;
00444 m_scale = m_prev_scale *
00445 sqrt(dx * dx + dy * dy) /
00446 sqrt(m_pdx * m_pdx + m_pdy * m_pdy);
00447
00448 m_angle = m_prev_angle + atan2(dy, dx) - atan2(m_pdy, m_pdx);
00449 force_redraw();
00450 }
00451 }
00452 }
00453 }
00454
00455
00456 virtual void on_mouse_button_down(int x, int y, unsigned flags)
00457 {
00458 m_mouse_move = true;
00459 double x2 = x;
00460 double y2 = y;
00461 trans_affine_resizing().inverse_transform(&x2, &y2);
00462
00463 m_pdx = m_center_x - x2;
00464 m_pdy = m_center_y - y2;
00465 m_prev_scale = m_scale;
00466 m_prev_angle = m_angle + agg::pi;
00467 m_prev_scale_x = m_scale_x;
00468 m_prev_scale_y = m_scale_y;
00469 force_redraw();
00470 }
00471
00472
00473 virtual void on_mouse_button_up(int x, int y, unsigned flags)
00474 {
00475 m_mouse_move = false;
00476 }
00477
00478
00479 virtual void on_key(int x, int y, unsigned key, unsigned flags)
00480 {
00481 if(key == agg::key_f1)
00482 {
00483 FILE* fd = fopen(full_file_name("colors.dat"), "w");
00484 int i;
00485 for(i = 0; i < 256; i++)
00486 {
00487 color_type c = agg::rgba(m_spline_r.spline()[i],
00488 m_spline_g.spline()[i],
00489 m_spline_b.spline()[i],
00490 m_spline_a.spline()[i]);
00491 fprintf(fd, " %3d, %3d, %3d, %3d,\n", c.r, c.g, c.b, c.a);
00492 }
00493 fclose(fd);
00494
00495 fd = fopen(full_file_name("profile.dat"), "w");
00496 for(i = 0; i < 256; i++)
00497 {
00498 fprintf(fd, "%3d, ", unsigned(m_profile.gamma()[i]));
00499 if((i & 0xF) == 0xF) fprintf(fd, "\n");
00500 }
00501 fclose(fd);
00502 }
00503
00504
00505 }
00506
00507 };
00508
00509
00510
00511 int agg_main(int argc, char* argv[])
00512 {
00513
00514
00515
00516
00517
00518 the_application app(pix_format, flip_y);
00519 app.caption("AGG gradients with Mach bands compensation");
00520
00521 if(app.init(512, 400, agg::window_resize | agg::window_hw_buffer))
00522 {
00523 return app.run();
00524 }
00525 return 1;
00526 }
00527
00528