Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Gradient line

This thread is locked; no one can reply to it. rss feed Print
Gradient line
ngiacomelli
Member #5,114
October 2004

I'm looking to render a line with a gradient from one colour to the other. I'm looking to use vanilla Allegro. I assume the best way would be to use do_line and calculate the colour value each iteration but I'm not so sure from there.

Anyone have any nice solutions?

kentl
Member #2,905
November 2002

Bresenhams's line drawing algorithm where you paint each pixel yourself in the gradient colors.

Sirocco
Member #88
April 2000
avatar

I've done it before using do_line, then stepping through the supplied coords and painting them accordingly. That's about as "Allegro friendly" as you can get.

Makes for some very nice effects.

-->
Graphic file formats used to fascinate me, but now I find them rather satanic.

Mae Mutts
Member #3,766
August 2003
avatar

This is how I did it. Looks fine.

1Notes: Color is a typedef of int
2 : GradientType indicates a horizontal or vertical gradient
3void fillGradient( BITMAP * bmp, int x1, int y1, int x2, int y2, Color startColor, Color endColor, GradientType direction)
4{
5 int numOfRedDivisions = getr( startColor ) - getr( endColor );
6 int numOfGreenDivisions = getg( startColor ) - getg( endColor );
7 int numOfBlueDivisions = getb( startColor ) - getb( endColor );
8
9 int divisions = 0;
10 switch( direction )
11 {
12 case HORIZONTAL_GRADIENT: divisions = x2-x1 ; break;
13 case VERTICAL_GRADIENT: divisions = y2-y1 ; break;
14 }
15
16 for(int i = 0; i < divisions; i++ )
17 {
18 int r = getr( startColor ) - (int)floor( i * numOfRedDivisions / divisions );
19 int g = getg( startColor ) - (int)floor( i * numOfGreenDivisions / divisions );
20 int b = getb( startColor ) - (int)floor( i * numOfBlueDivisions / divisions );
21
22
23 switch( direction )
24 {
25 case HORIZONTAL_GRADIENT: drawLine( bmp, x1+i, y1, x1+i, y2, makecol(r, g, b) ); break;
26 case VERTICAL_GRADIENT: drawLine( bmp, x1, y1+i, x2, y1+i, makecol(r, g, b) ); break;
27 }
28 }
29}
30 
31void drawLine( BITMAP * bmp, int x1, int y1, int x2, int y2, Color color)
32{
33 if( x1 == x2 )
34 vline( bmp, x1, y1, y2, color );
35 else
36 line( bmp, x1, y1, x2, y2, color );
37}

Johan Halmén
Member #1,550
September 2001

http://edu.loviisa.fi/~jhalmen/projects/mapgen/spectrline.gif
A line drawn using a class of mine
Basicly it's just my own version of do_line(), without a callback. You initiate an object with a start coordinate and an end coordinate or a start coordinate and a direction. Then you call a step function, which updates members x and y, which you can read.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

Neil Walker
Member #210
April 2000
avatar

I'm still waiting for the OpenLayer plug ;)

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Peter Hanratty
Member #7,191
May 2006

Greetings,

Heres a definable gradient class I did in Delphi a couple of years ago (you shouldnt have any problem understanding it since its not too different from C++). It lets you add points at a given position and define the colours.

------------------------------------------------------

1unit ColGrad;
2 
3interface
4 
5Uses Graphics;
6 
7Type
8 TColArray = Record
9 Bytes : Array [0..3] Of Byte;
10 End;
11 
12 TGradientPoint = Class (TObject)
13 Protected
14 IColour : TColor;
15 IPosition : Single;
16 INext : TGradientPoint;
17 
18 Procedure ISetPosition (Pos : Single);
19 
20 Public
21 Constructor Create; Overload; Virtual;
22 Constructor Create (Col : TColor; Pos : Single); Overload; Virtual;
23 Destructor Destroy; Override;
24 
25 Property Colour : TColor Read IColour Write IColour;
26 Property Position : Single Read IPosition Write ISetPosition;
27 Property Next : TGradientPoint Read INext Write INext;
28 
29 End;
30 
31 TGradientPoints = Class (TObject)
32 Protected
33 IPoints : TGradientPoint;
34 ICount : LongInt;
35 
36 Function IGetPoint (PointIndex : LongInt) : TGradientPoint;
37 
38 Public
39 Constructor Create; Virtual;
40 Destructor Destroy; Override;
41 
42 Property Count : LongInt Read ICount;
43 Property Points [PointIndex : LongInt] : TGradientPoint Read IGetPoint; Default;
44 
45 Procedure Add (NewPoint : TGradientPoint); Virtual;
46 Procedure Delete (Point : TGradientPoint); Virtual;
47 Procedure Clear; Virtual;
48 
49 End;
50 
51 TColourGradient = Class (TObject)
52 Protected
53 IHighColour, ILowColour : TColor;
54 IPoints : TGradientPoints;
55 
56 Public
57 Constructor Create; Overload; Virtual;
58 Constructor Create (HiCol, LoCol : TColor); Overload; Virtual;
59 Destructor Destroy; Override;
60 
61 Property HighColour : TColor Read IHighColour Write IHighColour;
62 Property LowColour : TColor Read ILowColour Write ILowColour;
63 Property Points : TGradientPoints Read IPoints;
64 
65 Function ColourAtPosition (Pos : Single) : TColor; Virtual;
66 Procedure Copy (ToGrad : TColourGradient); Virtual;
67 
68 End;
69 
70implementation
71 
72Procedure TGradientPoint.ISetPosition (Pos : Single);
73Begin
74 If Pos < 0 Then
75 IPosition := 0
76 Else
77 If Pos > 1 Then
78 IPosition := 1
79 Else
80 IPosition := Pos;
81End;
82 
83Constructor TGradientPoint.Create;
84Begin
85 Inherited Create;
86 IColour := clGray;
87 IPosition := 0.5;
88 INext := NIL;
89End;
90 
91Constructor TGradientPoint.Create (Col : TColor; Pos : Single);
92Begin
93 Inherited Create;
94 IColour := Col;
95 IPosition := Pos;
96 INext := NIL;
97End;
98 
99Destructor TGradientPoint.Destroy;
100Begin
101 Inherited;
102End;
103 
104Function TGradientPoints.IGetPoint (PointIndex : LongInt) : TGradientPoint;
105Var
106 Count : LongInt;
107 Current : TGradientPoint;
108Begin
109 If PointIndex >= ICount Then
110 Result := NIL
111 Else
112 Begin
113 Current := IPoints;
114 For Count := 1 To PointIndex Do
115 Current := Current.Next;
116 Result := Current;
117 End;
118End;
119 
120Constructor TGradientPoints.Create;
121Begin
122 Inherited Create;
123 IPoints := NIL;
124 ICount := 0;
125End;
126 
127Destructor TGradientPoints.Destroy;
128Begin
129 Self.Clear;
130 Inherited;
131End;
132 
133Procedure TGradientPoints.Add (NewPoint : TGradientPoint);
134Var
135 Current : TGradientPoint;
136Begin
137 If IPoints = NIL Then
138 IPoints := NewPoint
139 Else
140 Begin
141 Current := IPoints;
142 While Current.Next <> NIL Do
143 Current := Current.Next;
144 Current.Next := NewPoint;
145 End;
146 ICount := ICount + 1;
147End;
148 
149Procedure TGradientPoints.Delete (Point : TGradientPoint);
150Var
151 Current, Previous : TGradientPoint;
152 Found : Boolean;
153Begin
154 If IPoints = Point Then
155 Begin
156 Previous := IPoints;
157 IPoints := IPoints.Next;
158 Previous.Free;
159 ICount := ICount - 1;
160 End
161 Else
162 Begin
163 Current := IPoints;
164 Found := False;
165 While (Current.Next <> NIL) And (Not (Found)) Do
166 Begin
167 If Current.Next = Point Then
168 Begin
169 Previous := Current.Next;
170 Current.Next := Current.Next.Next;
171 Previous.Free;
172 Found := True;
173 ICount := ICount - 1;
174 End
175 Else
176 Current := Current.Next;
177 End;
178 End;
179End;
180 
181Procedure TGradientPoints.Clear;
182Var
183 Current, Previous : TGradientPoint;
184Begin
185 Current := IPoints;
186 While Current <> NIL Do
187 Begin
188 Previous := Current;
189 Current := Current.Next;
190 Previous.Free;
191 End;
192 ICount := 0;
193 IPoints := NIL;
194End;
195 
196Constructor TColourGradient.Create;
197Begin
198 Inherited Create;
199 ILowColour := clGray;
200 IHighColour := clGray;
201 IPoints := TGradientPoints.Create;
202End;
203 
204Constructor TColourGradient.Create (HiCol, LoCol : TColor);
205Begin
206 Inherited Create;
207 IHighColour := HiCol;
208 ILowColour := LoCol;
209 IPoints := TGradientPoints.Create;
210End;
211 
212Destructor TColourGradient.Destroy;
213Begin
214 IPoints.Free;
215 Inherited;
216End;
217 
218Function TColourGradient.ColourAtPosition (Pos : Single) : TColor;
219Var
220 CurrentPoint : TGradientPoint;
221 HiPoint, LoPoint, MidPoint : Single;
222 HiCol, LoCol, ResCol : TColArray;
223 BytePos : Byte;
224Begin
225 If Pos < 0 Then
226 Result := IHighColour
227 Else
228 If Pos > 1 Then
229 Result := ILowColour
230 Else
231 Begin
232 HiPoint := 0;
233 LoPoint := 1;
234 Move (IHighColour, HiCol, 4);
235 Move (ILowColour, LoCol, 4);
236 
237 CurrentPoint := IPoints [0];
238 While CurrentPoint <> NIL Do
239 Begin
240 If (CurrentPoint.Position <= Pos) And
241 (CurrentPoint.Position >= HiPoint) Then
242 Begin
243 HiPoint := CurrentPoint.Position;
244 Move (CurrentPoint.Colour, HiCol, 4);
245 End;
246 CurrentPoint := CurrentPoint.Next;
247 End;
248 
249 CurrentPoint := IPoints [0];
250 While CurrentPoint <> NIL Do
251 Begin
252 If (CurrentPoint.Position >= Pos) And
253 (CurrentPoint.Position <= LoPoint) Then
254 Begin
255 LoPoint := CurrentPoint.Position;
256 Move (CurrentPoint.Colour, LoCol, 4);
257 End;
258 CurrentPoint := CurrentPoint.Next;
259 End;
260 
261 If HiPoint = LoPoint Then
262 ResCol := LoCol
263 Else
264 Begin
265 MidPoint := (Pos - HiPoint) / (LoPoint - HiPoint);
266 For BytePos := 0 To 3 Do
267 Begin
268 HiPoint := HiCol.Bytes [BytePos];
269 LoPoint := LoCol.Bytes [BytePos];
270 ResCol.Bytes [BytePos] := Round (HiPoint + ((LoPoint - HiPoint) * MidPoint));
271 End;
272 End;
273 
274 Move (ResCol, Result, 4);
275 End;
276End;
277 
278Procedure TColourGradient.Copy (ToGrad : TColourGradient);
279Var
280 Current : TGradientPoint;
281Begin
282 ToGrad.LowColour := ILowColour;
283 ToGrad.HighColour := IHighColour;
284 ToGrad.Points.Clear;
285 Current := IPoints [0];
286 While Current <> NIL Do
287 Begin
288 ToGrad.Points.Add (TGradientPoint.Create (Current.Colour, Current.Position));
289 Current := Current.Next;
290 End;
291End;
292 
293end.

And Here it is in action :-

{"name":"recol2.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/9\/098e1eb81a1df741ab60947b023d8cbc.jpg","w":628,"h":489,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/9\/098e1eb81a1df741ab60947b023d8cbc"}recol2.jpg

Go to: