mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-07-18 06:06:00 +02:00
236 lines
5.8 KiB
ObjectPascal
236 lines
5.8 KiB
ObjectPascal
//----------------------------------------------------------------------------
|
|
// Anti-Grain Geometry - Version 2.4 (Public License)
|
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
|
//
|
|
// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
|
|
// Pascal Port By: Milan Marusinec alias Milano
|
|
// milan@marusinec.sk
|
|
// http://www.aggpas.org
|
|
// Copyright (c) 2005-2006
|
|
//
|
|
// Permission to copy, use, modify, sell and distribute this software
|
|
// is granted provided this copyright notice appears in all copies.
|
|
// This software is provided "as is" without express or implied
|
|
// warranty, and with no claim as to its suitability for any purpose.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
// Contact: mcseem@antigrain.com
|
|
// mcseemagg@yahoo.com
|
|
// http://www.antigrain.com
|
|
//
|
|
// [Pascal Port History] -----------------------------------------------------
|
|
//
|
|
// 23.06.2006-Milano: ptrcomp adjustments
|
|
// 27.01.2006-Milano: Unit port establishment
|
|
//
|
|
{ agg_span_gouraud.pas }
|
|
unit
|
|
agg_span_gouraud ;
|
|
|
|
INTERFACE
|
|
|
|
{$I agg_mode.inc }
|
|
|
|
uses
|
|
agg_basics ,
|
|
agg_math ,
|
|
agg_span_allocator ,
|
|
agg_span_generator ,
|
|
agg_color ,
|
|
agg_vertex_source ;
|
|
|
|
{ TYPES DEFINITION }
|
|
type
|
|
coord_type_ptr = ^coord_type;
|
|
coord_type = record
|
|
x ,y : double;
|
|
color : aggclr;
|
|
|
|
end;
|
|
|
|
span_gouraud = object(span_generator )
|
|
m_coord : array[0..2 ] of coord_type;
|
|
m_x ,
|
|
m_y : array[0..7 ] of double;
|
|
m_cmd : array[0..7 ] of unsigned;
|
|
m_vertex : unsigned;
|
|
|
|
constructor Construct(alloc : span_allocator_ptr ); overload;
|
|
constructor Construct(
|
|
alloc : span_allocator_ptr;
|
|
c1 ,c2 ,c3 : aggclr_ptr;
|
|
x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,d : double ); overload;
|
|
|
|
procedure colors_ (c1 ,c2 ,c3 : aggclr_ptr );
|
|
procedure triangle(x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,d : double );
|
|
|
|
// Vertex Source Interface to feed the coordinates to the rasterizer
|
|
procedure rewind(path_id : unsigned ); virtual;
|
|
function vertex(x ,y : double_ptr ) : unsigned; virtual;
|
|
|
|
// Private
|
|
procedure arrange_vertices(coord : coord_type_ptr );
|
|
|
|
end;
|
|
|
|
{ GLOBAL PROCEDURES }
|
|
|
|
|
|
IMPLEMENTATION
|
|
{ LOCAL VARIABLES & CONSTANTS }
|
|
{ UNIT IMPLEMENTATION }
|
|
{ CONSTRUCT }
|
|
constructor span_gouraud.Construct(alloc : span_allocator_ptr );
|
|
begin
|
|
inherited Construct(alloc );
|
|
|
|
m_cmd[0 ]:=path_cmd_stop;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor span_gouraud.Construct(
|
|
alloc : span_allocator_ptr;
|
|
c1 ,c2 ,c3 : aggclr_ptr;
|
|
x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,d : double );
|
|
begin
|
|
inherited Construct(alloc );
|
|
|
|
colors_ (c1 ,c2 ,c3 );
|
|
triangle(x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,d );
|
|
|
|
end;
|
|
|
|
{ COLORS_ }
|
|
procedure span_gouraud.colors_;
|
|
begin
|
|
m_coord[0 ].color:=c1^;
|
|
m_coord[1 ].color:=c2^;
|
|
m_coord[2 ].color:=c3^;
|
|
|
|
end;
|
|
|
|
{ TRIANGLE }
|
|
// Sets the triangle and dilates it if needed.
|
|
// The trick here is to calculate beveled joins in the vertices of the
|
|
// triangle and render it as a 6-vertex polygon.
|
|
// It's necessary to achieve numerical stability.
|
|
// However, the coordinates to interpolate colors are calculated
|
|
// as miter joins (calc_intersection).
|
|
procedure span_gouraud.triangle;
|
|
begin
|
|
m_coord[0 ].x:=x1;
|
|
m_x[0 ] :=x1;
|
|
m_coord[0 ].y:=y1;
|
|
m_y[0 ] :=y1;
|
|
m_coord[1 ].x:=x2;
|
|
m_x[1 ] :=x2;
|
|
m_coord[1 ].y:=y2;
|
|
m_y[1 ] :=y2;
|
|
m_coord[2 ].x:=x3;
|
|
m_x[2 ] :=x3;
|
|
m_coord[2 ].y:=y3;
|
|
m_y[2 ] :=y3;
|
|
|
|
m_cmd[0 ]:=path_cmd_move_to;
|
|
m_cmd[1 ]:=path_cmd_line_to;
|
|
m_cmd[2 ]:=path_cmd_line_to;
|
|
m_cmd[3 ]:=path_cmd_stop;
|
|
|
|
if d <> 0.0 then
|
|
begin
|
|
dilate_triangle(
|
|
m_coord[0 ].x ,m_coord[0 ].y ,
|
|
m_coord[1 ].x ,m_coord[1 ].y ,
|
|
m_coord[2 ].x ,m_coord[2 ].y ,
|
|
@m_x ,@m_y ,d );
|
|
|
|
calc_intersection(
|
|
m_x[4 ] ,m_y[4 ] ,m_x[5 ] ,m_y[5 ] ,
|
|
m_x[0 ] ,m_y[0 ] ,m_x[1 ] ,m_y[1 ] ,
|
|
@m_coord[0 ].x ,@m_coord[0 ].y );
|
|
|
|
calc_intersection(
|
|
m_x[0 ] ,m_y[0 ] ,m_x[1 ] ,m_y[1 ] ,
|
|
m_x[2 ] ,m_y[2 ] ,m_x[3 ] ,m_y[3 ] ,
|
|
@m_coord[1 ].x ,@m_coord[1 ].y );
|
|
|
|
calc_intersection(
|
|
m_x[2 ] ,m_y[2 ] ,m_x[3 ] ,m_y[3 ] ,
|
|
m_x[4 ] ,m_y[4 ] ,m_x[5 ] ,m_y[5 ] ,
|
|
@m_coord[2 ].x ,@m_coord[2 ].y );
|
|
|
|
m_cmd[3 ]:=path_cmd_line_to;
|
|
m_cmd[4 ]:=path_cmd_line_to;
|
|
m_cmd[5 ]:=path_cmd_line_to;
|
|
m_cmd[6 ]:=path_cmd_stop;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
{ REWIND }
|
|
procedure span_gouraud.rewind;
|
|
begin
|
|
m_vertex:=0;
|
|
|
|
end;
|
|
|
|
{ VERTEX }
|
|
function span_gouraud.vertex;
|
|
begin
|
|
x^:=m_x[m_vertex ];
|
|
y^:=m_y[m_vertex ];
|
|
|
|
result:=m_cmd[m_vertex ];
|
|
|
|
inc(m_vertex );
|
|
|
|
end;
|
|
|
|
{ ARRANGE_VERTICES }
|
|
procedure span_gouraud.arrange_vertices;
|
|
var
|
|
tmp : coord_type;
|
|
|
|
begin
|
|
coord_type_ptr(ptrcomp(coord ) + 0 * sizeof(coord_type ) )^:=m_coord[0 ];
|
|
coord_type_ptr(ptrcomp(coord ) + 1 * sizeof(coord_type ) )^:=m_coord[1 ];
|
|
coord_type_ptr(ptrcomp(coord ) + 2 * sizeof(coord_type ) )^:=m_coord[2 ];
|
|
|
|
if m_coord[0 ].y > m_coord[2 ].y then
|
|
begin
|
|
coord_type_ptr(ptrcomp(coord ) + 0 * sizeof(coord_type ) )^:=m_coord[2 ];
|
|
coord_type_ptr(ptrcomp(coord ) + 2 * sizeof(coord_type ) )^:=m_coord[0 ];
|
|
|
|
end;
|
|
|
|
if coord_type_ptr(ptrcomp(coord ) + 0 * sizeof(coord_type ) ).y >
|
|
coord_type_ptr(ptrcomp(coord ) + 1 * sizeof(coord_type ) ).y then
|
|
begin
|
|
tmp:=coord_type_ptr(ptrcomp(coord ) + 1 * sizeof(coord_type ) )^;
|
|
|
|
coord_type_ptr(ptrcomp(coord ) + 1 * sizeof(coord_type ) )^:=
|
|
coord_type_ptr(ptrcomp(coord ) + 0 * sizeof(coord_type ) )^;
|
|
|
|
coord_type_ptr(ptrcomp(coord ) + 0 * sizeof(coord_type ) )^:=tmp;
|
|
|
|
end;
|
|
|
|
if coord_type_ptr(ptrcomp(coord ) + 1 * sizeof(coord_type ) ).y >
|
|
coord_type_ptr(ptrcomp(coord ) + 2 * sizeof(coord_type ) ).y then
|
|
begin
|
|
tmp:=coord_type_ptr(ptrcomp(coord ) + 2 * sizeof(coord_type ) )^;
|
|
|
|
coord_type_ptr(ptrcomp(coord ) + 2 * sizeof(coord_type ) )^:=
|
|
coord_type_ptr(ptrcomp(coord ) + 1 * sizeof(coord_type ) )^;
|
|
|
|
coord_type_ptr(ptrcomp(coord ) + 1 * sizeof(coord_type ) )^:=tmp;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
END.
|
|
|