agg/examples/idea.cpp

365 lines
10 KiB
C++

#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_trans_affine.h"
#include "agg_conv_stroke.h"
#include "agg_conv_transform.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "ctrl/agg_slider_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_RGB24
//#define AGG_BGRA32
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_BGR96
//#define AGG_BGRA128
//#define AGG_RGB565
//#define AGG_RGB555
#include "pixel_formats.h"
enum flip_y_e { flip_y = false };
struct path_attributes
{
unsigned index;
agg::srgba8 fill_color;
agg::srgba8 stroke_color;
double stroke_width;
path_attributes() {}
path_attributes(unsigned idx,
const agg::srgba8& fill,
const agg::srgba8& stroke,
double width) :
index(idx),
fill_color(fill),
stroke_color(stroke),
stroke_width(width)
{
}
};
static double g_poly_bulb[] =
{
-6,-67, -6,-71, -7,-74, -8,-76, -10,-79,
-10,-82, -9,-84, -6,-86, -4,-87, -2,-86,
-1,-86, 1,-84, 2,-82, 2,-79, 0,-77,
-2,-73, -2,-71, -2,-69, -3,-67, -4,-65
};
static double g_poly_beam1[] =
{
-14,-84,-22,-85,-23,-87,-22,-88,-21,-88
};
static double g_poly_beam2[] =
{
-10,-92, -14,-96, -14,-98, -12,-99, -11,-97
};
static double g_poly_beam3[] =
{
-1,-92, -2,-98, 0,-100, 2,-100, 1,-98
};
static double g_poly_beam4[] =
{
5,-89, 11,-94, 13,-93, 13,-92, 12,-91
};
static double g_poly_fig1[] =
{
1,-48,-3,-54,-7,-58,-12,-58,-17,-55,-20,-52,-21,-47,
-20,-40,-17,-33,-11,-28,-6,-26,-2,-25,2,-26,4,-28,5,
-33,5,-39,3,-44,12,-48,12,-50,12,-51,3,-46
};
static double g_poly_fig2[] =
{
11,-27,6,-23,4,-22,3,-19,5,
-16,6,-15,11,-17,19,-23,25,-30,32,-38,32,-41,32,-50,30,-64,32,-72,
32,-75,31,-77,28,-78,26,-80,28,-87,27,-89,25,-88,24,-79,24,-76,23,
-75,20,-76,17,-76,17,-74,19,-73,22,-73,24,-71,26,-69,27,-64,28,-55,
28,-47,28,-40,26,-38,20,-33,14,-30
};
static double g_poly_fig3[] =
{
-6,-20,-9,-21,-15,-21,-20,-17,
-28,-8,-32,-1,-32,1,-30,6,-26,8,-20,10,-16,12,-14,14,-15,16,-18,20,
-22,20,-25,19,-27,20,-26,22,-23,23,-18,23,-14,22,-11,20,-10,17,-9,14,
-11,11,-16,9,-22,8,-26,5,-28,2,-27,-2,-23,-8,-19,-11,-12,-14,-6,-15,
-6,-18
};
static double g_poly_fig4[] =
{
11,-6,8,-16,5,-21,-1,-23,-7,
-22,-10,-17,-9,-10,-8,0,-8,10,-10,18,-11,22,-10,26,-7,28,-3,30,0,31,
5,31,10,27,14,18,14,11,11,2
};
static double g_poly_fig5[] =
{
0,22,-5,21,-8,22,-9,26,-8,49,
-8,54,-10,64,-10,75,-9,81,-10,84,-16,89,-18,95,-18,97,-13,100,-12,99,
-12,95,-10,90,-8,87,-6,86,-4,83,-3,82,-5,80,-6,79,-7,74,-6,63,-3,52,
0,42,1,31
};
static double g_poly_fig6[] =
{
12,31,12,24,8,21,3,21,2,24,3,
30,5,40,8,47,10,56,11,64,11,71,10,76,8,77,8,79,10,81,13,82,17,82,26,
84,28,87,32,86,33,81,32,80,25,79,17,79,14,79,13,76,14,72,14,64,13,55,
12,44,12,34
};
static path_attributes g_attr[3];
static agg::path_storage g_path;
static unsigned g_npaths = 0;
static agg::filling_rule_e g_pflag = agg::fill_non_zero;
static agg::rasterizer_scanline_aa<> g_rasterizer;
static agg::scanline_p8 g_scanline;
static double g_angle = 0.0;
#define AGG_POLY_SIZE(p) (sizeof(p) / (sizeof(*p) * 2))
struct trans_roundoff
{
static void transform(double* x, double* y)
{
*x = floor(*x + 0.5);
*y = floor(*y + 0.5);
}
};
class the_application : public agg::platform_support
{
double m_dx;
double m_dy;
agg::cbox_ctrl<color_type> m_rotate;
agg::cbox_ctrl<color_type> m_even_odd;
agg::cbox_ctrl<color_type> m_draft;
agg::cbox_ctrl<color_type> m_roundoff;
agg::slider_ctrl<color_type> m_angle_delta;
bool m_redraw_flag;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_rotate(10, 3, "Rotate", !flip_y),
m_even_odd(60, 3, "Even-Odd", !flip_y),
m_draft(130, 3, "Draft", !flip_y),
m_roundoff(175, 3, "Roundoff", !flip_y),
m_angle_delta(10, 21, 250-10, 27, !flip_y),
m_redraw_flag(true)
{
m_angle_delta.label("Step=%4.3f degree");
g_attr[g_npaths++] = path_attributes(g_path.start_new_path(),
agg::srgba8(255, 255, 0),
agg::srgba8(0, 0, 0),
1.0);
g_path.concat_poly(g_poly_bulb, AGG_POLY_SIZE(g_poly_bulb), true);
g_attr[g_npaths++] = path_attributes(g_path.start_new_path(),
agg::srgba8(255, 255, 200),
agg::srgba8(90, 0, 0),
0.7);
g_path.concat_poly(g_poly_beam1, AGG_POLY_SIZE(g_poly_beam1), true);
g_path.concat_poly(g_poly_beam2, AGG_POLY_SIZE(g_poly_beam2), true);
g_path.concat_poly(g_poly_beam3, AGG_POLY_SIZE(g_poly_beam3), true);
g_path.concat_poly(g_poly_beam4, AGG_POLY_SIZE(g_poly_beam4), true);
g_attr[g_npaths++] = path_attributes(g_path.start_new_path(),
agg::srgba8(0, 0, 0),
agg::srgba8(0, 0, 0),
0.0);
g_path.concat_poly(g_poly_fig1, AGG_POLY_SIZE(g_poly_fig1), true);
g_path.concat_poly(g_poly_fig2, AGG_POLY_SIZE(g_poly_fig2), true);
g_path.concat_poly(g_poly_fig3, AGG_POLY_SIZE(g_poly_fig3), true);
g_path.concat_poly(g_poly_fig4, AGG_POLY_SIZE(g_poly_fig4), true);
g_path.concat_poly(g_poly_fig5, AGG_POLY_SIZE(g_poly_fig5), true);
g_path.concat_poly(g_poly_fig6, AGG_POLY_SIZE(g_poly_fig6), true);
m_rotate.text_size(7);
m_even_odd.text_size(7);
m_draft.text_size(7);
m_roundoff.text_size(7);
add_ctrl(m_rotate);
add_ctrl(m_even_odd);
add_ctrl(m_draft);
add_ctrl(m_roundoff);
add_ctrl(m_angle_delta);
m_angle_delta.value(0.01);
}
virtual void on_init()
{
m_dx = rbuf_window().width();
m_dy = rbuf_window().height();
}
virtual void on_resize(int, int)
{
m_redraw_flag = true;
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> ren_base;
pixfmt pixf(rbuf_window());
ren_base rbase(pixf);
trans_roundoff roundoff;
if(m_redraw_flag)
{
g_rasterizer.gamma(agg::gamma_none());
rbase.clear(agg::srgba8(255,255,255));
g_rasterizer.filling_rule(agg::fill_non_zero);
agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_rotate);
agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_even_odd);
agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_draft);
agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_roundoff);
agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_angle_delta);
m_redraw_flag = false;
}
else
{
rbase.copy_bar(0,
int(32.0 * rbuf_window().height() / m_dy),
rbuf_window().width(),
rbuf_window().height(),
agg::srgba8(255,255,255));
}
if(m_draft.status())
{
g_rasterizer.gamma(agg::gamma_threshold(0.4));
}
agg::trans_affine mtx;
mtx.reset();
mtx *= agg::trans_affine_rotation(g_angle * agg::pi / 180.0);
mtx *= agg::trans_affine_translation(m_dx / 2, m_dy / 2 + 10);
mtx *= agg::trans_affine_scaling(rbuf_window().width() / m_dx,
rbuf_window().height() / m_dy);
agg::conv_transform<agg::path_storage> fill(g_path, mtx);
agg::conv_transform
<
agg::conv_transform<agg::path_storage>,
trans_roundoff
>
fill_roundoff(fill, roundoff);
agg::conv_stroke
<
agg::conv_transform<agg::path_storage>
>
stroke(fill);
agg::conv_stroke
<
agg::conv_transform
<
agg::conv_transform<agg::path_storage>,
trans_roundoff
>
>
stroke_roundoff(fill_roundoff);
g_pflag = m_even_odd.status() ? agg::fill_even_odd : agg::fill_non_zero;
unsigned i;
for(i = 0; i < g_npaths; i++)
{
g_rasterizer.filling_rule(g_pflag);
if(m_roundoff.status()) g_rasterizer.add_path(fill_roundoff, g_attr[i].index);
else g_rasterizer.add_path(fill, g_attr[i].index);
if(m_draft.status())
{
agg::render_scanlines_bin_solid(g_rasterizer, g_scanline, rbase, g_attr[i].fill_color);
}
else
{
agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rbase, g_attr[i].fill_color);
}
if(g_attr[i].stroke_width > 0.001)
{
stroke.width(g_attr[i].stroke_width * mtx.scale());
stroke_roundoff.width(g_attr[i].stroke_width * mtx.scale());
if(m_roundoff.status()) g_rasterizer.add_path(stroke_roundoff, g_attr[i].index);
else g_rasterizer.add_path(stroke, g_attr[i].index);
if(m_draft.status())
{
agg::render_scanlines_bin_solid(g_rasterizer, g_scanline, rbase, g_attr[i].stroke_color);
}
else
{
agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rbase, g_attr[i].stroke_color);
}
}
}
}
virtual void on_idle()
{
g_angle += m_angle_delta.value();
if(g_angle > 360.0) g_angle -= 360.0;
force_redraw();
}
virtual void on_ctrl_change()
{
wait_mode(!m_rotate.status());
m_redraw_flag = true;
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Idea");
if(app.init(250, 280, agg::window_resize))
{
return app.run();
}
return 1;
}