00001 #include <stdio.h>
00002 #include "agg_basics.h"
00003 #include "agg_rendering_buffer.h"
00004 #include "agg_rasterizer_scanline_aa.h"
00005 #include "agg_scanline_u.h"
00006 #include "agg_renderer_scanline.h"
00007 #include "agg_span_gradient.h"
00008 #include "agg_span_gradient_alpha.h"
00009 #include "agg_span_interpolator_linear.h"
00010 #include "agg_span_allocator.h"
00011 #include "agg_span_converter.h"
00012 #include "agg_ellipse.h"
00013 #include "agg_pixfmt_rgb.h"
00014 #include "agg_vcgen_stroke.h"
00015 #include "platform/agg_platform_support.h"
00016
00017 #include "ctrl/agg_spline_ctrl.h"
00018
00019 enum flip_y_e { flip_y = true };
00020
00021
00022
00023 #define pix_format agg::pix_format_bgr24
00024 typedef agg::pixfmt_bgr24 pixfmt_type;
00025 typedef pixfmt_type::color_type color_type;
00026 typedef color_type::value_type color_value_type;
00027
00028
00029 class the_application : public agg::platform_support
00030 {
00031 double m_x[3];
00032 double m_y[3];
00033 double m_dx;
00034 double m_dy;
00035 int m_idx;
00036 agg::spline_ctrl<color_type> m_alpha;
00037
00038
00039 public:
00040 the_application(agg::pix_format_e format, bool flip_y) :
00041 agg::platform_support(format, flip_y),
00042 m_idx(-1),
00043 m_alpha(2, 2, 200, 30, 6, !flip_y)
00044 {
00045 m_x[0] = 257; m_y[0] = 60;
00046 m_x[1] = 369; m_y[1] = 170;
00047 m_x[2] = 143; m_y[2] = 310;
00048
00049 m_alpha.point(0, 0.0, 0.0);
00050 m_alpha.point(1, 1.0/5.0, 1.0 - 4.0/5.0);
00051 m_alpha.point(2, 2.0/5.0, 1.0 - 3.0/5.0);
00052 m_alpha.point(3, 3.0/5.0, 1.0 - 2.0/5.0);
00053 m_alpha.point(4, 4.0/5.0, 1.0 - 1.0/5.0);
00054 m_alpha.point(5, 1.0, 1.0);
00055 m_alpha.update_spline();
00056 add_ctrl(m_alpha);
00057 }
00058
00059
00060
00061
00062
00063
00064 template<class ColorArrayT>
00065 static void fill_color_array(ColorArrayT& array,
00066 color_type begin,
00067 color_type middle,
00068 color_type end)
00069 {
00070 unsigned i;
00071 for(i = 0; i < 128; ++i)
00072 {
00073 array[i] = begin.gradient(middle, i / 128.0);
00074 }
00075 for(; i < 256; ++i)
00076 {
00077 array[i] = middle.gradient(end, (i - 128) / 128.0);
00078 }
00079 }
00080
00081
00082
00083 virtual void on_draw()
00084 {
00085 typedef agg::renderer_base<pixfmt_type> base_ren_type;
00086
00087 pixfmt_type pf(rbuf_window());
00088 base_ren_type ren_base(pf);
00089 ren_base.clear(agg::rgba(1,1,1));
00090
00091 agg::scanline_u8 sl;
00092 agg::rasterizer_scanline_aa<> ras;
00093
00094
00095
00096 agg::ellipse ell;
00097 srand(1234);
00098 unsigned i;
00099 unsigned w = unsigned(width());
00100 unsigned h = unsigned(height());
00101 for(i = 0; i < 100; i++)
00102 {
00103 ell.init(rand() % w, rand() % h, rand() % 60 + 5, rand() % 60 + 5, 50);
00104 ras.add_path(ell);
00105 agg::render_scanlines_aa_solid(ras, sl, ren_base,
00106 agg::rgba(rand() / double(RAND_MAX),
00107 rand() / double(RAND_MAX),
00108 rand() / double(RAND_MAX),
00109 rand() / double(RAND_MAX) / 2.0));
00110 }
00111
00112
00113
00114 double parallelogram[6];
00115 parallelogram[0] = m_x[0];
00116 parallelogram[1] = m_y[0];
00117 parallelogram[2] = m_x[1];
00118 parallelogram[3] = m_y[1];
00119 parallelogram[4] = m_x[2];
00120 parallelogram[5] = m_y[2];
00121
00122
00123
00124
00125 typedef agg::gradient_circle gradient_func_type;
00126
00127
00128
00129 typedef agg::gradient_xy gradient_alpha_func_type;
00130
00131
00132
00133
00134
00135 typedef agg::span_interpolator_linear<> interpolator_type;
00136
00137
00138
00139
00140
00141
00142
00143 typedef agg::span_allocator<color_type> span_allocator_type;
00144
00145
00146
00147
00148 typedef agg::pod_auto_array<color_type, 256> gradient_colors_type;
00149
00150
00151
00152
00153
00154 typedef agg::span_gradient<color_type,
00155 interpolator_type,
00156 gradient_func_type,
00157 gradient_colors_type> span_gradient_type;
00158
00159
00160
00161
00162 typedef agg::pod_auto_array<color_value_type, 256> gradient_alpha_type;
00163
00164
00165
00166
00167 typedef agg::span_gradient_alpha<color_type,
00168 interpolator_type,
00169 gradient_alpha_func_type,
00170 gradient_alpha_type> span_gradient_alpha_type;
00171
00172
00173
00174
00175 typedef agg::span_converter<span_gradient_type,
00176 span_gradient_alpha_type> span_conv_type;
00177
00178
00179
00180
00181 gradient_func_type gradient_func;
00182 gradient_alpha_func_type alpha_func;
00183 agg::trans_affine gradient_mtx;
00184 agg::trans_affine alpha_mtx;
00185 interpolator_type span_interpolator(gradient_mtx);
00186 interpolator_type span_interpolator_alpha(alpha_mtx);
00187 span_allocator_type span_allocator;
00188 gradient_colors_type color_array;
00189
00190
00191
00192
00193
00194
00195
00196 span_gradient_type span_gradient(span_interpolator,
00197 gradient_func,
00198 color_array,
00199 0, 150);
00200
00201
00202
00203
00204
00205
00206
00207 gradient_alpha_type alpha_array;
00208 span_gradient_alpha_type span_gradient_alpha(span_interpolator_alpha,
00209 alpha_func,
00210 alpha_array,
00211 0, 100);
00212
00213
00214 span_conv_type span_conv(span_gradient, span_gradient_alpha);
00215
00216
00217
00218
00219 gradient_mtx *= agg::trans_affine_scaling(0.75, 1.2);
00220 gradient_mtx *= agg::trans_affine_rotation(-agg::pi/3.0);
00221 gradient_mtx *= agg::trans_affine_translation(width()/2, height()/2);
00222 gradient_mtx.invert();
00223 alpha_mtx.parl_to_rect(parallelogram, -100, -100, 100, 100);
00224 fill_color_array(color_array,
00225 agg::rgba(0, 0.19, 0.19),
00226 agg::rgba(0.7, 0.7, 0.19),
00227 agg::rgba(0.31, 0, 0));
00228
00229
00230
00231 for(i = 0; i < 256; i++)
00232 {
00233 alpha_array[i] = color_value_type(m_alpha.value(i / 255.0) * double(color_type::base_mask));
00234 }
00235
00236 ell.init(width()/2, height()/2, 150, 150, 100);
00237 ras.add_path(ell);
00238
00239
00240 agg::render_scanlines_aa(ras, sl, ren_base, span_allocator, span_conv);
00241
00242
00243
00244
00245 agg::rgba color_pnt(0, 0.4, 0.4, 0.31);
00246 ell.init(m_x[0], m_y[0], 5, 5, 20);
00247 ras.add_path(ell);
00248 agg::render_scanlines_aa_solid(ras, sl, ren_base, color_pnt);
00249 ell.init(m_x[1], m_y[1], 5, 5, 20);
00250 ras.add_path(ell);
00251 agg::render_scanlines_aa_solid(ras, sl, ren_base, color_pnt);
00252 ell.init(m_x[2], m_y[2], 5, 5, 20);
00253 ras.add_path(ell);
00254 agg::render_scanlines_aa_solid(ras, sl, ren_base, color_pnt);
00255
00256 agg::vcgen_stroke stroke;
00257 stroke.add_vertex(m_x[0], m_y[0], agg::path_cmd_move_to);
00258 stroke.add_vertex(m_x[1], m_y[1], agg::path_cmd_line_to);
00259 stroke.add_vertex(m_x[2], m_y[2], agg::path_cmd_line_to);
00260 stroke.add_vertex(m_x[0]+m_x[2]-m_x[1], m_y[0]+m_y[2]-m_y[1], agg::path_cmd_line_to);
00261 stroke.add_vertex(0, 0, agg::path_cmd_end_poly | agg::path_flags_close);
00262 ras.add_path(stroke);
00263 agg::render_scanlines_aa_solid(ras, sl, ren_base, agg::rgba(0, 0, 0));
00264
00265 agg::render_ctrl(ras, sl, ren_base, m_alpha);
00266 }
00267
00268
00269
00270
00271
00272 virtual void on_mouse_button_down(int x, int y, unsigned flags)
00273 {
00274 unsigned i;
00275 if(flags & agg::mouse_left)
00276 {
00277 for (i = 0; i < 3; i++)
00278 {
00279 if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 10.0)
00280 {
00281 m_dx = x - m_x[i];
00282 m_dy = y - m_y[i];
00283 m_idx = i;
00284 break;
00285 }
00286 }
00287 if(i == 3)
00288 {
00289 if(agg::point_in_triangle(m_x[0], m_y[0],
00290 m_x[1], m_y[1],
00291 m_x[2], m_y[2],
00292 x, y))
00293 {
00294 m_dx = x - m_x[0];
00295 m_dy = y - m_y[0];
00296 m_idx = 3;
00297 }
00298
00299 }
00300 }
00301 }
00302
00303
00304 virtual void on_mouse_move(int x, int y, unsigned flags)
00305 {
00306 if(flags & agg::mouse_left)
00307 {
00308 if(m_idx == 3)
00309 {
00310 double dx = x - m_dx;
00311 double dy = y - m_dy;
00312 m_x[1] -= m_x[0] - dx;
00313 m_y[1] -= m_y[0] - dy;
00314 m_x[2] -= m_x[0] - dx;
00315 m_y[2] -= m_y[0] - dy;
00316 m_x[0] = dx;
00317 m_y[0] = dy;
00318 force_redraw();
00319 return;
00320 }
00321
00322 if(m_idx >= 0)
00323 {
00324 m_x[m_idx] = x - m_dx;
00325 m_y[m_idx] = y - m_dy;
00326 force_redraw();
00327 }
00328 }
00329 else
00330 {
00331 on_mouse_button_up(x, y, flags);
00332 }
00333 }
00334
00335 virtual void on_mouse_button_up(int x, int y, unsigned flags)
00336 {
00337 m_idx = -1;
00338 }
00339
00340
00341 virtual void on_key(int x, int y, unsigned key, unsigned flags)
00342 {
00343 double dx = 0;
00344 double dy = 0;
00345 switch(key)
00346 {
00347 case agg::key_left: dx = -0.1; break;
00348 case agg::key_right: dx = 0.1; break;
00349 case agg::key_up: dy = 0.1; break;
00350 case agg::key_down: dy = -0.1; break;
00351 }
00352 m_x[0] += dx;
00353 m_y[0] += dy;
00354 m_x[1] += dx;
00355 m_y[1] += dy;
00356 force_redraw();
00357 }
00358
00359
00360 };
00361
00362
00363 int agg_main(int argc, char* argv[])
00364 {
00365 the_application app(pix_format, flip_y);
00366 app.caption("AGG Example. Alpha channel gradient");
00367
00368 if(app.init(400, 320, agg::window_resize))
00369 {
00370 return app.run();
00371 }
00372 return 1;
00373 }
00374
00375