383 lines
11 KiB
C++
383 lines
11 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include "agg_rendering_buffer.h"
|
|
#include "agg_rasterizer_scanline_aa.h"
|
|
#include "agg_path_storage.h"
|
|
#include "agg_trans_affine.h"
|
|
#include "agg_conv_transform.h"
|
|
#include "agg_conv_smooth_poly1.h"
|
|
#include "agg_scanline_p.h"
|
|
#include "agg_renderer_scanline.h"
|
|
#include "agg_span_allocator.h"
|
|
#include "agg_span_pattern_gray.h"
|
|
#include "agg_span_pattern_rgb.h"
|
|
#include "agg_span_pattern_rgba.h"
|
|
#include "agg_image_accessors.h"
|
|
#include "ctrl/agg_slider_ctrl.h"
|
|
#include "ctrl/agg_rbox_ctrl.h"
|
|
#include "ctrl/agg_cbox_ctrl.h"
|
|
#include "platform/agg_platform_support.h"
|
|
|
|
enum flip_y_e { flip_y = true };
|
|
|
|
//#define AGG_GRAY8
|
|
//#define AGG_BGR24
|
|
//#define AGG_RGB24
|
|
#define AGG_BGRA32
|
|
//#define AGG_RGBA32
|
|
//#define AGG_ARGB32
|
|
//#define AGG_ABGR32
|
|
//#define AGG_BGRA128
|
|
//#define AGG_RGB565
|
|
//#define AGG_RGB555
|
|
#include "pixel_formats.h"
|
|
|
|
|
|
|
|
|
|
class the_application : public agg::platform_support
|
|
{
|
|
agg::slider_ctrl<agg::rgba> m_polygon_angle;
|
|
agg::slider_ctrl<agg::rgba> m_polygon_scale;
|
|
|
|
agg::slider_ctrl<agg::rgba> m_pattern_angle;
|
|
agg::slider_ctrl<agg::rgba> m_pattern_size;
|
|
|
|
agg::slider_ctrl<agg::rgba> m_pattern_alpha;
|
|
|
|
agg::cbox_ctrl<agg::rgba> m_rotate_polygon;
|
|
agg::cbox_ctrl<agg::rgba> m_rotate_pattern;
|
|
agg::cbox_ctrl<agg::rgba> m_tie_pattern;
|
|
|
|
double m_polygon_cx;
|
|
double m_polygon_cy;
|
|
|
|
double m_dx;
|
|
double m_dy;
|
|
|
|
int m_flag;
|
|
|
|
agg::int8u* m_pattern;
|
|
agg::rendering_buffer m_pattern_rbuf;
|
|
|
|
agg::rasterizer_scanline_aa<> m_ras;
|
|
agg::scanline_p8 m_sl;
|
|
agg::path_storage m_ps;
|
|
|
|
|
|
public:
|
|
//------------------------------------------------------------------------
|
|
the_application(agg::pix_format_e format, bool flip_y) :
|
|
agg::platform_support(format, flip_y),
|
|
m_polygon_angle(5, 5, 145, 12, !flip_y),
|
|
m_polygon_scale(5, 5+14, 145, 12+14, !flip_y),
|
|
m_pattern_angle(155, 5, 300, 12, !flip_y),
|
|
m_pattern_size (155, 5+14, 300, 12+14, !flip_y),
|
|
m_pattern_alpha(310, 5, 460, 12, !flip_y),
|
|
m_rotate_polygon(5, 5+14+14, "Rotate Polygon", !flip_y),
|
|
m_rotate_pattern(5, 5+14+14+14, "Rotate Pattern", !flip_y),
|
|
m_tie_pattern (155, 5+14+14, "Tie pattern to polygon", !flip_y),
|
|
m_flag(0),
|
|
m_pattern(0)
|
|
{
|
|
add_ctrl(m_polygon_angle);
|
|
add_ctrl(m_polygon_scale);
|
|
add_ctrl(m_pattern_angle);
|
|
add_ctrl(m_pattern_size);
|
|
add_ctrl(m_pattern_alpha);
|
|
add_ctrl(m_rotate_polygon);
|
|
add_ctrl(m_rotate_pattern);
|
|
add_ctrl(m_tie_pattern);
|
|
|
|
m_polygon_angle.label("Polygon Angle=%3.2f");
|
|
m_polygon_angle.range(-180.0, 180.0);
|
|
|
|
m_polygon_scale.label("Polygon Scale=%3.2f");
|
|
m_polygon_scale.range(0.1, 5.0);
|
|
m_polygon_scale.value(1.0);
|
|
|
|
m_pattern_angle.label("Pattern Angle=%3.2f");
|
|
m_pattern_angle.range(-180.0, 180.0);
|
|
|
|
m_pattern_size.label("Pattern Size=%3.2f");
|
|
m_pattern_size.range(10, 40);
|
|
m_pattern_size.value(30);
|
|
|
|
m_pattern_alpha.label("Background Alpha=%.2f");
|
|
m_pattern_alpha.value(0.1);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
virtual ~the_application()
|
|
{
|
|
delete [] m_pattern;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
void create_star(double xc, double yc,
|
|
double r1, double r2,
|
|
unsigned n, double start_angle = 0.0)
|
|
{
|
|
m_ps.remove_all();
|
|
unsigned i;
|
|
start_angle *= agg::pi / 180.0;
|
|
for(i = 0; i < n; i++)
|
|
{
|
|
double a = agg::pi * 2.0 * i / n - agg::pi / 2.0;
|
|
double dx = cos(a + start_angle);
|
|
double dy = sin(a + start_angle);
|
|
|
|
if(i & 1)
|
|
{
|
|
m_ps.line_to(xc + dx * r1, yc + dy * r1);
|
|
}
|
|
else
|
|
{
|
|
if(i) m_ps.line_to(xc + dx * r2, yc + dy * r2);
|
|
else m_ps.move_to(xc + dx * r2, yc + dy * r2);
|
|
}
|
|
}
|
|
m_ps.close_polygon();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
void generate_pattern()
|
|
{
|
|
unsigned size = unsigned(m_pattern_size.value());
|
|
|
|
create_star(m_pattern_size.value() / 2.0,
|
|
m_pattern_size.value() / 2.0,
|
|
m_pattern_size.value() / 2.5,
|
|
m_pattern_size.value() / 6.0,
|
|
6,
|
|
m_pattern_angle.value());
|
|
|
|
agg::conv_smooth_poly1_curve<agg::path_storage> smooth(m_ps);
|
|
agg::conv_stroke<agg::conv_smooth_poly1_curve<agg::path_storage> > stroke(smooth);
|
|
|
|
smooth.smooth_value(1.0);
|
|
smooth.approximation_scale(4.0);
|
|
stroke.width(m_pattern_size.value() / 15.0);
|
|
|
|
delete [] m_pattern;
|
|
m_pattern = new agg::int8u[size * size * pixfmt::pix_width];
|
|
m_pattern_rbuf.attach(m_pattern, size, size, size * pixfmt::pix_width);
|
|
|
|
pixfmt pixf(m_pattern_rbuf);
|
|
agg::renderer_base<pixfmt> rb(pixf);
|
|
agg::renderer_scanline_aa_solid<agg::renderer_base<pixfmt> > rs(rb);
|
|
|
|
rb.clear(agg::rgba_pre(0.4, 0.0, 0.1, m_pattern_alpha.value())); // Pattern background color
|
|
|
|
m_ras.add_path(smooth);
|
|
rs.color(agg::srgba8(110,130,50));
|
|
agg::render_scanlines(m_ras, m_sl, rs);
|
|
|
|
m_ras.add_path(stroke);
|
|
rs.color(agg::srgba8(0,50,80));
|
|
agg::render_scanlines(m_ras, m_sl, rs);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
virtual void on_init()
|
|
{
|
|
m_polygon_cx = initial_width() / 2.0;
|
|
m_polygon_cy = initial_height() / 2.0;
|
|
generate_pattern();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
virtual void on_draw()
|
|
{
|
|
double width = rbuf_window().width();
|
|
double height = rbuf_window().height();
|
|
|
|
typedef agg::renderer_base<pixfmt> renderer_base;
|
|
typedef agg::renderer_base<pixfmt_pre> renderer_base_pre;
|
|
|
|
pixfmt pixf(rbuf_window());
|
|
pixfmt_pre pixf_pre(rbuf_window());
|
|
|
|
renderer_base rb(pixf);
|
|
renderer_base_pre rb_pre(pixf_pre);
|
|
|
|
rb.clear(agg::rgba(1.0, 1.0, 1.0));
|
|
|
|
agg::trans_affine polygon_mtx;
|
|
|
|
polygon_mtx *= agg::trans_affine_translation(-m_polygon_cx, -m_polygon_cy);
|
|
polygon_mtx *= agg::trans_affine_rotation(m_polygon_angle.value() * agg::pi / 180.0);
|
|
polygon_mtx *= agg::trans_affine_scaling(m_polygon_scale.value());
|
|
polygon_mtx *= agg::trans_affine_translation(m_polygon_cx, m_polygon_cy);
|
|
|
|
double r = initial_width() / 3.0 - 8.0;
|
|
create_star(m_polygon_cx, m_polygon_cy, r, r / 1.45, 14);
|
|
|
|
agg::conv_transform<agg::path_storage> tr(m_ps, polygon_mtx);
|
|
|
|
typedef agg::wrap_mode_reflect_auto_pow2 wrap_x_type;
|
|
typedef agg::wrap_mode_reflect_auto_pow2 wrap_y_type;
|
|
typedef agg::image_accessor_wrap<pixfmt,
|
|
wrap_x_type,
|
|
wrap_y_type> img_source_type;
|
|
typedef agg::span_pattern_rgba<img_source_type> span_gen_type;
|
|
|
|
unsigned offset_x = 0;
|
|
unsigned offset_y = 0;
|
|
|
|
if(m_tie_pattern.status())
|
|
{
|
|
offset_x = unsigned(width-m_polygon_cx);
|
|
offset_y = unsigned(height-m_polygon_cy);
|
|
}
|
|
|
|
agg::span_allocator<color_type> sa;
|
|
pixfmt img_pixf(m_pattern_rbuf);
|
|
img_source_type img_src(img_pixf);
|
|
span_gen_type sg(img_src, offset_x, offset_y);
|
|
|
|
// Alpha is meaningful for RGB only because RGBA has its own
|
|
sg.alpha(span_gen_type::value_type(m_pattern_alpha.value() * 255.0));
|
|
|
|
m_ras.add_path(tr);
|
|
agg::render_scanlines_aa(m_ras, m_sl, rb_pre, sa, sg);
|
|
|
|
agg::render_ctrl(m_ras, m_sl, rb, m_polygon_angle);
|
|
agg::render_ctrl(m_ras, m_sl, rb, m_polygon_scale);
|
|
agg::render_ctrl(m_ras, m_sl, rb, m_pattern_angle);
|
|
agg::render_ctrl(m_ras, m_sl, rb, m_pattern_size);
|
|
agg::render_ctrl(m_ras, m_sl, rb, m_pattern_alpha);
|
|
agg::render_ctrl(m_ras, m_sl, rb, m_rotate_polygon);
|
|
agg::render_ctrl(m_ras, m_sl, rb, m_rotate_pattern);
|
|
agg::render_ctrl(m_ras, m_sl, rb, m_tie_pattern);
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
virtual void on_mouse_button_down(int x, int y, unsigned flags)
|
|
{
|
|
if(flags & agg::mouse_left)
|
|
{
|
|
agg::trans_affine polygon_mtx;
|
|
|
|
polygon_mtx *= agg::trans_affine_translation(-m_polygon_cx, -m_polygon_cy);
|
|
polygon_mtx *= agg::trans_affine_rotation(m_polygon_angle.value() * agg::pi / 180.0);
|
|
polygon_mtx *= agg::trans_affine_scaling(m_polygon_scale.value(), m_polygon_scale.value());
|
|
polygon_mtx *= agg::trans_affine_translation(m_polygon_cx, m_polygon_cy);
|
|
|
|
double r = initial_width() / 3.0 - 8.0;
|
|
create_star(m_polygon_cx, m_polygon_cy, r, r / 1.45, 14);
|
|
|
|
agg::conv_transform<agg::path_storage> tr(m_ps, polygon_mtx);
|
|
m_ras.add_path(tr);
|
|
if(m_ras.hit_test(x, y))
|
|
{
|
|
m_dx = x - m_polygon_cx;
|
|
m_dy = y - m_polygon_cy;
|
|
m_flag = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
virtual void on_mouse_move(int x, int y, unsigned flags)
|
|
{
|
|
if(flags & agg::mouse_left)
|
|
{
|
|
if(m_flag)
|
|
{
|
|
m_polygon_cx = x - m_dx;
|
|
m_polygon_cy = y - m_dy;
|
|
force_redraw();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
on_mouse_button_up(x, y, flags);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
virtual void on_mouse_button_up(int x, int y, unsigned flags)
|
|
{
|
|
m_flag = 0;
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
virtual void on_ctrl_change()
|
|
{
|
|
if(m_rotate_polygon.status() || m_rotate_pattern.status())
|
|
{
|
|
wait_mode(false);
|
|
}
|
|
else
|
|
{
|
|
wait_mode(true);
|
|
}
|
|
|
|
generate_pattern();
|
|
force_redraw();
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
virtual void on_idle()
|
|
{
|
|
bool redraw = false;
|
|
if(m_rotate_polygon.status())
|
|
{
|
|
m_polygon_angle.value(m_polygon_angle.value() + 0.5);
|
|
if(m_polygon_angle.value() >= 180.0)
|
|
{
|
|
m_polygon_angle.value(m_polygon_angle.value() - 360.0);
|
|
}
|
|
redraw = true;
|
|
}
|
|
|
|
if(m_rotate_pattern.status())
|
|
{
|
|
m_pattern_angle.value(m_pattern_angle.value() - 0.5);
|
|
if(m_pattern_angle.value() <= -180.0)
|
|
{
|
|
m_pattern_angle.value(m_pattern_angle.value() + 360.0);
|
|
}
|
|
generate_pattern();
|
|
redraw = true;
|
|
}
|
|
|
|
if(redraw) force_redraw();
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
int agg_main(int argc, char* argv[])
|
|
{
|
|
the_application app(pix_format, flip_y);
|
|
app.caption("AGG Example: Pattern Filling");
|
|
|
|
if(app.init(640, 480, 0))
|
|
{
|
|
return app.run();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|