1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 #ifndef AGG_SPAN_GOURAUD_INCLUDED
17 #define AGG_SPAN_GOURAUD_INCLUDED
19 #include "agg_basics.h"
21 #include "agg_span_generator.h"
26 //============================================================span_gouraud
27 template<class ColorT
, class Allocator
>
28 class span_gouraud
: public span_generator
<ColorT
, Allocator
>
31 typedef ColorT color_type
;
32 typedef Allocator alloc_type
;
41 //--------------------------------------------------------------------
42 span_gouraud(alloc_type
& alloc
) :
43 span_generator
<color_type
, alloc_type
>(alloc
),
46 m_cmd
[0] = path_cmd_stop
;
49 //--------------------------------------------------------------------
50 span_gouraud(alloc_type
& alloc
,
58 span_generator
<color_type
, alloc_type
>(alloc
)
61 triangle(x1
, y1
, x2
, y2
, x3
, y3
, d
);
64 //--------------------------------------------------------------------
65 void colors(ColorT c1
, ColorT c2
, ColorT c3
)
67 m_coord
[0].color
= c1
;
68 m_coord
[1].color
= c2
;
69 m_coord
[2].color
= c3
;
72 //--------------------------------------------------------------------
73 // Sets the triangle and dilates it if needed.
74 // The trick here is to calculate beveled joins in the vertices of the
75 // triangle and render it as a 6-vertex polygon.
76 // It's necessary to achieve numerical stability.
77 // However, the coordinates to interpolate colors are calculated
78 // as miter joins (calc_intersection).
79 void triangle(double x1
, double y1
,
84 m_coord
[0].x
= m_x
[0] = x1
;
85 m_coord
[0].y
= m_y
[0] = y1
;
86 m_coord
[1].x
= m_x
[1] = x2
;
87 m_coord
[1].y
= m_y
[1] = y2
;
88 m_coord
[2].x
= m_x
[2] = x3
;
89 m_coord
[2].y
= m_y
[2] = y3
;
90 m_cmd
[0] = path_cmd_move_to
;
91 m_cmd
[1] = path_cmd_line_to
;
92 m_cmd
[2] = path_cmd_line_to
;
93 m_cmd
[3] = path_cmd_stop
;
97 dilate_triangle(m_coord
[0].x
, m_coord
[0].y
,
98 m_coord
[1].x
, m_coord
[1].y
,
99 m_coord
[2].x
, m_coord
[2].y
,
102 calc_intersection(m_x
[4], m_y
[4], m_x
[5], m_y
[5],
103 m_x
[0], m_y
[0], m_x
[1], m_y
[1],
104 &m_coord
[0].x
, &m_coord
[0].y
);
106 calc_intersection(m_x
[0], m_y
[0], m_x
[1], m_y
[1],
107 m_x
[2], m_y
[2], m_x
[3], m_y
[3],
108 &m_coord
[1].x
, &m_coord
[1].y
);
110 calc_intersection(m_x
[2], m_y
[2], m_x
[3], m_y
[3],
111 m_x
[4], m_y
[4], m_x
[5], m_y
[5],
112 &m_coord
[2].x
, &m_coord
[2].y
);
113 m_cmd
[3] = path_cmd_line_to
;
114 m_cmd
[4] = path_cmd_line_to
;
115 m_cmd
[5] = path_cmd_line_to
;
116 m_cmd
[6] = path_cmd_stop
;
120 //--------------------------------------------------------------------
121 // Vertex Source Interface to feed the coordinates to the rasterizer
122 void rewind(unsigned)
127 //--------------------------------------------------------------------
128 unsigned vertex(double* x
, double* y
)
132 return m_cmd
[m_vertex
++];
138 //--------------------------------------------------------------------
139 void arrange_vertices(coord_type
* coord
) const
141 coord
[0] = m_coord
[0];
142 coord
[1] = m_coord
[1];
143 coord
[2] = m_coord
[2];
145 if(m_coord
[0].y
> m_coord
[2].y
)
147 coord
[0] = m_coord
[2];
148 coord
[2] = m_coord
[0];
152 if(coord
[0].y
> coord
[1].y
)
159 if(coord
[1].y
> coord
[2].y
)
169 //--------------------------------------------------------------------
170 coord_type m_coord
[3];