mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-30 06:33:43 +02:00
456 lines
8.1 KiB
ObjectPascal
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. |