00001 #include <stdlib.h>
00002 #include <ctype.h>
00003 #include <stdio.h>
00004 #include "agg_basics.h"
00005 #include "agg_rendering_buffer.h"
00006 #include "agg_rasterizer_scanline_aa.h"
00007 #include "agg_scanline_u.h"
00008 #include "agg_renderer_scanline.h"
00009 #include "agg_path_storage.h"
00010 #include "agg_conv_transform.h"
00011 #include "agg_trans_affine.h"
00012 #include "agg_trans_bilinear.h"
00013 #include "agg_trans_perspective.h"
00014 #include "agg_span_allocator.h"
00015 #include "agg_span_interpolator_linear.h"
00016 #include "agg_span_interpolator_trans.h"
00017 #include "agg_span_subdiv_adaptor.h"
00018 #include "agg_pixfmt_rgba.h"
00019 #include "agg_image_accessors.h"
00020 #include "agg_span_image_filter_rgba.h"
00021 #include "ctrl/agg_rbox_ctrl.h"
00022 #include "platform/agg_platform_support.h"
00023 #include "interactive_polygon.h"
00024
00025
00026 enum flip_y_e { flip_y = true };
00027
00028 agg::rasterizer_scanline_aa<> g_rasterizer;
00029 agg::scanline_u8 g_scanline;
00030 double g_x1 = 0;
00031 double g_y1 = 0;
00032 double g_x2 = 0;
00033 double g_y2 = 0;
00034
00035
00036
00037 class the_application : public agg::platform_support
00038 {
00039 public:
00040 typedef agg::pixfmt_bgra32 pixfmt;
00041 typedef pixfmt::color_type color_type;
00042 typedef agg::renderer_base<pixfmt> renderer_base;
00043 typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
00044
00045 typedef agg::pixfmt_bgra32_pre pixfmt_pre;
00046 typedef agg::renderer_base<pixfmt_pre> renderer_base_pre;
00047
00048 agg::interactive_polygon m_quad;
00049 agg::rbox_ctrl<agg::rgba8> m_trans_type;
00050
00051 the_application(agg::pix_format_e format, bool flip_y) :
00052 agg::platform_support(format, flip_y),
00053 m_quad(4, 5.0),
00054 m_trans_type(420, 5.0, 420+170.0, 70.0, !flip_y)
00055 {
00056 m_trans_type.add_item("Affine Parallelogram");
00057 m_trans_type.add_item("Bilinear");
00058 m_trans_type.add_item("Perspective");
00059 m_trans_type.cur_item(2);
00060 add_ctrl(m_trans_type);
00061 }
00062
00063
00064 virtual void on_init()
00065 {
00066 double d = 0.0;
00067 g_x1 = d;
00068 g_y1 = d;
00069 g_x2 = rbuf_img(0).width() - d;
00070 g_y2 = rbuf_img(0).height() - d;
00071
00072 m_quad.xn(0) = 100;
00073 m_quad.yn(0) = 100;
00074 m_quad.xn(1) = width() - 100;
00075 m_quad.yn(1) = 100;
00076 m_quad.xn(2) = width() - 100;
00077 m_quad.yn(2) = height() - 100;
00078 m_quad.xn(3) = 100;
00079 m_quad.yn(3) = height() - 100;
00080 }
00081
00082 virtual void on_draw()
00083 {
00084 pixfmt pixf(rbuf_window());
00085 pixfmt_pre pixf_pre(rbuf_window());
00086 renderer_base rb(pixf);
00087 renderer_base_pre rb_pre(pixf_pre);
00088
00089 renderer_solid r(rb);
00090
00091
00092 rb.clear(agg::rgba(1, 1, 1));
00093
00094 if(m_trans_type.cur_item() == 0)
00095 {
00096
00097
00098 m_quad.xn(3) = m_quad.xn(0) + (m_quad.xn(2) - m_quad.xn(1));
00099 m_quad.yn(3) = m_quad.yn(0) + (m_quad.yn(2) - m_quad.yn(1));
00100 }
00101
00102
00103
00104 g_rasterizer.add_path(m_quad);
00105 agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rb,
00106 agg::rgba(0, 0.3, 0.5, 0.6));
00107
00108
00109
00110 g_rasterizer.clip_box(0, 0, width(), height());
00111 g_rasterizer.reset();
00112 g_rasterizer.move_to_d(m_quad.xn(0), m_quad.yn(0));
00113 g_rasterizer.line_to_d(m_quad.xn(1), m_quad.yn(1));
00114 g_rasterizer.line_to_d(m_quad.xn(2), m_quad.yn(2));
00115 g_rasterizer.line_to_d(m_quad.xn(3), m_quad.yn(3));
00116
00117 agg::span_allocator<color_type> sa;
00118 agg::image_filter_bilinear filter_kernel;
00119 agg::image_filter_lut filter(filter_kernel, false);
00120
00121 pixfmt pixf_img(rbuf_img(0));
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 typedef agg::image_accessor_clone<pixfmt> img_accessor_type;
00132 img_accessor_type ia(pixf_img);
00133
00134 start_timer();
00135 switch(m_trans_type.cur_item())
00136 {
00137 case 0:
00138 {
00139
00140
00141
00142
00143
00144 agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00145
00146
00147
00148
00149 typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type;
00150 interpolator_type interpolator(tr);
00151
00152 typedef agg::span_image_filter_rgba_nn<img_accessor_type,
00153 interpolator_type> span_gen_type;
00154 span_gen_type sg(ia, interpolator);
00155 agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00156 break;
00157 }
00158
00159 case 1:
00160 {
00161 agg::trans_bilinear tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00162 if(tr.is_valid())
00163 {
00164 typedef agg::span_interpolator_linear<agg::trans_bilinear> interpolator_type;
00165 interpolator_type interpolator(tr);
00166
00167 typedef agg::span_image_filter_rgba_2x2<img_accessor_type,
00168 interpolator_type> span_gen_type;
00169 span_gen_type sg(ia, interpolator, filter);
00170 agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00171 }
00172 break;
00173 }
00174
00175 case 2:
00176 {
00177 agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00178 if(tr.is_valid())
00179 {
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 typedef agg::span_interpolator_trans<agg::trans_perspective> interpolator_type;
00195 interpolator_type interpolator(tr);
00196 typedef agg::span_image_filter_rgba_2x2<img_accessor_type,
00197 interpolator_type> span_gen_type;
00198 span_gen_type sg(ia, interpolator, filter);
00199
00200
00201 agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00202 }
00203 break;
00204 }
00205 }
00206 double tm = elapsed_time();
00207
00208 char buf[128];
00209 agg::gsv_text t;
00210 t.size(10.0);
00211
00212 agg::conv_stroke<agg::gsv_text> pt(t);
00213 pt.width(1.5);
00214
00215 sprintf(buf, "%3.2f ms", tm);
00216 t.start_point(10.0, 10.0);
00217 t.text(buf);
00218
00219 g_rasterizer.add_path(pt);
00220 agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rb,
00221 agg::rgba(0,0,0));
00222
00223
00224 agg::render_ctrl(g_rasterizer, g_scanline, rb, m_trans_type);
00225 }
00226
00227
00228
00229 virtual void on_mouse_button_down(int x, int y, unsigned flags)
00230 {
00231 if(flags & agg::mouse_left)
00232 {
00233 if(m_quad.on_mouse_button_down(x, y))
00234 {
00235 force_redraw();
00236 }
00237 }
00238 }
00239
00240
00241 virtual void on_mouse_move(int x, int y, unsigned flags)
00242 {
00243 if(flags & agg::mouse_left)
00244 {
00245 if(m_quad.on_mouse_move(x, y))
00246 {
00247 force_redraw();
00248 }
00249 }
00250 if((flags & agg::mouse_left) == 0)
00251 {
00252 on_mouse_button_up(x, y, flags);
00253 }
00254 }
00255
00256
00257 virtual void on_mouse_button_up(int x, int y, unsigned flags)
00258 {
00259 if(m_quad.on_mouse_button_up(x, y))
00260 {
00261 force_redraw();
00262 }
00263 }
00264
00265 };
00266
00267
00268
00269
00270
00271
00272 int agg_main(int argc, char* argv[])
00273 {
00274 the_application app(agg::pix_format_bgra32, flip_y);
00275 app.caption("AGG Example. Image Perspective Transformations");
00276
00277 const char* img_name = "spheres";
00278 if(argc >= 2) img_name = argv[1];
00279 if(!app.load_img(0, img_name))
00280 {
00281 char buf[256];
00282 if(strcmp(img_name, "spheres") == 0)
00283 {
00284 sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
00285 "or copy it from another directory if available.",
00286 img_name, app.img_ext(), img_name, app.img_ext());
00287 }
00288 else
00289 {
00290 sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
00291 }
00292 app.message(buf);
00293 return 1;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 if(app.init(600, 600, agg::window_resize))
00320 {
00321 return app.run();
00322 }
00323 return 1;
00324 }
00325
00326
00327
00328
00329
00330