mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-01 00:43:42 +02:00
983 lines
16 KiB
ObjectPascal
983 lines
16 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
|
|
gouraud_mesh ;
|
|
|
|
uses
|
|
SysUtils ,
|
|
agg_basics ,
|
|
agg_color ,
|
|
agg_array ,
|
|
agg_math ,
|
|
agg_math_stroke ,
|
|
agg_platform_support ,
|
|
agg_ctrl ,
|
|
agg_slider_ctrl ,
|
|
agg_bezier_ctrl ,
|
|
agg_rbox_ctrl ,
|
|
agg_cbox_ctrl ,
|
|
agg_renderer_base ,
|
|
agg_rendering_buffer ,
|
|
agg_conv_transform ,
|
|
agg_conv_stroke ,
|
|
agg_conv_clip_polyline ,
|
|
agg_scanline_u ,
|
|
agg_scanline_bin ,
|
|
agg_renderer_scanline ,
|
|
agg_rasterizer_outline_aa ,
|
|
agg_rasterizer_scanline_aa ,
|
|
agg_span_allocator ,
|
|
agg_span_gouraud_rgba ,
|
|
agg_gamma_lut ,
|
|
agg_arc ,
|
|
agg_bezier_arc ,
|
|
agg_pixfmt ,
|
|
agg_pixfmt_rgb ,
|
|
agg_pixfmt_rgba ,
|
|
agg_bounding_rect ,
|
|
agg_vpgen_clip_polygon ,
|
|
agg_rasterizer_compound_aa ,
|
|
agg_gsv_text ;
|
|
|
|
{$I agg_mode.inc }
|
|
|
|
const
|
|
flip_y = true;
|
|
|
|
type
|
|
mesh_point_ptr = ^mesh_point;
|
|
mesh_point = object
|
|
x ,y ,dx ,dy : double;
|
|
color ,dc : aggclr;
|
|
|
|
constructor Construct; overload;
|
|
constructor Construct(x_ ,y_ ,dx_ ,dy_ : double; c ,dc_ : aggclr_ptr ); overload;
|
|
|
|
end;
|
|
|
|
mesh_triangle_ptr = ^mesh_triangle;
|
|
mesh_triangle = object
|
|
p1 ,p2 ,p3 : unsigned;
|
|
|
|
constructor Construct; overload;
|
|
constructor Construct(i ,j ,k : unsigned ); overload;
|
|
|
|
end;
|
|
|
|
mesh_edge_ptr = ^mesh_edge;
|
|
mesh_edge = object
|
|
p1 ,p2 : unsigned;
|
|
tl ,tr : int;
|
|
|
|
constructor Construct; overload;
|
|
constructor Construct(p1_ ,p2_ : unsigned; tl_ ,tr_ : int ); overload;
|
|
|
|
end;
|
|
|
|
mesh_ctrl_ptr = ^mesh_ctrl;
|
|
mesh_ctrl = object
|
|
m_cols ,
|
|
m_rows : unsigned;
|
|
|
|
m_drag_idx : int;
|
|
|
|
m_drag_dx ,
|
|
m_drag_dy ,
|
|
m_cell_w ,
|
|
m_cell_h ,
|
|
m_start_x ,
|
|
m_start_y : double;
|
|
|
|
m_vertices ,
|
|
m_triangles ,
|
|
m_edges : pod_bvector;
|
|
|
|
constructor Construct;
|
|
destructor Destruct;
|
|
|
|
procedure generate(
|
|
cols ,rows : unsigned;
|
|
cell_w ,cell_h ,start_x ,start_y : double );
|
|
|
|
procedure randomize_points(delta : double );
|
|
procedure rotate_colors;
|
|
|
|
function on_mouse_button_down(x ,y : double; flags : unsigned ) : boolean;
|
|
function on_mouse_move (x ,y : double; flags : unsigned ) : boolean;
|
|
function on_mouse_button_up (x ,y : double; flags : unsigned ) : boolean;
|
|
|
|
function num_vertices : unsigned;
|
|
function vertex(i : unsigned ) : mesh_point_ptr; overload;
|
|
function vertex(x ,y : unsigned ) : mesh_point_ptr; overload;
|
|
|
|
function num_triangles : unsigned;
|
|
function triangle(i : unsigned ) : mesh_triangle_ptr;
|
|
|
|
function num_edges : unsigned;
|
|
function edge(i : unsigned ) : mesh_edge_ptr;
|
|
|
|
end;
|
|
|
|
styles_gouraud = object(style_handler )
|
|
m_triangles : pod_bvector;
|
|
|
|
m_rgba : aggclr;
|
|
|
|
constructor Construct(mesh : mesh_ctrl_ptr; gamma : gamma_ptr );
|
|
destructor Destruct;
|
|
|
|
function is_solid(style : unsigned ) : boolean; virtual;
|
|
function color (style : unsigned ) : aggclr_ptr; virtual;
|
|
|
|
procedure generate_span(span : aggclr_ptr; x ,y : int; len ,style : unsigned ); virtual;
|
|
|
|
end;
|
|
|
|
the_application = object(platform_support )
|
|
m_mesh : mesh_ctrl;
|
|
m_gamma : gamma_lut;
|
|
|
|
constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
|
|
destructor Destruct;
|
|
|
|
procedure on_init; virtual;
|
|
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;
|
|
procedure on_idle; virtual;
|
|
procedure on_ctrl_change; virtual;
|
|
|
|
end;
|
|
|
|
{ random }
|
|
function random_(v1 ,v2 : double ) : double;
|
|
begin
|
|
result:=(v2 - v1 ) * (rand mod 1000 ) / 999.0 + v1;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor mesh_point.Construct;
|
|
begin
|
|
x :=0;
|
|
y :=0;
|
|
dx:=0;
|
|
dy:=0;
|
|
|
|
color.Construct;
|
|
dc.Construct;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor mesh_point.Construct(x_ ,y_ ,dx_ ,dy_ : double; c ,dc_ : aggclr_ptr );
|
|
begin
|
|
x :=x_;
|
|
y :=y_;
|
|
dx:=dx_;
|
|
dy:=dy_;
|
|
|
|
color.Construct(c );
|
|
dc.Construct(dc_ );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor mesh_triangle.Construct;
|
|
begin
|
|
p1:=0;
|
|
p2:=0;
|
|
p3:=0;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor mesh_triangle.Construct(i ,j ,k : unsigned );
|
|
begin
|
|
p1:=i;
|
|
p2:=j;
|
|
p3:=k;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor mesh_edge.Construct;
|
|
begin
|
|
p1:=0;
|
|
p2:=0;
|
|
tl:=0;
|
|
tr:=0;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor mesh_edge.Construct(p1_ ,p2_ : unsigned; tl_ ,tr_ : int );
|
|
begin
|
|
p1:=p1_;
|
|
p2:=p2_;
|
|
tl:=tl_;
|
|
tr:=tr_;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor mesh_ctrl.Construct;
|
|
begin
|
|
m_vertices.Construct(sizeof(mesh_point ) );
|
|
m_triangles.Construct(sizeof(mesh_triangle ) );
|
|
m_edges.Construct(sizeof(mesh_edge ) );
|
|
|
|
m_cols:=0;
|
|
m_rows:=0;
|
|
|
|
m_drag_idx:=-1;
|
|
m_drag_dx :=0;
|
|
m_drag_dy :=0;
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor mesh_ctrl.Destruct;
|
|
begin
|
|
m_vertices.Destruct;
|
|
m_triangles.Destruct;
|
|
m_edges.Destruct;
|
|
|
|
end;
|
|
|
|
{ GENERATE }
|
|
procedure mesh_ctrl.generate(
|
|
cols ,rows : unsigned;
|
|
cell_w ,cell_h ,start_x ,start_y : double );
|
|
var
|
|
i ,j : unsigned;
|
|
|
|
x ,dx ,dy : double;
|
|
|
|
p1 ,p2 ,p3 ,p4 ,curr_cell ,left_cell ,bott_cell ,
|
|
|
|
curr_t1 ,curr_t2 ,left_t1 ,left_t2 ,bott_t1 ,bott_t2 : int;
|
|
|
|
c ,dc : aggclr;
|
|
|
|
c1 ,c2 ,c3 : int8u;
|
|
|
|
mp : mesh_point;
|
|
mt : mesh_triangle;
|
|
me : mesh_edge;
|
|
|
|
begin
|
|
m_cols :=cols;
|
|
m_rows :=rows;
|
|
m_cell_w:=cell_w;
|
|
m_cell_h:=cell_h;
|
|
|
|
m_start_x:=start_x;
|
|
m_start_y:=start_y;
|
|
|
|
m_vertices.remove_all;
|
|
|
|
i:=0;
|
|
|
|
while i < m_rows do
|
|
begin
|
|
x:=start_x;
|
|
j:=0;
|
|
|
|
while j < m_cols do
|
|
begin
|
|
dx:=random_(-0.5 ,0.5 );
|
|
dy:=random_(-0.5 ,0.5 );
|
|
|
|
c1:=rand and $FF;
|
|
c2:=rand and $FF;
|
|
c3:=rand and $FF;
|
|
|
|
c.ConstrInt (c3 ,c2 ,c1 );
|
|
|
|
c1:=rand and 1;
|
|
c2:=rand and 1;
|
|
c3:=rand and 1;
|
|
|
|
dc.ConstrInt(c3 ,c2 ,c1 );
|
|
|
|
mp.Construct (x ,start_y ,dx ,dy ,@c ,@dc );
|
|
m_vertices.add(@mp );
|
|
|
|
x:=x + cell_w;
|
|
|
|
inc(j );
|
|
|
|
end;
|
|
|
|
start_y:=start_y + cell_h;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
// 4---3
|
|
// |t2/|
|
|
// | / |
|
|
// |/t1|
|
|
// 1---2
|
|
m_triangles.remove_all;
|
|
m_edges.remove_all;
|
|
|
|
i:=0;
|
|
|
|
while i < m_rows - 1 do
|
|
begin
|
|
j:=0;
|
|
|
|
while j < m_cols - 1 do
|
|
begin
|
|
p1:=i * m_cols + j;
|
|
p2:=p1 + 1;
|
|
p3:=p2 + m_cols;
|
|
p4:=p1 + m_cols;
|
|
|
|
mt.Construct (p1 ,p2 ,p3 );
|
|
m_triangles.add(@mt );
|
|
mt.Construct (p3 ,p4 ,p1 );
|
|
m_triangles.add(@mt );
|
|
|
|
curr_cell:=i * (m_cols - 1 ) + j;
|
|
|
|
if j <> 0 then
|
|
left_cell:=int(curr_cell - 1 )
|
|
else
|
|
left_cell:=-1;
|
|
|
|
if i <> 0 then
|
|
bott_cell:=int(curr_cell - (m_cols - 1 ) )
|
|
else
|
|
bott_cell:=-1;
|
|
|
|
curr_t1:=curr_cell * 2;
|
|
curr_t2:=curr_t1 + 1;
|
|
|
|
if left_cell >= 0 then
|
|
left_t1:=left_cell * 2
|
|
else
|
|
left_t1:=-1;
|
|
|
|
if left_cell >= 0 then
|
|
left_t2:=left_t1 + 1
|
|
else
|
|
left_t2:=-1;
|
|
|
|
if bott_cell >= 0 then
|
|
bott_t1:=bott_cell * 2
|
|
else
|
|
bott_t1:=-1;
|
|
|
|
if bott_cell >= 0 then
|
|
bott_t2:=bott_t1 + 1
|
|
else
|
|
bott_t2:=-1;
|
|
|
|
me.Construct(p1 ,p2 ,curr_t1 ,bott_t2 );
|
|
m_edges.add (@me );
|
|
me.Construct(p1 ,p3 ,curr_t2 ,curr_t1 );
|
|
m_edges.add (@me );
|
|
me.Construct(p1 ,p4 ,left_t1 ,curr_t2 );
|
|
m_edges.add (@me );
|
|
|
|
if j = m_cols - 2 then // Last column
|
|
begin
|
|
me.Construct(p2 ,p3 ,curr_t1 ,-1 );
|
|
m_edges.add (@me );
|
|
|
|
end;
|
|
|
|
if i = m_rows - 2 then // Last row
|
|
begin
|
|
me.Construct(p3 ,p4 ,curr_t2 ,-1 );
|
|
m_edges.add (@me );
|
|
|
|
end;
|
|
|
|
inc(j );
|
|
|
|
end;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ RANDOMIZE_POINTS }
|
|
procedure mesh_ctrl.randomize_points(delta : double );
|
|
var
|
|
i ,j : unsigned;
|
|
|
|
xc ,yc ,x1 ,y1 ,x2 ,y2 : double;
|
|
|
|
p : mesh_point_ptr;
|
|
|
|
begin
|
|
i:=0;
|
|
|
|
while i < m_rows do
|
|
begin
|
|
j:=0;
|
|
|
|
while j < m_cols do
|
|
begin
|
|
xc:=j * m_cell_w + m_start_x;
|
|
yc:=i * m_cell_h + m_start_y;
|
|
x1:=xc - m_cell_w / 4;
|
|
y1:=yc - m_cell_h / 4;
|
|
x2:=xc + m_cell_w / 4;
|
|
y2:=yc + m_cell_h / 4;
|
|
|
|
p:=vertex(j ,i );
|
|
|
|
p.x:=p.x + p.dx;
|
|
p.y:=p.y + p.dy;
|
|
|
|
if p.x < x1 then
|
|
begin
|
|
p.x :=x1;
|
|
p.dx:=-p.dx;
|
|
|
|
end;
|
|
|
|
if p.y < y1 then
|
|
begin
|
|
p.y :=y1;
|
|
p.dy:=-p.dy;
|
|
|
|
end;
|
|
|
|
if p.x > x2 then
|
|
begin
|
|
p.x :=x2;
|
|
p.dx:=-p.dx;
|
|
|
|
end;
|
|
|
|
if p.y > y2 then
|
|
begin
|
|
p.y :=y2;
|
|
p.dy:=-p.dy;
|
|
|
|
end;
|
|
|
|
inc(j );
|
|
|
|
end;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ ROTATE_COLORS }
|
|
procedure mesh_ctrl.rotate_colors;
|
|
var
|
|
i : unsigned;
|
|
|
|
c ,dc : aggclr_ptr;
|
|
|
|
r ,g ,b : int;
|
|
|
|
begin
|
|
i:=1;
|
|
|
|
while i < m_vertices.size do
|
|
begin
|
|
c :=@mesh_point_ptr(m_vertices.array_operator(i ) ).color;
|
|
dc:=@mesh_point_ptr(m_vertices.array_operator(i ) ).dc;
|
|
|
|
if dc.r <> 0 then
|
|
r:=c.r + 5
|
|
else
|
|
r:=c.r - 5;
|
|
|
|
if dc.g <> 0 then
|
|
g:=c.g + 5
|
|
else
|
|
g:=c.g - 5;
|
|
|
|
if dc.b <> 0 then
|
|
b:=c.b + 5
|
|
else
|
|
b:=c.b - 5;
|
|
|
|
if r < 0 then
|
|
begin
|
|
r :=0;
|
|
dc.r:=dc.r xor 1;
|
|
|
|
end;
|
|
|
|
if r > 255 then
|
|
begin
|
|
r :=255;
|
|
dc.r:=dc.r xor 1;
|
|
|
|
end;
|
|
|
|
if g < 0 then
|
|
begin
|
|
g :=0;
|
|
dc.g:=dc.g xor 1;
|
|
|
|
end;
|
|
|
|
if g > 255 then
|
|
begin
|
|
g :=255;
|
|
dc.g:=dc.g xor 1;
|
|
|
|
end;
|
|
|
|
if b < 0 then
|
|
begin
|
|
b :=0;
|
|
dc.b:=dc.b xor 1;
|
|
|
|
end;
|
|
|
|
if b > 255 then
|
|
begin
|
|
b := 255;
|
|
dc.b:=dc.b xor 1;
|
|
|
|
end;
|
|
|
|
c.r:=r;
|
|
c.g:=g;
|
|
c.b:=b;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_BUTTON_DOWN }
|
|
function mesh_ctrl.on_mouse_button_down(x ,y : double; flags : unsigned ) : boolean;
|
|
var
|
|
i : unsigned;
|
|
|
|
begin
|
|
if flags and 1 <> 0 then
|
|
begin
|
|
i:=0;
|
|
|
|
while i < m_vertices.size do
|
|
begin
|
|
if calc_distance(
|
|
x ,y ,
|
|
mesh_point_ptr(m_vertices.array_operator(i ) ).x ,
|
|
mesh_point_ptr(m_vertices.array_operator(i ) ).y ) < 5 then
|
|
begin
|
|
m_drag_idx:=i;
|
|
|
|
m_drag_dx:=x - mesh_point_ptr(m_vertices.array_operator(i ) ).x;
|
|
m_drag_dy:=y - mesh_point_ptr(m_vertices.array_operator(i ) ).y;
|
|
|
|
result:=true;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
result:=false;
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_MOVE }
|
|
function mesh_ctrl.on_mouse_move(x ,y : double; flags : unsigned ) : boolean;
|
|
begin
|
|
if flags and 1 <> 0 then
|
|
begin
|
|
if m_drag_idx >= 0 then
|
|
begin
|
|
mesh_point_ptr(m_vertices.array_operator(m_drag_idx ) ).x:=x - m_drag_dx;
|
|
mesh_point_ptr(m_vertices.array_operator(m_drag_idx ) ).y:=y - m_drag_dy;
|
|
|
|
result:=true;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
end
|
|
else
|
|
begin
|
|
result:=on_mouse_button_up(x ,y ,flags );
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
result:=false;
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_BUTTON_UP }
|
|
function mesh_ctrl.on_mouse_button_up(x ,y : double; flags : unsigned ) : boolean;
|
|
begin
|
|
result :=m_drag_idx >= 0;
|
|
m_drag_idx:=-1;
|
|
|
|
end;
|
|
|
|
{ NUM_VERTICES }
|
|
function mesh_ctrl.num_vertices : unsigned;
|
|
begin
|
|
result:=m_vertices.size;
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function mesh_ctrl.vertex(i : unsigned ) : mesh_point_ptr;
|
|
begin
|
|
result:=m_vertices.array_operator(i );
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function mesh_ctrl.vertex(x ,y : unsigned ) : mesh_point_ptr;
|
|
begin
|
|
result:=m_vertices.array_operator(y * m_rows + x );
|
|
|
|
end;
|
|
|
|
{ NUM_TRIANGLES }
|
|
function mesh_ctrl.num_triangles : unsigned;
|
|
begin
|
|
result:=m_triangles.size;
|
|
|
|
end;
|
|
|
|
{ TRIANGLE }
|
|
function mesh_ctrl.triangle(i : unsigned ) : mesh_triangle_ptr;
|
|
begin
|
|
result:=m_triangles.array_operator(i );
|
|
|
|
end;
|
|
|
|
{ NUM_EDGES }
|
|
function mesh_ctrl.num_edges : unsigned;
|
|
begin
|
|
result:=m_edges.size;
|
|
|
|
end;
|
|
|
|
{ EDGE }
|
|
function mesh_ctrl.edge(i : unsigned ) : mesh_edge_ptr;
|
|
begin
|
|
result:=m_edges.array_operator(i );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor styles_gouraud.Construct(mesh : mesh_ctrl_ptr; gamma : gamma_ptr );
|
|
var
|
|
i : unsigned;
|
|
t : mesh_triangle_ptr;
|
|
|
|
p1 ,p2 ,p3 : mesh_point_ptr;
|
|
c1 ,c2 ,c3 : aggclr;
|
|
|
|
gouraud : span_gouraud_rgba;
|
|
|
|
begin
|
|
m_triangles.Construct(sizeof(span_gouraud_rgba ) );
|
|
m_rgba.ConstrInt (0 ,0 ,0 ,0 );
|
|
|
|
i:=0;
|
|
|
|
while i < mesh.num_triangles do
|
|
begin
|
|
t :=mesh.triangle(i );
|
|
p1:=mesh.vertex (t.p1 );
|
|
p2:=mesh.vertex (t.p2 );
|
|
p3:=mesh.vertex (t.p3 );
|
|
|
|
c1.Construct(@p1.color );
|
|
c2.Construct(@p2.color );
|
|
c3.Construct(@p3.color );
|
|
|
|
c1.apply_gamma_dir(gamma );
|
|
c2.apply_gamma_dir(gamma );
|
|
c2.apply_gamma_dir(gamma );
|
|
|
|
gouraud.Construct_(
|
|
@c1 ,@c2 ,@c3 ,
|
|
p1.x ,p1.y ,
|
|
p2.x ,p2.y ,
|
|
p3.x ,p3.y );
|
|
|
|
gouraud.prepare_;
|
|
m_triangles.add(@gouraud );
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor styles_gouraud.Destruct;
|
|
begin
|
|
m_triangles.Destruct;
|
|
|
|
end;
|
|
|
|
{ IS_SOLID }
|
|
function styles_gouraud.is_solid(style : unsigned ) : boolean;
|
|
begin
|
|
result:=false;
|
|
|
|
end;
|
|
|
|
{ COLOR }
|
|
function styles_gouraud.color(style : unsigned ) : aggclr_ptr;
|
|
begin
|
|
result:=@m_rgba;
|
|
|
|
end;
|
|
|
|
{ GENERATE_SPAN }
|
|
procedure styles_gouraud.generate_span(span : aggclr_ptr; x ,y : int; len ,style : unsigned );
|
|
begin
|
|
span_gouraud_rgba_ptr(
|
|
m_triangles.array_operator(style ) ).generate_(span ,x ,y ,len );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor the_application.Construct;
|
|
begin
|
|
inherited Construct(format_ ,flip_y_ );
|
|
|
|
m_mesh.Construct;
|
|
m_gamma.Construct_;
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor the_application.Destruct;
|
|
begin
|
|
inherited Destruct;
|
|
|
|
m_mesh.Destruct;
|
|
m_gamma.Destruct;
|
|
|
|
// m_gamma.gamma_(2.0 );
|
|
|
|
end;
|
|
|
|
{ ON_INIT }
|
|
procedure the_application.on_init;
|
|
begin
|
|
m_mesh.generate(20 ,20 ,17 ,17 ,40 ,40 );
|
|
|
|
end;
|
|
|
|
{ ON_DRAW }
|
|
procedure the_application.on_draw;
|
|
var
|
|
pf : pixel_formats;
|
|
|
|
rgba : aggclr;
|
|
|
|
ren_base : renderer_base;
|
|
|
|
ren : renderer_scanline_aa_solid;
|
|
ras : rasterizer_scanline_aa;
|
|
|
|
sl : scanline_u8;
|
|
sl_bin : scanline_bin;
|
|
|
|
rasc : rasterizer_compound_aa_int;
|
|
alloc : span_allocator;
|
|
|
|
styles : styles_gouraud;
|
|
|
|
i : unsigned;
|
|
e : mesh_edge_ptr;
|
|
|
|
p1 ,p2 : mesh_point_ptr;
|
|
|
|
tm : double;
|
|
buf : array[0..255 ] of char;
|
|
|
|
t : gsv_text;
|
|
pt : conv_stroke_math;
|
|
|
|
begin
|
|
// Initialize structures
|
|
pixfmt_bgra32_pre(pf ,rbuf_window );
|
|
|
|
ren_base.Construct(@pf );
|
|
|
|
rgba.ConstrInt(0 ,0 ,0 );
|
|
ren_base.clear(@rgba );
|
|
ren.Construct (@ren_base );
|
|
|
|
ras.Construct;
|
|
sl.Construct;
|
|
sl_bin.Construct;
|
|
|
|
rasc.Construct;
|
|
alloc.Construct;
|
|
|
|
styles.Construct(@m_mesh ,@m_gamma );
|
|
|
|
start_timer;
|
|
rasc.reset;
|
|
|
|
//rasc.clip_box(40 ,40 ,_width - 40 ,_height - 40 );
|
|
|
|
i:=0;
|
|
|
|
while i < m_mesh.num_edges do
|
|
begin
|
|
e :=m_mesh.edge (i );
|
|
p1:=m_mesh.vertex(e.p1 );
|
|
p2:=m_mesh.vertex(e.p2 );
|
|
|
|
rasc.styles (e.tl ,e.tr );
|
|
rasc.move_to_d(p1.x ,p1.y );
|
|
rasc.line_to_d(p2.x ,p2.y );
|
|
|
|
inc(i );
|
|
|
|
end;
|
|
|
|
render_scanlines_compound(@rasc ,@sl ,@sl_bin ,@ren_base ,@alloc ,@styles );
|
|
|
|
// Info
|
|
tm:=elapsed_time;
|
|
|
|
t.Construct;
|
|
t.size_(10.0 );
|
|
|
|
pt.Construct (@t );
|
|
pt.width_ (1.5 );
|
|
pt.line_cap_ (round_cap );
|
|
pt.line_join_(round_join );
|
|
|
|
sprintf(@buf[0 ] ,'%3.2f ms, ' ,tm );
|
|
sprintf(@buf[StrLen(@buf ) ] ,'%d triangles, ' ,m_mesh.num_triangles );
|
|
sprintf(@buf[StrLen(@buf ) ] ,'%.0f tri/sec' ,m_mesh.num_triangles / tm * 1000.0 );
|
|
|
|
t.start_point_(10.0 ,10.0 );
|
|
t.text_ (@buf[0 ] );
|
|
|
|
ras.add_path (@pt );
|
|
rgba.ConstrDbl(1 ,1 ,1 );
|
|
|
|
render_scanlines_aa_solid(@ras ,@sl ,@ren_base ,@rgba );
|
|
|
|
if m_gamma._gamma <> 1.0 then
|
|
pf.apply_gamma_inv(@m_gamma ,bgra_order );
|
|
|
|
// Free AGG resources
|
|
ras.Destruct;
|
|
sl.Destruct;
|
|
sl_bin.Destruct;
|
|
|
|
rasc.Destruct;
|
|
alloc.Destruct;
|
|
|
|
styles.Destruct;
|
|
|
|
t.Destruct;
|
|
pt.Destruct;
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_MOVE }
|
|
procedure the_application.on_mouse_move;
|
|
begin
|
|
if m_mesh.on_mouse_move(x ,y ,flags ) then
|
|
force_redraw;
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_BUTTON_DOWN }
|
|
procedure the_application.on_mouse_button_down;
|
|
begin
|
|
if m_mesh.on_mouse_button_down(x ,y ,flags ) then
|
|
force_redraw;
|
|
|
|
end;
|
|
|
|
{ ON_MOUSE_BUTTON_UP }
|
|
procedure the_application.on_mouse_button_up;
|
|
begin
|
|
if m_mesh.on_mouse_button_up(x ,y ,flags ) then
|
|
force_redraw;
|
|
|
|
end;
|
|
|
|
{ ON_KEY }
|
|
procedure the_application.on_key;
|
|
begin
|
|
if key = key_f1 then
|
|
message_(
|
|
'Yet another example that demonstrates the power of compound shape rasterization. '#13 +
|
|
'Here we create a mesh of triangles and render them in one pass with multiple Gouraud '#13 +
|
|
'shaders (span_gouraud_rgba). The example demonstrates perfect Anti-Aliasing '#13 +
|
|
'and perfect triangle stitching (seamless edges) at the same time.'#13#13 +
|
|
'How to play with:'#13#13 +
|
|
'You can modify the points of the mesh by left mouse click and drag.' );
|
|
|
|
end;
|
|
|
|
{ ON_IDLE }
|
|
procedure the_application.on_idle;
|
|
begin
|
|
m_mesh.randomize_points(1.0 );
|
|
m_mesh.rotate_colors;
|
|
force_redraw;
|
|
|
|
end;
|
|
|
|
{ ON_CTRL_CHANGE }
|
|
procedure the_application.on_ctrl_change;
|
|
begin
|
|
end;
|
|
|
|
VAR
|
|
app : the_application;
|
|
|
|
BEGIN
|
|
app.Construct(pix_format_bgra32 ,flip_y );
|
|
app.caption_ ('AGG Example. (F1-Help)' );
|
|
|
|
if app.init(400 ,400 ,0 ) then
|
|
begin
|
|
app.wait_mode_(false );
|
|
app.run;
|
|
|
|
end;
|
|
|
|
app.Destruct;
|
|
|
|
END. |