Difference between revisions of "BGRABitmap tutorial 11"
m (→Use a custom scanner: rotation later) |
m (Text replace - "delphi>" to "syntaxhighlight>") |
||
Line 12: | Line 12: | ||
Here is an affine transformation applied on a gradient like we did with textures : | Here is an affine transformation applied on a gradient like we did with textures : | ||
− | < | + | <syntaxhighlight>uses BGRAGradientScanner, BGRATransform; |
procedure TForm1.FormPaint(Sender: TObject); | procedure TForm1.FormPaint(Sender: TObject); | ||
Line 35: | Line 35: | ||
image.Draw(Canvas,0,0,True); | image.Draw(Canvas,0,0,True); | ||
image.free; | image.free; | ||
− | end; </ | + | end; </syntaxhighlight> |
The base gradient is radial, centered at origin (0,0), of radius 1. | The base gradient is radial, centered at origin (0,0), of radius 1. | ||
Line 55: | Line 55: | ||
We can add another transformation to it like this : | We can add another transformation to it like this : | ||
− | < | + | <syntaxhighlight>var image: TBGRABitmap; |
grad: TBGRAGradientScanner; | grad: TBGRAGradientScanner; | ||
affine: TBGRAAffineScannerTransform; | affine: TBGRAAffineScannerTransform; | ||
Line 78: | Line 78: | ||
image.Draw(Canvas,0,0,True); | image.Draw(Canvas,0,0,True); | ||
image.free; | image.free; | ||
− | end; </ | + | end; </syntaxhighlight> |
Here, we simply create a twirl transformation applied to the previous one, and fill with it. | Here, we simply create a twirl transformation applied to the previous one, and fill with it. | ||
Line 91: | Line 91: | ||
We may want to create our own gradient generator. Here is for example a multiply gradient : | We may want to create our own gradient generator. Here is for example a multiply gradient : | ||
− | < | + | <syntaxhighlight>type |
{ TBGRAMultiplyScanner } | { TBGRAMultiplyScanner } | ||
Line 112: | Line 112: | ||
mul := cycle512(round(x*y)); | mul := cycle512(round(x*y)); | ||
result := BGRA(mul,mul,mul,255); | result := BGRA(mul,mul,mul,255); | ||
− | end; </ | + | end; </syntaxhighlight> |
It is derived from TBGRACustomScanner to be used for filling, and the ScanAt function is overridden. It computes the product of both coordinates and make a cycle of 512 with it (from 0 to 255 and then from 255 down to 0). | It is derived from TBGRACustomScanner to be used for filling, and the ScanAt function is overridden. It computes the product of both coordinates and make a cycle of 512 with it (from 0 to 255 and then from 255 down to 0). | ||
Let's draw it on the screen with a simple affine transformation : | Let's draw it on the screen with a simple affine transformation : | ||
− | < | + | <syntaxhighlight>var image: TBGRABitmap; |
grad: TBGRAMultiplyScanner; | grad: TBGRAMultiplyScanner; | ||
affine: TBGRAAffineScannerTransform; | affine: TBGRAAffineScannerTransform; | ||
Line 133: | Line 133: | ||
image.Draw(Canvas,0,0,True); | image.Draw(Canvas,0,0,True); | ||
image.free; | image.free; | ||
− | end; </ | + | end; </syntaxhighlight> |
=== Run the program === | === Run the program === | ||
Line 144: | Line 144: | ||
Add some colors by modifying the ScanAt procedure of the multiply gradient : | Add some colors by modifying the ScanAt procedure of the multiply gradient : | ||
− | < | + | <syntaxhighlight>var |
mul: integer; | mul: integer; | ||
begin | begin | ||
mul := round(x*y); | mul := round(x*y); | ||
result := BGRA(cycle512(round(x*10)),cycle512(mul),cycle512(round(y*10)),255); | result := BGRA(cycle512(round(x*10)),cycle512(mul),cycle512(round(y*10)),255); | ||
− | end; </ | + | end; </syntaxhighlight> |
The red and blue intensities are filled with a cycle of x and y positions. | The red and blue intensities are filled with a cycle of x and y positions. | ||
And add some rotation : | And add some rotation : | ||
− | < | + | <syntaxhighlight> affine := TBGRAAffineScannerTransform.Create(grad); |
affine.Scale(6,4); | affine.Scale(6,4); | ||
affine.RotateDeg(-30); | affine.RotateDeg(-30); | ||
− | affine.Translate(ClientWidth/2, ClientHeight/2); </ | + | affine.Translate(ClientWidth/2, ClientHeight/2); </syntaxhighlight> |
[[Image:BGRATutorial11d.png]] | [[Image:BGRATutorial11d.png]] |
Revision as of 14:52, 24 March 2012
│ Deutsch (de) │ English (en) │ español (es) │ français (fr) │
Home | Tutorial 1 | Tutorial 2 | Tutorial 3 | Tutorial 4 | Tutorial 5 | Tutorial 6 | Tutorial 7 | Tutorial 8 | Tutorial 9 | Tutorial 10 | Tutorial 11 | Tutorial 12 | Tutorial 13 | Tutorial 14 | Tutorial 15 | Tutorial 16 | Edit
This tutorial shows how to combine transformations.
Create a new project
Create a new project and add a reference to BGRABitmap, the same way as in the first tutorial.
Affine transformation of a radial gradient
Here is an affine transformation applied on a gradient like we did with textures :
uses BGRAGradientScanner, BGRATransform;
procedure TForm1.FormPaint(Sender: TObject);
var image: TBGRABitmap;
grad: TBGRAGradientScanner;
affine: TBGRAAffineScannerTransform;
begin
image := TBGRABitmap.Create(ClientWidth,ClientHeight, BGRABlack );
grad := TBGRAGradientScanner.Create(BGRA(0,0,255),BGRAWhite,gtRadial,PointF(0,0),PointF(1,0),True,True);
affine := TBGRAAffineScannerTransform.Create(grad);
affine.Scale(150,80);
affine.RotateDeg(-30);
affine.Translate(ClientWidth/2, ClientHeight/2);
image.Fill(affine);
affine.free;
grad.free;
image.Draw(Canvas,0,0,True);
image.free;
end;
The base gradient is radial, centered at origin (0,0), of radius 1.
The affine transformation does the following :
- stretch the gradient to a size of 150x80
- rotate 30 degrees in counterclockwise direction
- center it in the form
The Fill instruction draws the result into the image.
Run the program
You should obtain a blue and white ellipse gradient.
Combine with a twirl
We can add another transformation to it like this :
var image: TBGRABitmap;
grad: TBGRAGradientScanner;
affine: TBGRAAffineScannerTransform;
twirl: TBGRATwirlScanner;
begin
image := TBGRABitmap.Create(ClientWidth,ClientHeight, BGRABlack );
grad := TBGRAGradientScanner.Create(BGRA(0,0,255),BGRAWhite,gtRadial,PointF(0,0),PointF(1,0),True,True);
affine := TBGRAAffineScannerTransform.Create(grad);
affine.Scale(150,80);
affine.RotateDeg(-30);
affine.Translate(ClientWidth/2, ClientHeight/2);
twirl := TBGRATwirlScanner.Create(affine,Point(ClientWidth div 2, ClientHeight div 2),100);
image.Fill(twirl);
twirl.Free;
affine.free;
grad.free;
image.Draw(Canvas,0,0,True);
image.free;
end;
Here, we simply create a twirl transformation applied to the previous one, and fill with it.
Run the program
Now the center of the gradient is twirled.
Use a custom scanner
We may want to create our own gradient generator. Here is for example a multiply gradient :
type
{ TBGRAMultiplyScanner }
TBGRAMultiplyScanner = class(TBGRACustomScanner)
function ScanAt(X, Y: Single): TBGRAPixel; override;
end;
{ TBGRAMultiplyScanner }
function TBGRAMultiplyScanner.ScanAt(X, Y: Single): TBGRAPixel;
function cycle512(value: integer): integer; inline;
begin
result := value and 511;
if result >= 256 then result := 511-result;
end;
var
mul: integer;
begin
mul := cycle512(round(x*y));
result := BGRA(mul,mul,mul,255);
end;
It is derived from TBGRACustomScanner to be used for filling, and the ScanAt function is overridden. It computes the product of both coordinates and make a cycle of 512 with it (from 0 to 255 and then from 255 down to 0).
Let's draw it on the screen with a simple affine transformation :
var image: TBGRABitmap;
grad: TBGRAMultiplyScanner;
affine: TBGRAAffineScannerTransform;
begin
image := TBGRABitmap.Create(ClientWidth,ClientHeight, BGRABlack );
grad := TBGRAMultiplyScanner.Create;
affine := TBGRAAffineScannerTransform.Create(grad);
affine.Scale(6,4);
affine.Translate(ClientWidth/2, ClientHeight/2);
image.Fill(affine);
affine.free;
grad.free;
image.Draw(Canvas,0,0,True);
image.free;
end;
Run the program
It should look like this :
Make it beautiful
Add some colors by modifying the ScanAt procedure of the multiply gradient :
var
mul: integer;
begin
mul := round(x*y);
result := BGRA(cycle512(round(x*10)),cycle512(mul),cycle512(round(y*10)),255);
end;
The red and blue intensities are filled with a cycle of x and y positions.
And add some rotation :
affine := TBGRAAffineScannerTransform.Create(grad);
affine.Scale(6,4);
affine.RotateDeg(-30);
affine.Translate(ClientWidth/2, ClientHeight/2);
Previous tutorial (texture mapping) Next tutorial (text functions)