lazarus/components/aggpas/aa_demo.dpr
mattias 36a2b1ea07 added aggpas
git-svn-id: trunk@21942 -
2009-10-01 12:24:32 +00:00

456 lines
8.1 KiB
ObjectPascal

//
// AggPas 2.4 RM3 Demo application
// Note: Press F1 key on run to see more info about this demo
//
// Paths: src;src\ctrl;src\svg;src\util;src\platform\win;expat-wrap
//
program
aa_demo ;
uses
agg_basics ,
agg_platform_support ,
agg_math ,
agg_color ,
agg_pixfmt ,
agg_pixfmt_rgb ,
agg_ctrl ,
agg_slider_ctrl ,
agg_cbox_ctrl ,
agg_renderer_base ,
agg_renderer_scanline ,
agg_rasterizer_scanline_aa ,
agg_scanline ,
agg_scanline_p ,
agg_scanline_u ,
agg_render_scanlines ,
agg_gamma_functions ,
agg_path_storage ,
agg_conv_stroke ,
agg_vertex_source ;
{$I agg_mode.inc }
const
flip_y = true;
type
square = object
m_size : double;
constructor Construct(size : double );
procedure draw(ras : rasterizer_scanline_aa_ptr; sl : scanline_ptr; ren : renderer_scanline_ptr; x ,y : double );
end;
renderer_enlarged = object(renderer_scanline )
m_ras : rasterizer_scanline_aa;
m_sl : scanline_u8;
m_ren : renderer_scanline_aa_solid_ptr;
m_square : square;
m_color : aggclr;
m_size : double;
constructor Construct(ren : renderer_scanline_aa_solid_ptr; size : double );
destructor Destruct;
procedure color (c : aggclr_ptr ); virtual;
procedure prepare(u : unsigned ); virtual;
procedure render (sl : scanline_ptr ); virtual;
end;
the_application = object(platform_support )
m_x ,
m_y : array[0..2 ] of double;
m_dx ,
m_dy : double;
m_idx : int;
m_slider1 ,
m_slider2 : slider_ctrl;
constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
destructor Destruct;
procedure on_draw; virtual;
procedure on_mouse_move (x ,y : int; flags : unsigned ); virtual;
procedure on_mouse_button_down(x ,y : int; flags : unsigned ); virtual;
procedure on_mouse_button_up (x ,y : int; flags : unsigned ); virtual;
procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
end;
{ CONSTRUCT }
constructor square.Construct;
begin
m_size:=size;
end;
{ DRAW }
procedure square.Draw;
begin
ras.reset;
ras.move_to_d(x * m_size ,y * m_size );
ras.line_to_d(x * m_size + m_size ,y * m_size );
ras.line_to_d(x * m_size + m_size ,y * m_size + m_size );
ras.line_to_d(x * m_size ,y * m_size + m_size );
render_scanlines(ras ,sl ,ren );
end;
{ CONSTRUCT }
constructor renderer_enlarged.Construct;
begin
m_square.Construct(size );
m_ras.Construct;
m_sl.Construct;
m_color.Construct;
m_ren :=ren;
m_size:=size;
end;
{ DESTRUCT }
destructor renderer_enlarged.Destruct;
begin
m_ras.Destruct;
m_sl.Destruct;
end;
{ COLOR }
procedure renderer_enlarged.color;
begin
m_color:=c^;
end;
{ PREPARE }
procedure renderer_enlarged.prepare;
begin
end;
{ RENDER }
procedure renderer_enlarged.render;
var
y ,x ,a ,
num_pix : int;
num_spans : unsigned;
span : span_u8_ptr;
covers : int8u_ptr;
rgba : aggclr;
begin
y :=sl.y;
num_spans:=sl.num_spans;
span :=sl.begin_;
repeat
x :=span.x;
covers :=span.covers;
num_pix:=span.len;
repeat
a:=shr_int32(covers^ * m_color.a ,8 );
inc(ptrcomp(covers ) ,sizeof(int8u ) );
rgba.ConstrInt(m_color.r ,m_color.g ,m_color.b ,a );
m_ren.color_ (@rgba );
m_square.draw (@m_ras ,@m_sl ,m_ren ,x ,y );
inc(x );
dec(num_pix );
until num_pix = 0;
dec(num_spans );
until num_spans = 0;
end;
{ CONSTRUCT }
constructor the_application.Construct;
begin
inherited Construct(format_ ,flip_y_ );
m_slider1.Construct(80 ,10 ,600 - 10 ,19 ,not flip_y );
m_slider2.Construct(80 ,10 + 20 ,600 - 10 ,19 + 20 ,not flip_y_ );
m_idx:=-1;
m_x[0 ]:=57; m_y[0 ]:=100;
m_x[1 ]:=369; m_y[1 ]:=170;
m_x[2 ]:=143; m_y[2 ]:=310;
add_ctrl(@m_slider1 );
add_ctrl(@m_slider2 );
m_slider1.range_ (8.0 ,100.0 );
m_slider1.num_steps_(23 );
m_slider1.value_ (32.0 );
m_slider2.range_(0.1 ,3.0 );
m_slider2.value_(1.0 );
m_slider1.label_('Pixel size=%1.0f' );
m_slider2.label_('Gamma=%4.3f' );
m_slider1.no_transform;
m_slider2.no_transform;
end;
{ DESTRUCT }
destructor the_application.Destruct;
begin
inherited Destruct;
m_slider1.Destruct;
m_slider2.Destruct;
end;
{ ON_DRAW }
procedure the_application.on_draw;
var
size_mul : int;
pixf : pixel_formats;
rb : renderer_base;
ren : renderer_scanline_aa_solid;
ras : rasterizer_scanline_aa;
sl : scanline_u8;
rgba : aggclr;
gm_no : vertex_source;
gm_pw : gamma_power;
ren_en : renderer_enlarged;
ps : path_storage;
pg : conv_stroke;
begin
// Initialize structures
pixfmt_bgr24(pixf ,rbuf_window );
rb.Construct (@pixf );
ren.Construct(@rb );
rgba.ConstrDbl(1 ,1 ,1 );
rb.clear(@rgba );
sl.Construct;
ras.Construct;
// Draw Zoomed Triangle
size_mul:=trunc(m_slider1._value );
gm_pw.Construct(m_slider2._value );
ras.gamma (@gm_pw );
ren_en.Construct(@ren ,size_mul );
rgba.ConstrInt(0 ,0 ,0 ,255 );
ren_en.color (@rgba );
ras.reset;
ras.move_to_d(m_x[0 ] / size_mul ,m_y[0 ] / size_mul );
ras.line_to_d(m_x[1 ] / size_mul ,m_y[1 ] / size_mul );
ras.line_to_d(m_x[2 ] / size_mul ,m_y[2 ] / size_mul );
render_scanlines(@ras ,@sl ,@ren_en );
// Draw final triangle bottom-left
rgba.ConstrInt(0 ,0 ,0 );
ren.color_ (@rgba );
render_scanlines(@ras ,@sl ,@ren );
// Draw The Supposed Triangle over
gm_no.Construct;
ras.gamma(@gm_no );
ps.Construct;
pg.Construct(@ps );
pg.width_ (2.0 );
rgba.ConstrInt(0 ,150 ,160 ,200 );
ren.color_ (@rgba );
ps.remove_all;
ps.move_to(m_x[0 ] ,m_y[0 ] );
ps.line_to(m_x[1 ] ,m_y[1 ] );
ras.add_path(@pg );
render_scanlines(@ras ,@sl ,@ren );
ps.remove_all;
ps.move_to(m_x[1 ] ,m_y[1 ] );
ps.line_to(m_x[2 ] ,m_y[2 ] );
ras.add_path(@pg );
render_scanlines(@ras ,@sl ,@ren );
ps.remove_all;
ps.move_to(m_x[2 ] ,m_y[2 ] );
ps.line_to(m_x[0 ] ,m_y[0 ] );
ras.add_path(@pg );
render_scanlines(@ras ,@sl ,@ren );
// Render the controls
render_ctrl(@ras ,@sl ,@ren ,@m_slider1 );
render_ctrl(@ras ,@sl ,@ren ,@m_slider2 );
// Free AGG resources
ras.Destruct;
sl.Destruct;
pg.Destruct;
ps.Destruct;
ren_en.Destruct;
end;
{ ON_MOUSE_MOVE }
procedure the_application.on_mouse_move;
var
dx ,dy : double;
begin
if flags and mouse_left <> 0 then
begin
if m_idx = 3 then
begin
dx:=x - m_dx;
dy:=y - m_dy;
m_x[1 ]:=m_x[1 ] - (m_x[0 ] - dx );
m_y[1 ]:=m_y[1 ] - (m_y[0 ] - dy );
m_x[2 ]:=m_x[2 ] - (m_x[0 ] - dx );
m_y[2 ]:=m_y[2 ] - (m_y[0 ] - dy );
m_x[0 ]:= dx;
m_y[0 ]:= dy;
force_redraw;
exit;
end;
if m_idx >= 0 then
begin
m_x[m_idx ]:=x - m_dx;
m_y[m_idx ]:=y - m_dy;
force_redraw;
end;
end
else
on_mouse_button_up(x ,y ,flags );
end;
{ ON_MOUSE_BUTTON_DOWN }
procedure the_application.on_mouse_button_down;
var
i : unsigned;
begin
if flags and mouse_left <> 0 then
begin
i:=0;
while i < 3 do
begin
if Sqrt((x - m_x[ i ] ) * (x - m_x[i ] ) + (y - m_y[i ] ) * (y - m_y[i ] ) ) < 10.0 then
begin
m_dx :=x - m_x[i ];
m_dy :=y - m_y[i ];
m_idx:=i;
break;
end;
inc(i );
end;
if i = 3 then
if point_in_triangle(m_x[0 ] ,m_y[0 ] ,m_x[1 ] ,m_y[1 ] ,m_x[2 ] ,m_y[2 ] ,x ,y ) then
begin
m_dx :=x - m_x[0 ];
m_dy :=y - m_y[0 ];
m_idx:=3;
end;
end;
end;
{ ON_MOUSE_BUTTON_UP }
procedure the_application.on_mouse_button_up;
begin
m_idx:=-1;
end;
{ ON_KEY }
procedure the_application.on_key;
begin
if key = key_f1 then
message_(
'Demonstration of the Anti-Aliasing principle with Subpixel Accuracy.'#13 +
'The triangle is rendered two times, with its "natural" size (at the bottom-left)'#13 +
'and enlarged. To draw the enlarged version there was a special scanline'#13 +
'renderer written (see class renderer_enlarged in the source code).'#13#13+
'How to play with:'#13#13 +
'You can drag the whole triangle as well as each vertex of it.'#13 +
'Also change "Gamma" to see how it affects the quality of Anti-Aliasing.' +
#13#13'Note: F2 key saves current "screenshot" file in this demo''s directory. ' );
end;
VAR
app : the_application;
BEGIN
app.Construct(pix_format_bgr24 ,flip_y );
app.caption_ ('AGG Example. Anti-Aliasing Demo (F1-Help)' );
if app.init(600 ,400 ,window_resize ) then
app.run;
app.Destruct;
END.