00001 #include <stdlib.h>
00002 #include <ctype.h>
00003 #include <stdio.h>
00004 #include "agg_rendering_buffer.h"
00005 #include "agg_rasterizer_scanline_aa.h"
00006 #include "agg_scanline_u.h"
00007 #include "agg_renderer_scanline.h"
00008 #include "agg_path_storage.h"
00009 #include "agg_conv_transform.h"
00010 #include "agg_trans_affine.h"
00011 #include "agg_span_allocator.h"
00012 #include "agg_span_interpolator_linear.h"
00013 #include "agg_span_interpolator_trans.h"
00014 #include "agg_span_interpolator_persp.h"
00015 #include "agg_span_subdiv_adaptor.h"
00016 #include "agg_image_accessors.h"
00017 #include "agg_gamma_lut.h"
00018 #include "ctrl/agg_rbox_ctrl.h"
00019 #include "ctrl/agg_slider_ctrl.h"
00020 #include "platform/agg_platform_support.h"
00021 #include "interactive_polygon.h"
00022
00023
00024 int global_offset = 0;
00025
00026
00027 enum flip_y_e { flip_y = true };
00028
00029 agg::rasterizer_scanline_aa<> g_rasterizer;
00030 agg::scanline_u8 g_scanline;
00031 double g_x1 = 0;
00032 double g_y1 = 0;
00033 double g_x2 = 0;
00034 double g_y2 = 0;
00035
00036 #include "agg_pixfmt_rgb.h"
00037 #include "agg_span_image_filter_rgb.h"
00038 #define pix_format agg::pix_format_bgr24
00039 typedef agg::pixfmt_bgr24 pixfmt;
00040 typedef agg::pixfmt_bgr24_pre pixfmt_pre;
00041 #define image_filter_2x2_type agg::span_image_filter_rgb_2x2
00042 #define image_resample_affine_type agg::span_image_resample_rgb_affine
00043 #define image_resample_type agg::span_image_resample_rgb
00044
00045 typedef pixfmt::color_type color_type;
00046 typedef color_type::value_type value_type;
00047 typedef agg::renderer_base<pixfmt> renderer_base;
00048 typedef agg::renderer_base<pixfmt_pre> renderer_base_pre;
00049 typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
00050 enum base_scale_e { base_shift = color_type::base_shift };
00051
00052 class the_application : public agg::platform_support
00053 {
00054 public:
00055 agg::gamma_lut<value_type, value_type, base_shift, base_shift> m_gamma_lut;
00056 agg::interactive_polygon m_quad;
00057 agg::rbox_ctrl<agg::rgba> m_trans_type;
00058 agg::slider_ctrl<agg::rgba> m_gamma;
00059 agg::slider_ctrl<agg::rgba> m_blur;
00060 double m_old_gamma;
00061
00062 the_application(agg::pix_format_e format, bool flip_y) :
00063 agg::platform_support(format, flip_y),
00064 m_gamma_lut(2.0),
00065 m_quad(4, 5.0),
00066 m_trans_type(400, 5.0, 430+170.0, 100.0, !flip_y),
00067 m_gamma(5.0, 5.0+15*0, 400-5, 10.0+15*0, !flip_y),
00068 m_blur (5.0, 5.0+15*1, 400-5, 10.0+15*1, !flip_y),
00069 m_old_gamma(2.0)
00070 {
00071 m_trans_type.text_size(7);
00072 m_trans_type.add_item("Affine No Resample");
00073 m_trans_type.add_item("Affine Resample");
00074 m_trans_type.add_item("Perspective No Resample LERP");
00075 m_trans_type.add_item("Perspective No Resample Exact");
00076 m_trans_type.add_item("Perspective Resample LERP");
00077 m_trans_type.add_item("Perspective Resample Exact");
00078 m_trans_type.cur_item(4);
00079 add_ctrl(m_trans_type);
00080
00081 m_gamma.range(0.5, 3.0);
00082 m_gamma.value(2.0);
00083 m_gamma.label("Gamma=%.3f");
00084 add_ctrl(m_gamma);
00085
00086 m_blur.range(0.5, 2.0);
00087 m_blur.value(1.0);
00088 m_blur.label("Blur=%.3f");
00089 add_ctrl(m_blur);
00090 }
00091
00092
00093 virtual void on_init()
00094 {
00095 g_x1 = 0.0;
00096 g_y1 = 0.0;
00097 g_x2 = rbuf_img(0).width();
00098 g_y2 = rbuf_img(0).height();
00099
00100 double x1 = g_x1;
00101 double y1 = g_y1;
00102 double x2 = g_x2;
00103 double y2 = g_y2;
00104
00105 double dx = width() / 2.0 - (x2 - x1) / 2.0;
00106 double dy = height() / 2.0 - (y2 - y1) / 2.0;
00107 m_quad.xn(0) = floor(x1 + dx);
00108 m_quad.yn(0) = floor(y1 + dy);
00109 m_quad.xn(1) = floor(x2 + dx);
00110 m_quad.yn(1) = floor(y1 + dy);
00111 m_quad.xn(2) = floor(x2 + dx);
00112 m_quad.yn(2) = floor(y2 + dy);
00113 m_quad.xn(3) = floor(x1 + dx);
00114 m_quad.yn(3) = floor(y2 + dy);
00115
00116 pixfmt pixf(rbuf_img(0));
00117 pixf.apply_gamma_dir(m_gamma_lut);
00118 }
00119
00120 virtual void on_draw()
00121 {
00122 if(m_gamma.value() != m_old_gamma)
00123 {
00124 m_gamma_lut.gamma(m_gamma.value());
00125 load_img(0, "spheres");
00126 pixfmt pixf(rbuf_img(0));
00127 pixf.apply_gamma_dir(m_gamma_lut);
00128 m_old_gamma = m_gamma.value();
00129 }
00130
00131 pixfmt pixf(rbuf_window());
00132 pixfmt_pre pixf_pre(rbuf_window());
00133 renderer_base rb(pixf);
00134 renderer_base_pre rb_pre(pixf_pre);
00135
00136 renderer_solid r(rb);
00137
00138 rb.clear(agg::rgba(1, 1, 1));
00139
00140 if(m_trans_type.cur_item() < 2)
00141 {
00142
00143
00144 m_quad.xn(3) = m_quad.xn(0) + (m_quad.xn(2) - m_quad.xn(1));
00145 m_quad.yn(3) = m_quad.yn(0) + (m_quad.yn(2) - m_quad.yn(1));
00146 }
00147
00148
00149
00150 g_rasterizer.add_path(m_quad);
00151 r.color(agg::rgba(0, 0.3, 0.5, 0.1));
00152 agg::render_scanlines(g_rasterizer, g_scanline, r);
00153
00154
00155
00156 g_rasterizer.clip_box(0, 0, width(), height());
00157 g_rasterizer.reset();
00158 int b = 0;
00159 g_rasterizer.move_to_d(m_quad.xn(0)-b, m_quad.yn(0)-b);
00160 g_rasterizer.line_to_d(m_quad.xn(1)+b, m_quad.yn(1)-b);
00161 g_rasterizer.line_to_d(m_quad.xn(2)+b, m_quad.yn(2)+b);
00162 g_rasterizer.line_to_d(m_quad.xn(3)-b, m_quad.yn(3)+b);
00163
00164 typedef agg::span_allocator<color_type> span_alloc_type;
00165 span_alloc_type sa;
00166 agg::image_filter_bilinear filter_kernel;
00167 agg::image_filter_lut filter(filter_kernel, true);
00168
00169 pixfmt pixf_img(rbuf_img(0));
00170 typedef agg::image_accessor_clone<pixfmt> source_type;
00171 source_type source(pixf_img);
00172
00173 start_timer();
00174 switch(m_trans_type.cur_item())
00175 {
00176 case 0:
00177 {
00178 agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00179
00180 typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type;
00181 interpolator_type interpolator(tr);
00182
00183 typedef image_filter_2x2_type<source_type,
00184 interpolator_type> span_gen_type;
00185 span_gen_type sg(source, interpolator, filter);
00186 agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00187 break;
00188 }
00189
00190 case 1:
00191 {
00192 agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00193
00194 typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type;
00195 typedef image_resample_affine_type<source_type> span_gen_type;
00196
00197 interpolator_type interpolator(tr);
00198 span_gen_type sg(source, interpolator, filter);
00199 sg.blur(m_blur.value());
00200 agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00201 break;
00202 }
00203
00204 case 2:
00205 {
00206 agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00207 if(tr.is_valid())
00208 {
00209 typedef agg::span_interpolator_linear_subdiv<agg::trans_perspective> interpolator_type;
00210 interpolator_type interpolator(tr);
00211
00212 typedef image_filter_2x2_type<source_type,
00213 interpolator_type> span_gen_type;
00214 span_gen_type sg(source, interpolator, filter);
00215 agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00216 }
00217 break;
00218 }
00219
00220 case 3:
00221 {
00222 agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00223 if(tr.is_valid())
00224 {
00225 typedef agg::span_interpolator_trans<agg::trans_perspective> interpolator_type;
00226 interpolator_type interpolator(tr);
00227
00228 typedef image_filter_2x2_type<source_type,
00229 interpolator_type> span_gen_type;
00230 span_gen_type sg(source, interpolator, filter);
00231 agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00232 }
00233 break;
00234 }
00235
00236 case 4:
00237 {
00238 typedef agg::span_interpolator_persp_lerp<> interpolator_type;
00239 typedef agg::span_subdiv_adaptor<interpolator_type> subdiv_adaptor_type;
00240
00241 interpolator_type interpolator(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00242 subdiv_adaptor_type subdiv_adaptor(interpolator);
00243
00244 if(interpolator.is_valid())
00245 {
00246 typedef image_resample_type<source_type,
00247 subdiv_adaptor_type> span_gen_type;
00248 span_gen_type sg(source, subdiv_adaptor, filter);
00249 sg.blur(m_blur.value());
00250 agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00251 }
00252 break;
00253 }
00254
00255 case 5:
00256 {
00257 typedef agg::span_interpolator_persp_exact<> interpolator_type;
00258 typedef agg::span_subdiv_adaptor<interpolator_type> subdiv_adaptor_type;
00259
00260 interpolator_type interpolator(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00261 subdiv_adaptor_type subdiv_adaptor(interpolator);
00262
00263 if(interpolator.is_valid())
00264 {
00265 typedef image_resample_type<source_type,
00266 subdiv_adaptor_type> span_gen_type;
00267 span_gen_type sg(source, subdiv_adaptor, filter);
00268 sg.blur(m_blur.value());
00269 agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00270 }
00271 break;
00272 }
00273 }
00274 double tm = elapsed_time();
00275 pixf.apply_gamma_inv(m_gamma_lut);
00276
00277 char buf[64];
00278 agg::gsv_text t;
00279 t.size(10.0);
00280
00281 agg::conv_stroke<agg::gsv_text> pt(t);
00282 pt.width(1.5);
00283
00284 sprintf(buf, "%3.2f ms", tm);
00285 t.start_point(10.0, 70.0);
00286 t.text(buf);
00287
00288 g_rasterizer.add_path(pt);
00289 r.color(agg::rgba(0,0,0));
00290 agg::render_scanlines(g_rasterizer, g_scanline, r);
00291
00292
00293 agg::render_ctrl(g_rasterizer, g_scanline, rb, m_trans_type);
00294 agg::render_ctrl(g_rasterizer, g_scanline, rb, m_gamma);
00295 agg::render_ctrl(g_rasterizer, g_scanline, rb, m_blur);
00296 }
00297
00298
00299
00300 virtual void on_mouse_button_down(int x, int y, unsigned flags)
00301 {
00302 if(flags & agg::mouse_left)
00303 {
00304 if(m_quad.on_mouse_button_down(x, y))
00305 {
00306 force_redraw();
00307 }
00308 }
00309 }
00310
00311
00312 virtual void on_mouse_move(int x, int y, unsigned flags)
00313 {
00314 if(flags & agg::mouse_left)
00315 {
00316 if(m_quad.on_mouse_move(x, y))
00317 {
00318 force_redraw();
00319 }
00320 }
00321 if((flags & agg::mouse_left) == 0)
00322 {
00323 on_mouse_button_up(x, y, flags);
00324 }
00325 }
00326
00327
00328 virtual void on_mouse_button_up(int x, int y, unsigned flags)
00329 {
00330 if(m_quad.on_mouse_button_up(x, y))
00331 {
00332 force_redraw();
00333 }
00334 }
00335
00336 virtual void on_key(int x, int y, unsigned key, unsigned flags)
00337 {
00338 if(key == ' ')
00339 {
00340 double cx = (m_quad.xn(0) + m_quad.xn(1) + m_quad.xn(2) + m_quad.xn(3)) / 4;
00341 double cy = (m_quad.yn(0) + m_quad.yn(1) + m_quad.yn(2) + m_quad.yn(3)) / 4;
00342 agg::trans_affine tr = agg::trans_affine_translation(-cx, -cy);
00343 tr *= agg::trans_affine_rotation(agg::pi / 2.0);
00344 tr *= agg::trans_affine_translation(cx, cy);
00345 tr.transform(&m_quad.xn(0), &m_quad.yn(0));
00346 tr.transform(&m_quad.xn(1), &m_quad.yn(1));
00347 tr.transform(&m_quad.xn(2), &m_quad.yn(2));
00348 tr.transform(&m_quad.xn(3), &m_quad.yn(3));
00349 force_redraw();
00350 }
00351 }
00352
00353 };
00354
00355
00356
00357
00358
00359
00360 int agg_main(int argc, char* argv[])
00361 {
00362 the_application app(pix_format, flip_y);
00363 app.caption("AGG Example. Image Transformations with Resampling");
00364
00365 const char* img_name = "spheres";
00366 if(argc >= 2) img_name = argv[1];
00367 if(!app.load_img(0, img_name))
00368 {
00369 char buf[256];
00370 if(strcmp(img_name, "spheres") == 0)
00371 {
00372 sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
00373 "or copy it from another directory if available.",
00374 img_name, app.img_ext(), img_name, app.img_ext());
00375 }
00376 else
00377 {
00378 sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
00379 }
00380 app.message(buf);
00381 return 1;
00382 }
00383
00384
00385 if(app.init(600, 600, agg::window_resize))
00386 {
00387 return app.run();
00388 }
00389 return 1;
00390 }
00391
00392
00393
00394
00395
00396