00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include "agg_rendering_buffer.h"
00004 #include "agg_rasterizer_scanline_aa.h"
00005 #include "agg_conv_transform.h"
00006 #include "agg_bspline.h"
00007 #include "agg_ellipse.h"
00008 #include "agg_gsv_text.h"
00009 #include "agg_scanline_p.h"
00010 #include "agg_renderer_scanline.h"
00011 #include "ctrl/agg_slider_ctrl.h"
00012 #include "ctrl/agg_scale_ctrl.h"
00013 #include "platform/agg_platform_support.h"
00014
00015 #define AGG_BGR24
00016
00017
00018
00019
00020
00021
00022
00023 #include "pixel_formats.h"
00024
00025 enum flip_y_e { flip_y = true };
00026 enum default_num_points_e { default_num_points = 10000 };
00027
00028 enum start_size_e
00029 {
00030 start_width = 400,
00031 start_height = 400
00032 };
00033
00034 static double spline_r_x[] = { 0.000000, 0.200000, 0.400000, 0.910484, 0.957258, 1.000000 };
00035 static double spline_r_y[] = { 1.000000, 0.800000, 0.600000, 0.066667, 0.169697, 0.600000 };
00036
00037 static double spline_g_x[] = { 0.000000, 0.292244, 0.485655, 0.564859, 0.795607, 1.000000 };
00038 static double spline_g_y[] = { 0.000000, 0.607260, 0.964065, 0.892558, 0.435571, 0.000000 };
00039
00040 static double spline_b_x[] = { 0.000000, 0.055045, 0.143034, 0.433082, 0.764859, 1.000000 };
00041 static double spline_b_y[] = { 0.385480, 0.128493, 0.021416, 0.271507, 0.713974, 1.000000 };
00042
00043
00044 struct scatter_point
00045 {
00046 double x;
00047 double y;
00048 double z;
00049 agg::rgba color;
00050 };
00051
00052
00053 double random_dbl(double start, double end)
00054 {
00055 unsigned r = rand() & 0x7FFF;
00056 return double(r) * (end - start) / 32768.0 + start;
00057 }
00058
00059
00060 class the_application : public agg::platform_support
00061 {
00062 unsigned m_num_points;
00063 scatter_point* m_points;
00064
00065 agg::scale_ctrl<agg::rgba8> m_scale_ctrl_z;
00066 agg::slider_ctrl<agg::rgba8> m_slider_ctrl_sel;
00067 agg::slider_ctrl<agg::rgba8> m_slider_ctrl_size;
00068
00069 agg::bspline m_spline_r;
00070 agg::bspline m_spline_g;
00071 agg::bspline m_spline_b;
00072
00073 public:
00074 virtual ~the_application()
00075 {
00076 delete [] m_points;
00077 }
00078
00079 the_application(agg::pix_format_e format, bool flip_y, unsigned num_points) :
00080 agg::platform_support(format, flip_y),
00081 m_num_points(num_points),
00082 m_points(new scatter_point [num_points]),
00083 m_scale_ctrl_z (5, 5, start_width-5, 12, !flip_y),
00084 m_slider_ctrl_sel (5, 20, start_width-5, 27, !flip_y),
00085 m_slider_ctrl_size(5, 35, start_width-5, 42, !flip_y)
00086 {
00087
00088 m_spline_r.init(6, spline_r_x, spline_r_y);
00089 m_spline_g.init(6, spline_g_x, spline_g_y);
00090 m_spline_b.init(6, spline_b_x, spline_b_y);
00091
00092 add_ctrl(m_scale_ctrl_z);
00093 add_ctrl(m_slider_ctrl_sel);
00094 add_ctrl(m_slider_ctrl_size);
00095
00096 m_slider_ctrl_size.label("Size");
00097 m_slider_ctrl_sel.label("Selectivity");
00098 }
00099
00100
00101 void generate()
00102 {
00103 unsigned i;
00104
00105 double rx = initial_width()/3.5;
00106 double ry = initial_height()/3.5;
00107
00108 for(i = 0; i < m_num_points; i++)
00109 {
00110 double z = m_points[i].z = random_dbl(0.0, 1.0);
00111 double x = cos(z * 2.0 * agg::pi) * rx;
00112 double y = sin(z * 2.0 * agg::pi) * ry;
00113
00114 double dist = random_dbl(0.0, rx/2.0);
00115 double angle = random_dbl(0.0, agg::pi * 2.0);
00116
00117 m_points[i].x = initial_width()/2.0 + x + cos(angle) * dist;
00118 m_points[i].y = initial_height()/2.0 + y + sin(angle) * dist;
00119 m_points[i].color = agg::rgba(m_spline_r.get(z)*0.8,
00120 m_spline_g.get(z)*0.8,
00121 m_spline_b.get(z)*0.8,
00122 1.0);
00123 }
00124 }
00125
00126
00127 virtual void on_init()
00128 {
00129 generate();
00130 }
00131
00132
00133 virtual void on_draw()
00134 {
00135 agg::rasterizer_scanline_aa<> pf;
00136 agg::scanline_p8 sl;
00137
00138 typedef agg::renderer_base<pixfmt> renderer_base;
00139
00140 pixfmt pixf(rbuf_window());
00141 renderer_base rb(pixf);
00142
00143 rb.clear(agg::rgba(1,1,1));
00144
00145 agg::ellipse e1;
00146 agg::conv_transform<agg::ellipse> t1(e1, trans_affine_resizing());
00147
00148
00149 unsigned i;
00150 unsigned n_drawn = 0;
00151 for(i = 0; i < m_num_points; i++)
00152 {
00153 double z = m_points[i].z;
00154 double alpha = 1.0;
00155 if(z < m_scale_ctrl_z.value1())
00156 {
00157 alpha =
00158 1.0 -
00159 (m_scale_ctrl_z.value1() - z) *
00160 m_slider_ctrl_sel.value() * 100.0;
00161 }
00162
00163 if(z > m_scale_ctrl_z.value2())
00164 {
00165 alpha =
00166 1.0 -
00167 (z - m_scale_ctrl_z.value2()) *
00168 m_slider_ctrl_sel.value() * 100.0;
00169 }
00170
00171
00172
00173 if(alpha > 1.0) alpha = 1.0;
00174 if(alpha < 0.0) alpha = 0.0;
00175
00176 if(alpha > 0.0)
00177 {
00178 e1.init(m_points[i].x,
00179 m_points[i].y,
00180 m_slider_ctrl_size.value() * 5.0,
00181 m_slider_ctrl_size.value() * 5.0,
00182 8);
00183 pf.add_path(t1);
00184
00185 agg::render_scanlines_aa_solid(
00186 pf, sl, rb,
00187 agg::rgba(m_points[i].color.r,
00188 m_points[i].color.g,
00189 m_points[i].color.b,
00190 alpha));
00191 n_drawn++;
00192 }
00193 }
00194
00195 agg::render_ctrl(pf, sl, rb, m_scale_ctrl_z);
00196 agg::render_ctrl(pf, sl, rb, m_slider_ctrl_sel);
00197 agg::render_ctrl(pf, sl, rb, m_slider_ctrl_size);
00198
00199 char buf[10];
00200 sprintf(buf, "%08u", n_drawn);
00201
00202 agg::gsv_text txt;
00203 txt.size(15.0);
00204 txt.text(buf);
00205 txt.start_point(10.0, initial_height() - 20.0);
00206 agg::gsv_text_outline<> txt_o(txt, trans_affine_resizing());
00207 pf.add_path(txt_o);
00208 agg::render_scanlines_aa_solid(pf, sl, rb, agg::rgba(0,0,0));
00209
00210 }
00211
00212
00213 virtual void on_idle()
00214 {
00215 unsigned i;
00216 for(i = 0; i < m_num_points; i++)
00217 {
00218 m_points[i].x += random_dbl(0, m_slider_ctrl_sel.value()) - m_slider_ctrl_sel.value()*0.5;
00219 m_points[i].y += random_dbl(0, m_slider_ctrl_sel.value()) - m_slider_ctrl_sel.value()*0.5;
00220 m_points[i].z += random_dbl(0, m_slider_ctrl_sel.value()*0.01) - m_slider_ctrl_sel.value()*0.005;
00221 if(m_points[i].z < 0.0) m_points[i].z = 0.0;
00222 if(m_points[i].z > 1.0) m_points[i].z = 1.0;
00223 }
00224 force_redraw();
00225 }
00226
00227
00228 virtual void on_mouse_button_down(int x, int y, unsigned flags)
00229 {
00230 if(flags & agg::mouse_left)
00231 {
00232 generate();
00233 force_redraw();
00234 }
00235
00236 if(flags & agg::mouse_right)
00237 {
00238 wait_mode(!wait_mode());
00239 }
00240 }
00241
00242 };
00243
00244
00245
00246 int agg_main(int argc, char* argv[])
00247 {
00248 unsigned num_points = default_num_points;
00249 if(argc > 1)
00250 {
00251 num_points = atoi(argv[1]);
00252 if(num_points == 0) num_points = default_num_points;
00253 if(num_points > 20000) num_points = 20000;
00254 }
00255
00256 the_application app(pix_format, flip_y, num_points);
00257 app.caption("AGG Drawing random circles - A scatter plot prototype");
00258
00259 if(app.init(start_width, start_height, agg::window_resize | agg::window_keep_aspect_ratio))
00260 {
00261 return app.run();
00262 }
00263 return 1;
00264 }
00265
00266