253 lines
8.1 KiB
C++
253 lines
8.1 KiB
C++
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include "agg_rendering_buffer.h"
|
|
#include "agg_rasterizer_scanline_aa.h"
|
|
#include "agg_scanline_u.h"
|
|
#include "agg_renderer_scanline.h"
|
|
#include "agg_span_allocator.h"
|
|
#include "agg_span_gradient.h"
|
|
#include "agg_gradient_lut.h"
|
|
#include "agg_gamma_lut.h"
|
|
#include "agg_span_interpolator_linear.h"
|
|
#include "ctrl/agg_slider_ctrl.h"
|
|
#include "platform/agg_platform_support.h"
|
|
|
|
#define AGG_BGR24
|
|
#include "pixel_formats.h"
|
|
|
|
enum { flip_y = true };
|
|
|
|
|
|
class the_application : public agg::platform_support
|
|
{
|
|
typedef agg::renderer_base<pixfmt> renderer_base;
|
|
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
|
|
typedef agg::gamma_lut<agg::int8u, agg::int8u> gamma_lut_type;
|
|
typedef agg::gradient_radial_focus gradient_func_type;
|
|
typedef agg::gradient_reflect_adaptor<gradient_func_type> gradient_adaptor_type;
|
|
typedef agg::gradient_lut<agg::color_interpolator<agg::srgba8>, 1024> color_func_type;
|
|
typedef agg::span_interpolator_linear<> interpolator_type;
|
|
typedef agg::span_allocator<color_type> span_allocator_type;
|
|
typedef agg::span_gradient<color_type,
|
|
interpolator_type,
|
|
gradient_adaptor_type,
|
|
color_func_type> span_gradient_type;
|
|
|
|
agg::slider_ctrl<color_type> m_gamma;
|
|
|
|
agg::scanline_u8 m_scanline;
|
|
agg::rasterizer_scanline_aa<> m_rasterizer;
|
|
span_allocator_type m_alloc;
|
|
color_func_type m_gradient_lut;
|
|
gamma_lut_type m_gamma_lut;
|
|
|
|
double m_mouse_x, m_mouse_y;
|
|
double m_old_gamma;
|
|
|
|
|
|
public:
|
|
the_application(agg::pix_format_e format, bool flip_y) :
|
|
agg::platform_support(format, flip_y),
|
|
m_gamma(5.0, 5.0, 340.0, 12.0, !flip_y),
|
|
m_mouse_x(200), m_mouse_y(200)
|
|
{
|
|
m_gamma.range(0.5, 2.5);
|
|
m_gamma.value(1.0);
|
|
m_gamma.label("Gamma = %.3f");
|
|
add_ctrl(m_gamma);
|
|
m_gamma.no_transform();
|
|
|
|
m_gamma_lut.gamma(m_gamma.value());
|
|
m_old_gamma = m_gamma.value();
|
|
|
|
build_gradient_lut();
|
|
}
|
|
|
|
virtual void on_init()
|
|
{
|
|
m_mouse_y = initial_height() / 2;
|
|
m_mouse_x = initial_width() / 2;
|
|
}
|
|
|
|
void build_gradient_lut()
|
|
{
|
|
m_gradient_lut.remove_all();
|
|
|
|
m_gradient_lut.add_color(0.0, agg::rgba8_gamma_dir(agg::srgba8(0, 255, 0), m_gamma_lut));
|
|
m_gradient_lut.add_color(0.2, agg::rgba8_gamma_dir(agg::srgba8(120, 0, 0), m_gamma_lut));
|
|
m_gradient_lut.add_color(0.7, agg::rgba8_gamma_dir(agg::srgba8(120, 120, 0), m_gamma_lut));
|
|
m_gradient_lut.add_color(1.0, agg::rgba8_gamma_dir(agg::srgba8(0, 0, 255), m_gamma_lut));
|
|
|
|
//m_gradient_lut.add_color(0.0, agg::srgba8::from_wavelength(380, m_gamma.value()));
|
|
//m_gradient_lut.add_color(0.1, agg::srgba8::from_wavelength(420, m_gamma.value()));
|
|
//m_gradient_lut.add_color(0.2, agg::srgba8::from_wavelength(460, m_gamma.value()));
|
|
//m_gradient_lut.add_color(0.3, agg::srgba8::from_wavelength(500, m_gamma.value()));
|
|
//m_gradient_lut.add_color(0.4, agg::srgba8::from_wavelength(540, m_gamma.value()));
|
|
//m_gradient_lut.add_color(0.5, agg::srgba8::from_wavelength(580, m_gamma.value()));
|
|
//m_gradient_lut.add_color(0.6, agg::srgba8::from_wavelength(620, m_gamma.value()));
|
|
//m_gradient_lut.add_color(0.7, agg::srgba8::from_wavelength(660, m_gamma.value()));
|
|
//m_gradient_lut.add_color(0.8, agg::srgba8::from_wavelength(700, m_gamma.value()));
|
|
//m_gradient_lut.add_color(0.9, agg::srgba8::from_wavelength(740, m_gamma.value()));
|
|
//m_gradient_lut.add_color(1.0, agg::srgba8::from_wavelength(780, m_gamma.value()));
|
|
|
|
m_gradient_lut.build_lut();
|
|
}
|
|
|
|
virtual void on_draw()
|
|
{
|
|
pixfmt pixf(rbuf_window());
|
|
renderer_base rb(pixf);
|
|
renderer_solid rs(rb);
|
|
rb.clear(agg::rgba(1, 1, 1));
|
|
|
|
// When Gamma changes rebuild the gamma and gradient LUTs
|
|
//------------------
|
|
if(m_old_gamma != m_gamma.value())
|
|
{
|
|
m_gamma_lut.gamma(m_gamma.value());
|
|
build_gradient_lut();
|
|
m_old_gamma = m_gamma.value();
|
|
}
|
|
|
|
|
|
// Gradient center. All gradient functions assume the
|
|
// center being in the origin (0,0) and you can't
|
|
// change it. But you can apply arbitrary transformations
|
|
// to the gradient (see below).
|
|
//------------------
|
|
double cx = initial_width() / 2;
|
|
double cy = initial_height() / 2;
|
|
double r = 100;
|
|
|
|
// Focal center. Defined in the gradient coordinates,
|
|
// that is, with respect to the origin (0,0)
|
|
//------------------
|
|
double fx = m_mouse_x - cx;
|
|
double fy = m_mouse_y - cy;
|
|
|
|
gradient_func_type gradient_func(r, fx, fy);
|
|
gradient_adaptor_type gradient_adaptor(gradient_func);
|
|
agg::trans_affine gradient_mtx;
|
|
|
|
// Making the affine matrix. Move to (cx,cy),
|
|
// apply the resizing transformations and invert
|
|
// the matrix. Gradients and images always assume the
|
|
// inverse transformations.
|
|
//------------------
|
|
gradient_mtx.translate(cx, cy);
|
|
gradient_mtx *= trans_affine_resizing();
|
|
gradient_mtx.invert();
|
|
|
|
interpolator_type span_interpolator(gradient_mtx);
|
|
span_gradient_type span_gradient(span_interpolator,
|
|
gradient_adaptor,
|
|
m_gradient_lut,
|
|
0, r);
|
|
|
|
// Form the simple rectangle
|
|
//------------------
|
|
m_rasterizer.reset();
|
|
m_rasterizer.move_to_d(0,0);
|
|
m_rasterizer.line_to_d(width(), 0);
|
|
m_rasterizer.line_to_d(width(), height());
|
|
m_rasterizer.line_to_d(0, height());
|
|
|
|
// Render the gradient to the whole screen and measure the time
|
|
//------------------
|
|
start_timer();
|
|
agg::render_scanlines_aa(m_rasterizer, m_scanline, rb, m_alloc, span_gradient);
|
|
double tm = elapsed_time();
|
|
|
|
// Draw the transformed circle that shows the gradient boundary
|
|
//------------------
|
|
agg::ellipse e(cx, cy, r, r);
|
|
agg::conv_stroke<agg::ellipse> estr(e);
|
|
agg::conv_transform<
|
|
agg::conv_stroke<
|
|
agg::ellipse> > etrans(estr, trans_affine_resizing());
|
|
|
|
m_rasterizer.add_path(etrans);
|
|
agg::render_scanlines_aa_solid(m_rasterizer, m_scanline, rb, agg::rgba(1,1,1));
|
|
|
|
// Show the gradient time
|
|
//------------------
|
|
char buf[64];
|
|
agg::gsv_text t;
|
|
t.size(10.0);
|
|
agg::conv_stroke<agg::gsv_text> pt(t);
|
|
pt.width(1.5);
|
|
sprintf(buf, "%3.2f ms", tm);
|
|
t.start_point(10.0, 35.0);
|
|
t.text(buf);
|
|
m_rasterizer.add_path(pt);
|
|
agg::render_scanlines_aa_solid(m_rasterizer, m_scanline, rb, agg::rgba(0,0,0));
|
|
|
|
// Show the controls
|
|
//------------------
|
|
agg::render_ctrl(m_rasterizer, m_scanline, rb, m_gamma);
|
|
|
|
// Apply the inverse gamma to the whole buffer
|
|
// (transform the colors to the perceptually uniform space)
|
|
//------------------
|
|
pixf.apply_gamma_inv(m_gamma_lut);
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void on_mouse_move(int x, int y, unsigned flags)
|
|
{
|
|
if(flags & agg::mouse_left)
|
|
{
|
|
m_mouse_x = x;
|
|
m_mouse_y = y;
|
|
trans_affine_resizing().inverse_transform(&m_mouse_x, &m_mouse_y);
|
|
force_redraw();
|
|
}
|
|
}
|
|
|
|
|
|
virtual void on_mouse_button_down(int x, int y, unsigned flags)
|
|
{
|
|
if(flags & agg::mouse_left)
|
|
{
|
|
m_mouse_x = x;
|
|
m_mouse_y = y;
|
|
trans_affine_resizing().inverse_transform(&m_mouse_x, &m_mouse_y);
|
|
force_redraw();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int agg_main(int argc, char* argv[])
|
|
{
|
|
the_application app(pix_format, flip_y);
|
|
app.caption("AGG Example. PDF linear and radial gradients");
|
|
|
|
if(app.init(600, 400, agg::window_resize))
|
|
{
|
|
return app.run();
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|