Recent

Author Topic: [LAMW] Playing with the Alpha channel for fun using the CanvasES2 library.😀  (Read 328 times)

José Hernández

  • Newbie
  • Posts: 5
Put one pixel via CanvasES2 like a pro (Part 2)

When I was analyzing how I could put a pixel using the CanvasES21GL library, the Alpha Channel variable used to display the texture caught my attention. I said to myself: If I'm going to be using the texturing technique to simulate a ScreenBuffer, I might as well play with the Alpha channel.

I really don't feel comfortable using black boxes, like this one, I really don't know how it does it. Maybe using the GPU or something else. I'm not sure. But it's there, whether I use it or not, I'm forced to set it anyway.

From my point of view, I could use it for some very specific things, and not abuse it. If I see that it is affecting performance, my first option to fix it would be to not use it and use other techniques.

In this example, I'm going to play with the Alpha channel in two ways:
1. Create a gradient from a Start color to a End color.
2. Draw a donut with 25% transparency.

Here is the code:
Code: Pascal  [Select][+][-]
  1. unit unit1;
  2.  
  3. {$mode delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  9.   cthreads,
  10.   {$ENDIF}{$ENDIF}
  11.   Classes, SysUtils, AndroidWidget,
  12.   Laz_And_GLESv2_Canvas, Laz_And_GLESv2_Canvas_h;
  13.  
  14. type
  15.  
  16.   { TAndroidModule1 }
  17.  
  18.   TAndroidModule1 = class(jForm)
  19.     CanvasES21: jCanvasES2;
  20.     procedure AndroidModule1JNIPrompt(Sender: TObject);
  21.     procedure CanvasES21GLCreate(Sender: TObject);
  22.     procedure CanvasES21GLDraw(Sender: TObject);
  23.   private
  24.     {private declarations}
  25.   public
  26.     {public declarations}
  27.     procedure DeployBuffer(B: PDWord; T: TxgElement; W, H: Integer);
  28.     procedure DrawTexture(T: TxgElement; A, x1, y1, x0, y0: Single);
  29.   end;
  30.   { TMyOwnPrimitives }
  31.     TMyOwnPrimitives = class
  32.   private
  33.     Data:            PDWord;
  34.     Len:             Integer;
  35.  
  36.     Alpha:           DWord;
  37.     Color:           DWord;
  38.     AlphaMater:      Single;
  39.     PencilColor:     DWord;
  40.     BackgroundColor: DWord;
  41.  
  42.     W,H,X:           Integer;
  43.     Texture:         TxgElement;
  44.   public
  45.     constructor Create; virtual;
  46.     procedure Update;  virtual;
  47.     procedure UpdateColor;  virtual;
  48.     procedure UpdateDimensions(Width, Height: Integer); virtual;
  49.     procedure SetTheBufferUp;
  50.     procedure SetPencilColor(NewColor: DWord);
  51.     procedure SetBackgroundColor(NewColor: Dword);
  52.     function  GetWidth:   Integer;
  53.     function  GetHeight:  Integer;
  54.     function  GetBuffer:  PDWord;
  55.     function  GetAlpha:   Single;
  56.     function  GetTexture: TxgElement;
  57.  
  58.     procedure MoveToInitialPoint;
  59.     procedure MoveTo(NewX, Newy: Integer);
  60.     procedure DrawHorizontal(Lenght: Integer);
  61.     procedure Clean;
  62.   end;
  63.  
  64.   { TChessBoard }
  65.  
  66.   TChessBoard = class(TMyOwnPrimitives)
  67.      private
  68.        TotalSquaresByWidth:      Integer;
  69.        TotalSquaresByHeight:     Integer;
  70.        LenghtOfSquareSide:       Integer;
  71.        DoubleSquareSize:         Integer;
  72.        Mask:                     Integer;
  73.        Remainder:                Integer;
  74.      public
  75.        constructor Create; override;
  76.        procedure Update; override;
  77.        procedure UpdateDimensions(Width, Height: Integer); override;
  78.        procedure SetSquareSize(SquareSize: Integer);
  79.        procedure DrawTwoSquareRows;
  80.        procedure DrawSquareRow;
  81.        procedure DrawLine; virtual;
  82.        procedure DrawTwoSquares;
  83.        procedure MoveToNextLine;
  84.        procedure WalkASquare;
  85.        procedure GoASquareBack;
  86.    end;
  87.  
  88.   { TGradiant }
  89.  
  90.   TGradiant = class(TChessBoard)
  91.      private
  92.        Gradiant:        DWord;
  93.        Numerator:       Integer;
  94.      public
  95.        constructor Create; override;
  96.        procedure Update; override;
  97.        procedure UpdateColor; override;
  98.        procedure DrawLine; override;
  99.        procedure CalculateGradiant;
  100.        procedure DecrementGradianteAndNumerator;
  101.    end;
  102.  
  103.   { TDonut }
  104.  
  105.   TDonut = class(TMyOwnPrimitives)
  106.     private
  107.       TheShorter, HoleRadius, DonutRadius: Integer;
  108.     public
  109.       constructor Create; override;
  110.       procedure Update; override;
  111.       procedure UpdateRadiusAndHole;
  112.       procedure SetBackGroundTransparent;
  113.       procedure SetPencilTransparent;
  114.       procedure MoveToTheCenter;
  115.       procedure DrawFilledCircle(Radius: Integer);
  116.       procedure WhichIsShorterBetweenHAndW;
  117.       procedure CirclePoints(Cx, Cy: Integer); Virtual;
  118.   end;
  119. var
  120.   AndroidModule1: TAndroidModule1;
  121.   Layers: Array[0..2] of TMyOwnPrimitives;
  122.  
  123. const
  124.    FullyOpaque          = $ff000000;
  125.    FullyTransparent     = $00000000;
  126.    PartiallyTransparent = $80000000;
  127.  
  128.    BlackColor   = $00000000;
  129.    WhiteColor   = $00bfbfbf;
  130.    GoldenBrown  = $001e5b89;
  131.    PrussianBlue = $00543500;
  132.    Olivine      = $0080c4b8;
  133.    PinkLavander = $00c1afdb;
  134.  
  135.    FULLY_OPAQUE          =  1.00;
  136.    PARTIALLY_TRANSPARENT =  0.25;
  137.    RightCorner           =  1.00;
  138.    LeftCorner            = -1.00;
  139.    TopCorner             =  1.00;
  140.    DownCorner            = -1.00;
  141.  
  142.    Square32x32pixels = 5;
  143.    Square16x16pixels = 4;
  144.    Square64x64pixels = 6;
  145.  
  146.    OneLevelOfTrransparency = $01000000;
  147.    DifferentLevelsOfTransparency = 255;
  148.  
  149.  
  150. implementation
  151.  
  152.  
  153. {$R *.lfm}
  154.  
  155.  
  156.  
  157. { TAndroidModule1 }
  158.  
  159. procedure TAndroidModule1.AndroidModule1JNIPrompt(Sender: TObject);
  160. var i: Integer;
  161. begin
  162.   Layers[0]:= TChessBoard.Create;
  163.   Layers[1]:= TGradiant.Create;
  164.   Layers[2]:= TDonut.Create;
  165.  
  166.   for i:= 0 to High(Layers) do with Layers[i] do begin
  167.     UpdateDimensions(CanvasES21.GetWidth, CanvasES21.GetHeight);
  168.     SetTheBufferUp;
  169.     //Update;
  170.   end;
  171. end;
  172.  
  173. procedure TAndroidModule1.CanvasES21GLCreate(Sender: TObject);
  174. var i: Integer;
  175. begin
  176.   CanvasES21.Shader_Compile('simon_Vert', 'simon_Frag');
  177.   CanvasES21.Shader_Link;
  178.  
  179.   for i:= 0 to High(Layers) do glGenTextures(1, @Layers[i].Texture.ID);
  180. end;
  181.  
  182. procedure TAndroidModule1.CanvasES21GLDraw(Sender: TObject);
  183. var i: Integer;
  184. begin
  185.   CanvasES21.MVP:= cID4x4;
  186.   CanvasES21.SetMVP(CanvasES21.MVP);
  187.   CanvasES21.Screen_Setup(CanvasES21.GetWidth, CanvasES21.GetHeight);
  188.   CanvasES21.Screen_Clear(0, 0, 0, 1);
  189.  
  190.   for i:= 0 to High(Layers) do with Layers[i] do begin
  191.     UpdateDimensions(CanvasES21.GetWidth, CanvasES21.GetHeight);
  192.  
  193.     Update;
  194.     DeployBuffer(GetBuffer, GetTexture, GetWidth, GetHeight);
  195.     DrawTexture(GetTexture, GetAlpha, RightCorner, TopCorner, LeftCorner, DownCorner);
  196.    end;
  197. end;
  198.  
  199. procedure TAndroidModule1.DeployBuffer(B: PDWord; T: TxgElement; W, H: Integer);
  200. begin
  201.   glDisable      (GL_DEPTH_BUFFER_BIT);
  202.   glBindTexture  (GL_TEXTURE_2D, T.ID);
  203.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  204.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  205.   glTexparameteri(GL_Texture_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  206.   glTexparameteri(GL_Texture_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  207.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, B);
  208. end;
  209.  
  210. procedure TAndroidModule1.DrawTexture(T: TxgElement; A, x1, y1, x0, y0: Single);
  211. begin
  212.   CanvasES21.DrawTexture(T, _xy4CW(x1,y0, x0,y0, x0,y1, x1,y1), 0, A);
  213. end;
  214.  
  215. { TMyOwnPrimitives }
  216.  
  217. constructor TMyOwnPrimitives.Create;
  218. begin
  219.   Data:= Nil;
  220.   Len:=0;
  221.   W:= 0; H:=0; X:=0;
  222.  
  223.   Alpha:= FullyOpaque;
  224.   AlphaMater:= FULLY_OPAQUE;
  225.   SetBackgroundColor(BlackColor);
  226. end;
  227.  
  228. procedure TMyOwnPrimitives.Update;
  229. begin
  230.  
  231. end;
  232.  
  233. procedure TMyOwnPrimitives.UpdateDimensions(Width, Height: Integer);
  234. begin
  235.   W:= Width; H:= Height;
  236. end;
  237.  
  238. procedure TMyOwnPrimitives.SetTheBufferUp;
  239. begin
  240.   Len:= W*H;
  241.   GetMem(Data, Len*SizeOf(DWord));
  242. end;
  243.  
  244. procedure TMyOwnPrimitives.SetPencilColor(NewColor: DWord);
  245. begin
  246.   PencilColor:= NewColor;
  247.   UpdateColor;
  248. end;
  249.  
  250. procedure TMyOwnPrimitives.UpdateColor;
  251. begin
  252.   Color:= PencilColor or Alpha;
  253. end;
  254.  
  255. procedure TMyOwnPrimitives.SetBackgroundColor(NewColor: Dword);
  256. begin
  257.   BackgroundColor:= NewColor or Alpha;
  258. end;
  259.  
  260. function TMyOwnPrimitives.GetWidth: Integer;
  261. begin
  262.   Result:= W;
  263. end;
  264.  
  265. function TMyOwnPrimitives.GetHeight: Integer;
  266. begin
  267.   Result:= H;
  268. end;
  269.  
  270. function TMyOwnPrimitives.GetBuffer: PDWord;
  271. begin
  272.   Result:= Data;
  273. end;
  274.  
  275. function TMyOwnPrimitives.GetAlpha: Single;
  276. begin
  277.   Result:= AlphaMater;
  278. end;
  279.  
  280. function TMyOwnPrimitives.GetTexture: TxgElement;
  281. begin
  282.   Result:= Texture;
  283. end;
  284.  
  285. procedure TMyOwnPrimitives.MoveToInitialPoint;
  286. begin
  287.   X:= 0;
  288. end;
  289.  
  290. procedure TMyOwnPrimitives.MoveTo(NewX, Newy: Integer);
  291. begin
  292.   X:= NewX + W*NewY;
  293. end;
  294.  
  295. procedure TMyOwnPrimitives.DrawHorizontal(Lenght: Integer);
  296. begin
  297.   FillDWord(Data[X], Lenght, Color);
  298.   Inc(X, Lenght);
  299. end;
  300.  
  301. procedure TMyOwnPrimitives.Clean;
  302. begin
  303.   FillDWord(Data^, Len, BackgroundColor);
  304. end;
  305.  
  306. { TChessBoard }
  307.  
  308. constructor TChessBoard.Create;
  309. begin
  310.   inherited Create;
  311.   SetSquareSize(Square32x32pixels);
  312.   SetPencilColor(GoldenBrown);
  313. end;
  314.  
  315. procedure TChessBoard.SetSquareSize(SquareSize: Integer);
  316. begin
  317.   DoubleSquareSize:= SquareSize + 1;
  318.   LenghtOfSquareSide:= 1 shl SquareSize;
  319.   Mask:= (1 shl DoubleSquareSize) - 1;
  320. end;
  321.  
  322. procedure TChessBoard.UpdateDimensions(Width, Height: Integer);
  323. begin
  324.   inherited UpdateDimensions(Width, Height);
  325.   TotalSquaresByHeight:= H shr DoubleSquareSize;
  326.   TotalSquaresByWidth:=  W shr DoubleSquareSize;
  327.   Remainder:=            W and Mask;
  328. end;
  329.  
  330. procedure TChessBoard.Update;
  331. var i: Integer;
  332. begin
  333.   Clean;
  334.   MoveToInitialPoint;
  335.   for i:= 1 to TotalSquaresByHeight do DrawTwoSquareRows;
  336. end;
  337.  
  338. procedure TChessBoard.DrawTwoSquareRows;
  339. begin
  340.   DrawSquareRow;
  341.   WalkASquare;
  342.   DrawSquareRow;
  343.   GoASquareBack;
  344. end;
  345.  
  346. procedure TChessBoard.DrawSquareRow;
  347. var i: Integer;
  348. begin
  349.   for i:= 1 to LenghtOfSquareSide do DrawLine;
  350. end;
  351.  
  352. procedure TChessBoard.DrawLine;
  353. var i: Integer;
  354. begin
  355.   for i:= 1 to TotalSquaresByWidth do DrawTwoSquares;
  356.   MoveToNextLine;
  357. end;
  358.  
  359. procedure TChessBoard.DrawTwoSquares;
  360. begin
  361.   DrawHorizontal(LenghtOfSquareSide);
  362.   WalkASquare;
  363. end;
  364.  
  365. procedure TChessBoard.MoveToNextLine;
  366. begin
  367.   Inc(X, Remainder);
  368. end;
  369.  
  370. procedure TChessBoard.WalkASquare;
  371. begin
  372.   Inc(X, LenghtOfSquareSide);
  373. end;
  374.  
  375. procedure TChessBoard.GoASquareBack;
  376. begin
  377.   Dec(X, LenghtOfSquareSide);
  378. end;
  379.  
  380. { TGradiant }
  381.  
  382. constructor TGradiant.Create;
  383. begin
  384.   inherited Create;
  385.   SetPencilColor(PrussianBlue);
  386. end;
  387.  
  388. procedure TGradiant.Update;
  389. begin
  390.   Gradiant:= FullyOpaque;
  391.   inherited Update;
  392. end;
  393.  
  394. procedure TGradiant.UpdateColor;
  395. begin
  396.   Color:= PencilColor or (Gradiant);
  397. end;
  398.  
  399. procedure TGradiant.DrawLine;
  400. begin
  401.   CalculateGradiant;
  402.   UpdateColor;
  403.   inherited DrawLine;
  404. end;
  405.  
  406. procedure TGradiant.CalculateGradiant;
  407. begin
  408.   If Numerator > H then DecrementGradianteAndNumerator;
  409.   Inc(Numerator, DifferentLevelsOfTransparency);
  410. end;
  411.  
  412. procedure TGradiant.DecrementGradianteAndNumerator;
  413. begin
  414.   Dec(Gradiant, OneLevelOfTrransparency);
  415.   Dec(Numerator, H);
  416. end;
  417.  
  418. { TDonut }
  419.  
  420. constructor TDonut.Create;
  421. begin
  422.   inherited Create;
  423.   AlphaMater:= PARTIALLY_TRANSPARENT;
  424. end;
  425.  
  426. procedure TDonut.Update;
  427. begin
  428.   UpdateRadiusAndHole;
  429.   SetBackGroundTransparent;
  430.  
  431.   MoveToTheCenter;
  432.   SetPencilColor(PinkLavander);
  433.   DrawFilledCircle(DonutRadius);
  434.  
  435.   SetPencilTransparent;
  436.   DrawFilledCircle(HoleRadius);
  437. end;
  438.  
  439. procedure TDonut.UpdateRadiusAndHole;
  440. begin
  441.   WhichIsShorterBetweenHAndW;
  442.   DonutRadius:= TheShorter shr 2;
  443.   HoleRadius:= DonutRadius - (TheShorter shr 4);
  444. end;
  445.  
  446. procedure TDonut.SetBackGroundTransparent;
  447. begin
  448.   BackgroundColor:= FullyTransparent;
  449.   Clean;
  450. end;
  451.  
  452. procedure TDonut.SetPencilTransparent;
  453. begin
  454.   Color:= FullyTransparent;
  455. end;
  456.  
  457. procedure TDonut.MoveToTheCenter;
  458. begin
  459.   MoveTo(W shr 1, H shr 1);
  460. end;
  461.  
  462. procedure TDonut.WhichIsShorterBetweenHAndW;
  463. begin
  464.   if W > H then TheShorter:= H
  465.   else TheShorter:= W
  466. end;
  467.  
  468. (*  Bresenham's Midpoint Circle Algorithm
  469. *)
  470. procedure TDonut.DrawFilledCircle(Radius: Integer);
  471. var
  472.    CircleX, CircleY, d, deltaE, deltaSE: Integer;
  473. begin
  474.    CircleX:= 0;
  475.    CircleY:= Radius;
  476.    d:= 1 - Radius;
  477.    deltaE:= 3;
  478.    deltaSE:= 5 -(Radius shl 1);
  479.    CirclePoints(CircleX, CircleY);
  480.  
  481.    while CircleY > CircleX do begin
  482.      if d < 0 then begin
  483.        Inc(d, deltaE);
  484.        Inc(deltaE, 2);
  485.        Inc(deltaSE,2);
  486.        Inc(CircleX);
  487.      end else begin
  488.        Inc(d, deltaSE);
  489.        Inc(deltaE,  2);
  490.        Inc(deltaSE, 4);
  491.        Inc(CircleX);
  492.        Dec(CircleY);
  493.      end;
  494.      CirclePoints(CircleX, CircleY);
  495.    end;
  496. end;
  497.  
  498. procedure TDonut.CirclePoints(Cx, Cy: Integer);
  499. var Wx, Wy: Integer;
  500. begin
  501.   Wx:= W*Cx; Wy:= W*Cy;
  502.   FillDWord(Data[X-Cx+Wy], Cx shl 1, Color);
  503.   FillDWord(Data[X-Cx-Wy], Cx shl 1, Color);
  504.   FillDWord(Data[X-Cy+Wx], Cy shl 1, Color);
  505.   FillDWord(Data[X-Cy-Wx], Cy shl 1, Color);
  506. end;
  507.  
  508. end.
  509.  

José Hernández

  • Newbie
  • Posts: 5
Playing more with the Alpha channel, we could use the code from this thread:
https://forum.lazarus.freepascal.org/index.php?topic=44811.0

And improve it a bit: As the circle grows, it fades away like a ghost.

Enjoy reading the code:
Code: Pascal  [Select][+][-]
  1. unit unit1;
  2.  
  3. {$mode delphi}
  4.  
  5. interface
  6.  
  7. uses
  8.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  9.   cthreads,
  10.   {$ENDIF}{$ENDIF}
  11.   Classes, SysUtils, AndroidWidget,
  12.   Laz_And_GLESv2_Canvas, Laz_And_GLESv2_Canvas_h, Laz_And_Controls;
  13.  
  14. type
  15.  
  16.   { TAndroidModule1 }
  17.  
  18.   TAndroidModule1 = class(jForm)
  19.     CanvasES21: jCanvasES2;
  20.     Timer1: jTimer;
  21.     procedure AndroidModule1JNIPrompt(Sender: TObject);
  22.     procedure CanvasES21GLCreate(Sender: TObject);
  23.     procedure CanvasES21GLDown(Sender: TObject; Touch: TMouch);
  24.     procedure CanvasES21GLDraw(Sender: TObject);
  25.     procedure CanvasES21GLUp(Sender: TObject; Touch: TMouch);
  26.     procedure Timer1Timer(Sender: TObject);
  27.   private
  28.     {private declarations}
  29.   public
  30.     {public declarations}
  31.     procedure DeployBuffer(B: PDWord; T: TxgElement; W, H: Integer);
  32.     procedure DrawTexture(T: TxgElement; A, x1, y1, x0, y0: Single);
  33.   end;
  34.  
  35.   { TMyOwnPrimitives }
  36.   TMyOwnPrimitives = class
  37.     private
  38.       Data:            PDWord;
  39.       Len:             Integer;
  40.  
  41.       Alpha:           DWord;
  42.       Color:           DWord;
  43.       AlphaMater:      Single;
  44.       PencilColor:     DWord;
  45.       BackgroundColor: DWord;
  46.  
  47.       W,H,X:           Integer;
  48.       Texture:         TxgElement;
  49.  
  50.       TheDimensionsHaveChanged: Boolean;
  51.     public
  52.       constructor Create; virtual;
  53.       procedure Update;  virtual;
  54.       procedure UpdateColor;  virtual;
  55.       procedure UpdateDimensions(NewWidth, NewHeight: Integer); virtual;
  56.       procedure SetTheBufferUp;
  57.       procedure SetPencilColor(NewColor: DWord);
  58.       procedure SetBackgroundColor(NewColor: Dword);
  59.       function  GetWidth:   Integer;
  60.       function  GetHeight:  Integer;
  61.       function  GetBuffer:  PDWord;
  62.       function  GetAlpha:   Single;
  63.       function  GetTexture: TxgElement;
  64.  
  65.       procedure MoveToInitialPoint;
  66.       procedure MoveTo(NewX, Newy: Integer);
  67.       procedure DrawHorizontal(Lenght: Integer);
  68.       procedure Clean;
  69.   end;
  70.  
  71.  
  72.  
  73.   { TChessBoard }
  74.  
  75.   TChessBoard = class(TMyOwnPrimitives)
  76.      private
  77.        TotalSquaresByWidth:      Integer;
  78.        TotalSquaresByHeight:     Integer;
  79.        LenghtOfSquareSide:       Integer;
  80.        DoubleSquareSize:         Integer;
  81.        Mask:                     Integer;
  82.        Remainder:                Integer;
  83.      public
  84.        constructor Create; override;
  85.        procedure Update; override;
  86.        procedure UpdateDimensions(Width, Height: Integer); override;
  87.        procedure SetSquareSize(SquareSize: Integer);
  88.        procedure DrawTwoSquareRows;
  89.        procedure DrawSquareRow;
  90.        procedure DrawLine; virtual;
  91.        procedure DrawTwoSquares;
  92.        procedure MoveToNextLine;
  93.        procedure WalkASquare;
  94.        procedure GoASquareBack;
  95.    end;
  96.  
  97.   { TGradiant }
  98.  
  99.   TGradiant = class(TChessBoard)
  100.      private
  101.        Gradiant:        DWord;
  102.        Numerator:       Integer;
  103.      public
  104.        constructor Create; override;
  105.        procedure Update; override;
  106.        procedure UpdateColor; override;
  107.        procedure DrawLine; override;
  108.        procedure CalculateGradiant;
  109.        procedure DecrementGradianteAndNumerator;
  110.    end;
  111.  
  112.  
  113.  
  114.   { TFilledCircle }
  115.  
  116.   TFilledCircle = class(TMyOwnPrimitives)
  117.     private
  118.       TheShorter: Integer;
  119.       MaximumRadius, Radius: Integer;
  120.       ClippedRadius: Integer;
  121.       Increment, InitialRadius: Integer;
  122.       Numerator: Integer;
  123.     public
  124.       constructor Create; override;
  125.       procedure Update; override;
  126.       procedure DrawExpandedCircle;
  127.       procedure DrawACircleWhereTheFingerTouches;
  128.       procedure UpdateRadius;
  129.       procedure DecreaseTheOpacity;
  130.       procedure DecreaseNumeratorAndAlpha;
  131.       function TheAlphaChannelIsTooLow: Boolean;
  132.       procedure ResetOpacityAndRadius;
  133.       procedure ResetRadius;
  134.       procedure SetBackGroundTransparent;
  135.       procedure SetPencilTransparent;
  136.       procedure GetClippedRadius;
  137.       function  TheRadiusExceedsTheTopSide: Boolean;
  138.       function  TheRadiusExceedsTheLeftSide: Boolean;
  139.       function  TheRadiusExceedsTheBottomSide: Boolean;
  140.       function  TheRadiusExceedsTheRightSide: Boolean;
  141.       procedure ClipTheTopSide;
  142.       procedure ClipTheLeftSide;
  143.       procedure ClipTheBottomSide;
  144.       procedure ClipTheRightSide;
  145.       procedure DrawFilledCircle(Radius: Integer);
  146.       procedure WhichIsShorterBetweenHAndW;
  147.       procedure CirclePoints(Cx, Cy: Integer); Virtual;
  148.   end;
  149.  
  150.   { TBanner }
  151.  
  152.   TBanner = class(TMyOwnPrimitives)
  153.     private
  154.       Text: String;
  155.       T, Remainder: Integer;
  156.     public
  157.       constructor Create; override;
  158.       procedure Update; override;
  159.       procedure ResetTextIndex;
  160.       procedure DrawBanner;
  161.       procedure DrawBannerLine;
  162.       procedure NextBannerLine;
  163.       procedure PutTextPixel;
  164.       procedure NextTextPixel;
  165.       procedure CalculateRemainder;
  166.   end;
  167.  
  168. var
  169.   AndroidModule1: TAndroidModule1;
  170.   Layers: Array[0..3] of TMyOwnPrimitives;
  171.   isPressing: Boolean = False;
  172.   FingerX: Integer = 100;
  173.   FingerY: Integer = 100;
  174.  
  175.   TextBanner: String =
  176.       '                             00                                                                          00                             00        0                 00                              '
  177.     + '0000000                      00          00000                                                           00                 00000                 0                 00                              '
  178.     + '   0                         00         0                                                                00                00                     0                 00                              '
  179.     + '   0    0000   0    0   0000 000000     00       0000 0 00  0000   0000   00000       0000   00000    00000      0000      0       0 00 00  0000  0   0000       00000  0 00 0000  00  00   0 00000 '
  180.     + '   0   00  00  0    0  00    00   0      00     00    00   00  00 00  00  00  00         00  00  00  0   00         00    00       00   00  0     0  00  00     0   00  00      00  0  000  0 00  00'
  181.     + '   0   0    00 0    0  0     00   0       000  00     00   0    0 0    0  0   00         00  0   00 00   00         00    00       0    00 00     0  0    0    00   00  0       00  0  000 00 0   00'
  182.     + '   0   0    00 0    0  0     00   0         00 00     0    000000 000000  0   00      00000  0   00 00   00      00000    00       0    00 00     0  000000    00   00  0    00000  00 0 0 00 0   00'
  183.     + '   0   0    00 0    0  0     00   0          0 00     0    0      0       0   00     00  00  0   00 00   00     00  00     0       0    00 00     0  0         00   00  0   00  00   000 000  0   00'
  184.     + '   0   00  00  00  00  00    00   0          0  00    0    00     00      0   00     0   00  0   00  0   00     0   00     00      0    00  0     0  00         0   00  0   0   00   00  000  0   00'
  185.     + '   0    0000    00000   0000 00   0     00000    0000 0     00000  00000  0   00     000000  0   00   00000     000000      00000  0    00  0000  0   00000      00000  0    00000   00   00  0   00';
  186.  
  187. const
  188.    FullyOpaque          = $ff000000;
  189.    FullyTransparent     = $00000000;
  190.    PartiallyTransparent = $80000000;
  191.  
  192.    BlackColor   = $00000000;
  193.    WhiteColor   = $00bfbfbf;
  194.    GoldenBrown  = $001e5b89;
  195.    PrussianBlue = $00543500;
  196.    Olivine      = $0080c4b8;
  197.    PinkLavander = $00c1afdb;
  198.  
  199.    FULLY_OPAQUE          =  1.00;
  200.    PARTIALLY_TRANSPARENT =  0.25;
  201.    RightCorner           =  1.00;
  202.    LeftCorner            = -1.00;
  203.    TopCorner             =  1.00;
  204.    DownCorner            = -1.00;
  205.  
  206.    Square32x32pixels = 5;
  207.    Square16x16pixels = 4;
  208.    Square64x64pixels = 6;
  209.  
  210.    OneLevelOfTrransparency   = $01000000;
  211.    EightLevelOfTrransparency = $08000000;
  212.    DifferentLevelsOfTransparency = 255;
  213.    Infinite = $7fffffff;
  214.  
  215.    _120FPS = 8;
  216.    _60FPS = 17;
  217.    _50FPS = 20;
  218.    _30FPS = 33;
  219.    _25FPS = 40;
  220.  
  221.    HeightBanner = 10;
  222.    WidthBanner = 196;
  223.  
  224.  
  225. implementation
  226.  
  227.  
  228. {$R *.lfm}
  229.  
  230.  
  231.  
  232. { TAndroidModule1 }
  233.  
  234. procedure TAndroidModule1.Timer1Timer(Sender: TObject);
  235. begin
  236.   CanvasES21.Refresh;
  237. end;
  238.  
  239. procedure TAndroidModule1.AndroidModule1JNIPrompt(Sender: TObject);
  240. var i: Integer;
  241. begin
  242.   Layers[0]:= TChessBoard.Create;
  243.   Layers[1]:= TGradiant.Create;
  244.   Layers[2]:= TBanner.Create;
  245.   Layers[3]:= TFilledCircle.Create;
  246.  
  247.   for i:= 0 to High(Layers) do with Layers[i] do begin
  248.     UpdateDimensions(CanvasES21.GetWidth, CanvasES21.GetHeight);
  249.     SetTheBufferUp;
  250.   end;
  251.  
  252.   Timer1.Interval:= _50FPS;
  253.   Timer1.Enabled:= True;
  254. end;
  255.  
  256. procedure TAndroidModule1.CanvasES21GLCreate(Sender: TObject);
  257. var i: Integer;
  258. begin
  259.   CanvasES21.Shader_Compile('simon_Vert', 'simon_Frag');
  260.   CanvasES21.Shader_Link;
  261.  
  262.   for i:= 0 to High(Layers) do glGenTextures(1, @Layers[i].Texture.ID);
  263. end;
  264.  
  265. procedure TAndroidModule1.CanvasES21GLDown(Sender: TObject; Touch: TMouch);
  266. begin
  267.   isPressing:= True;
  268.   FingerX:= round(Touch.Pt.X);
  269.   FingerY:= round(Touch.Pt.Y);
  270. end;
  271.  
  272. procedure TAndroidModule1.CanvasES21GLDraw(Sender: TObject);
  273. var i: Integer;
  274. begin
  275.   CanvasES21.MVP:= cID4x4;
  276.   CanvasES21.SetMVP(CanvasES21.MVP);
  277.   CanvasES21.Screen_Setup(CanvasES21.GetWidth, CanvasES21.GetHeight);
  278.  
  279.   for i:= 0 to High(Layers) do with Layers[i] do begin
  280.     UpdateDimensions(CanvasES21.GetWidth, CanvasES21.GetHeight);
  281.     Update;
  282.     DeployBuffer(GetBuffer, GetTexture, GetWidth, GetHeight);
  283.     DrawTexture(GetTexture, GetAlpha, RightCorner, TopCorner, LeftCorner, DownCorner);
  284.    end;
  285. end;
  286.  
  287. procedure TAndroidModule1.CanvasES21GLUp(Sender: TObject; Touch: TMouch);
  288. begin
  289.   isPressing:= False;
  290.   Touch.Pt.X:= Touch.Pt.X;
  291. end;
  292.  
  293. procedure TAndroidModule1.DeployBuffer(B: PDWord; T: TxgElement; W, H: Integer);
  294. begin
  295.   glDisable      (GL_DEPTH_BUFFER_BIT);
  296.   glBindTexture  (GL_TEXTURE_2D, T.ID);
  297.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  298.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  299.   glTexparameteri(GL_Texture_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  300.   glTexparameteri(GL_Texture_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  301.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, B);
  302. end;
  303.  
  304. procedure TAndroidModule1.DrawTexture(T: TxgElement; A, x1, y1, x0, y0: Single);
  305. begin
  306.   CanvasES21.DrawTexture(T, _xy4CW(x1,y0, x0,y0, x0,y1, x1,y1), 0, A);
  307. end;
  308.  
  309. { TMyOwnPrimitives }
  310.  
  311. constructor TMyOwnPrimitives.Create;
  312. begin
  313.   Data:= Nil;
  314.   Len:=0;
  315.   W:= 0; H:=0; X:=0;
  316.  
  317.   Alpha:= FullyOpaque;
  318.   AlphaMater:= FULLY_OPAQUE;
  319.   SetBackgroundColor(BlackColor);
  320.   TheDimensionsHaveChanged:= True;
  321. end;
  322.  
  323. procedure TMyOwnPrimitives.Update;
  324. begin
  325.  
  326. end;
  327.  
  328. procedure TMyOwnPrimitives.UpdateDimensions(NewWidth, NewHeight: Integer);
  329. begin
  330.   TheDimensionsHaveChanged:= ((W xor NewWidth) or (H xor NewHeight)) <> 0;
  331.   W:= NewWidth; H:= NewHeight;
  332. end;
  333.  
  334.  
  335. procedure TMyOwnPrimitives.SetTheBufferUp;
  336. begin
  337.   Len:= W*H;
  338.   GetMem(Data, Len*SizeOf(DWord));
  339. end;
  340.  
  341. procedure TMyOwnPrimitives.SetPencilColor(NewColor: DWord);
  342. begin
  343.   PencilColor:= NewColor;
  344.   UpdateColor;
  345. end;
  346.  
  347. procedure TMyOwnPrimitives.UpdateColor;
  348. begin
  349.   Color:= PencilColor or Alpha;
  350. end;
  351.  
  352. procedure TMyOwnPrimitives.SetBackgroundColor(NewColor: Dword);
  353. begin
  354.   BackgroundColor:= NewColor or Alpha;
  355. end;
  356.  
  357. function TMyOwnPrimitives.GetWidth: Integer;
  358. begin
  359.   Result:= W;
  360. end;
  361.  
  362. function TMyOwnPrimitives.GetHeight: Integer;
  363. begin
  364.   Result:= H;
  365. end;
  366.  
  367. function TMyOwnPrimitives.GetBuffer: PDWord;
  368. begin
  369.   Result:= Data;
  370. end;
  371.  
  372. function TMyOwnPrimitives.GetAlpha: Single;
  373. begin
  374.   Result:= AlphaMater;
  375. end;
  376.  
  377. function TMyOwnPrimitives.GetTexture: TxgElement;
  378. begin
  379.   Result:= Texture;
  380. end;
  381.  
  382. procedure TMyOwnPrimitives.MoveToInitialPoint;
  383. begin
  384.   X:= 0;
  385. end;
  386.  
  387. procedure TMyOwnPrimitives.MoveTo(NewX, Newy: Integer);
  388. begin
  389.   X:= NewX + W*NewY;
  390. end;
  391.  
  392. procedure TMyOwnPrimitives.DrawHorizontal(Lenght: Integer);
  393. begin
  394.   FillDWord(Data[X], Lenght, Color);
  395.   Inc(X, Lenght);
  396. end;
  397.  
  398. procedure TMyOwnPrimitives.Clean;
  399. begin
  400.   FillDWord(Data^, Len, BackgroundColor);
  401. end;
  402.  
  403. { TChessBoard }
  404.  
  405. constructor TChessBoard.Create;
  406. begin
  407.   inherited Create;
  408.   SetSquareSize(Square32x32pixels);
  409.   SetPencilColor(GoldenBrown);
  410. end;
  411.  
  412. procedure TChessBoard.SetSquareSize(SquareSize: Integer);
  413. begin
  414.   DoubleSquareSize:= SquareSize + 1;
  415.   LenghtOfSquareSide:= 1 shl SquareSize;
  416.   Mask:= (1 shl DoubleSquareSize) - 1;
  417. end;
  418.  
  419. procedure TChessBoard.UpdateDimensions(Width, Height: Integer);
  420. begin
  421.   inherited UpdateDimensions(Width, Height);
  422.   TotalSquaresByHeight:= H shr DoubleSquareSize;
  423.   TotalSquaresByWidth:=  W shr DoubleSquareSize;
  424.   Remainder:=            W and Mask;
  425. end;
  426.  
  427. procedure TChessBoard.Update;
  428. var i: Integer;
  429. begin
  430.   Clean;
  431.   MoveToInitialPoint;
  432.   for i:= 1 to TotalSquaresByHeight do DrawTwoSquareRows;
  433. end;
  434.  
  435. procedure TChessBoard.DrawTwoSquareRows;
  436. begin
  437.   DrawSquareRow;
  438.   WalkASquare;
  439.   DrawSquareRow;
  440.   GoASquareBack;
  441. end;
  442.  
  443. procedure TChessBoard.DrawSquareRow;
  444. var i: Integer;
  445. begin
  446.   for i:= 1 to LenghtOfSquareSide do DrawLine;
  447. end;
  448.  
  449. procedure TChessBoard.DrawLine;
  450. var i: Integer;
  451. begin
  452.   for i:= 1 to TotalSquaresByWidth do DrawTwoSquares;
  453.   MoveToNextLine;
  454. end;
  455.  
  456. procedure TChessBoard.DrawTwoSquares;
  457. begin
  458.   DrawHorizontal(LenghtOfSquareSide);
  459.   WalkASquare;
  460. end;
  461.  
  462. procedure TChessBoard.MoveToNextLine;
  463. begin
  464.   Inc(X, Remainder);
  465. end;
  466.  
  467. procedure TChessBoard.WalkASquare;
  468. begin
  469.   Inc(X, LenghtOfSquareSide);
  470. end;
  471.  
  472. procedure TChessBoard.GoASquareBack;
  473. begin
  474.   Dec(X, LenghtOfSquareSide);
  475. end;
  476.  
  477. { TGradiant }
  478.  
  479. constructor TGradiant.Create;
  480. begin
  481.   inherited Create;
  482.   SetPencilColor(PrussianBlue);
  483. end;
  484.  
  485. procedure TGradiant.Update;
  486. begin
  487.   Gradiant:= FullyOpaque;
  488.   inherited Update;
  489. end;
  490.  
  491. procedure TGradiant.UpdateColor;
  492. begin
  493.   Color:= PencilColor or (Gradiant);
  494. end;
  495.  
  496. procedure TGradiant.DrawLine;
  497. begin
  498.   CalculateGradiant;
  499.   UpdateColor;
  500.   inherited DrawLine;
  501. end;
  502.  
  503. procedure TGradiant.CalculateGradiant;
  504. begin
  505.   If Numerator > H then DecrementGradianteAndNumerator;
  506.   Inc(Numerator, DifferentLevelsOfTransparency);
  507. end;
  508.  
  509. procedure TGradiant.DecrementGradianteAndNumerator;
  510. begin
  511.   Dec(Gradiant, OneLevelOfTrransparency);
  512.   Dec(Numerator, H);
  513. end;
  514.  
  515. { TFilledCircle }
  516.  
  517. constructor TFilledCircle.Create;
  518. begin
  519.   inherited Create;
  520.   ClippedRadius:= Infinite;
  521. end;
  522.  
  523. procedure TFilledCircle.Update;
  524. begin
  525.   UpdateRadius;
  526.   SetBackGroundTransparent;
  527.  
  528.   if isPressing then DrawExpandedCircle
  529.   else ResetOpacityAndRadius;
  530. end;
  531.  
  532. procedure TFilledCircle.DrawExpandedCircle;
  533. begin
  534.   Inc(Radius, Increment);
  535.  
  536.   GetClippedRadius;
  537.   if Radius > ClippedRadius then ResetOpacityAndRadius;
  538.  
  539.   DrawACircleWhereTheFingerTouches;
  540.  
  541.   DecreaseTheOpacity;
  542. end;
  543.  
  544. procedure TFilledCircle.UpdateRadius;
  545. begin
  546.   WhichIsShorterBetweenHAndW;
  547.   InitialRadius:=  TheShorter shr 3;
  548.   MaximumRadius:=  TheShorter shr 2 + InitialRadius;
  549.   Increment:=      TheShorter shr 7;
  550. end;
  551.  
  552. procedure TFilledCircle.DrawACircleWhereTheFingerTouches;
  553. begin
  554.   MoveTo(FingerX, FingerY);
  555.   SetPencilColor(PinkLavander);
  556.   DrawFilledCircle(Radius);
  557. end;
  558.  
  559. procedure TFilledCircle.DecreaseTheOpacity;
  560. begin
  561.   while Numerator > InitialRadius do DecreaseNumeratorAndAlpha;
  562.   Inc(Numerator, InitialRadius);
  563. end;
  564.  
  565. procedure TFilledCircle.DecreaseNumeratorAndAlpha;
  566. begin
  567.   Dec(Numerator, InitialRadius);
  568.   if TheAlphaChannelIsTooLow then Alpha:= 0
  569.   else Dec(Alpha, EightLevelOfTrransparency);
  570. end;
  571.  
  572. function TFilledCircle.TheAlphaChannelIsTooLow: Boolean;
  573. begin
  574.   Result:= Alpha <= EightLevelOfTrransparency;
  575. end;
  576.  
  577. procedure TFilledCircle.GetClippedRadius;
  578. begin
  579.   ClippedRadius:= MaximumRadius;
  580.   if TheRadiusExceedsTheTopSide    then ClipTheTopSide;
  581.   if TheRadiusExceedsTheLeftSide   then ClipTheLeftSide;
  582.   if TheRadiusExceedsTheBottomSide then ClipTheBottomSide;
  583.   if TheRadiusExceedsTheRightSide  then ClipTheRightSide;
  584. end;
  585.  
  586. function TFilledCircle.TheRadiusExceedsTheTopSide: Boolean;
  587. begin
  588.   Result:= FingerY < ClippedRadius;
  589. end;
  590.  
  591. function TFilledCircle.TheRadiusExceedsTheLeftSide: Boolean;
  592. begin
  593.   Result:= FingerX < ClippedRadius;
  594. end;
  595.  
  596. function TFilledCircle.TheRadiusExceedsTheBottomSide: Boolean;
  597. begin
  598.   Result:= (H - FingerY) < ClippedRadius;
  599. end;
  600.  
  601. function TFilledCircle.TheRadiusExceedsTheRightSide: Boolean;
  602. begin
  603.   Result:= (W - FingerX) < ClippedRadius;
  604. end;
  605.  
  606. procedure TFilledCircle.ClipTheTopSide;
  607. begin
  608.   ClippedRadius:= FingerY;
  609. end;
  610.  
  611. procedure TFilledCircle.ClipTheLeftSide;
  612. begin
  613.   ClippedRadius:= FingerX;
  614. end;
  615.  
  616. procedure TFilledCircle.ClipTheBottomSide;
  617. begin
  618.   ClippedRadius:= H - FingerY;
  619. end;
  620.  
  621. procedure TFilledCircle.ClipTheRightSide;
  622. begin
  623.   ClippedRadius:= W - FingerX;
  624. end;
  625.  
  626. procedure TFilledCircle.ResetOpacityAndRadius;
  627. begin
  628.   Alpha:= FullyOpaque;
  629.   Numerator:= DifferentLevelsOfTransparency;
  630.   ResetRadius;
  631. end;
  632.  
  633. procedure TFilledCircle.ResetRadius;
  634. begin
  635.   if InitialRadius > ClippedRadius then Radius:= ClippedRadius
  636.   else Radius:= InitialRadius;
  637. end;
  638.  
  639. procedure TFilledCircle.WhichIsShorterBetweenHAndW;
  640. begin
  641.   if W > H then TheShorter:= H
  642.   else TheShorter:= W;
  643. end;
  644. procedure TFilledCircle.SetBackGroundTransparent;
  645. begin
  646.   BackgroundColor:= FullyTransparent;
  647.   Clean;
  648. end;
  649.  
  650. procedure TFilledCircle.SetPencilTransparent;
  651. begin
  652.   Color:= FullyTransparent;
  653. end;
  654.  
  655. procedure TFilledCircle.DrawFilledCircle(Radius: Integer);
  656. var
  657.   CircleX, CircleY, d, deltaE, deltaSE: Integer;
  658. begin
  659.   CircleX:= 0;
  660.   CircleY:= Radius;
  661.   d:= 1 - Radius;
  662.   deltaE:= 3;
  663.   deltaSE:= 5 -(Radius shl 1);
  664.   CirclePoints(CircleX, CircleY);
  665.  
  666.   while CircleY > CircleX do begin
  667.    if d < 0 then begin
  668.      Inc(d, deltaE);
  669.      Inc(deltaE, 2);
  670.      Inc(deltaSE,2);
  671.      Inc(CircleX);
  672.    end else begin
  673.      Inc(d, deltaSE);
  674.      Inc(deltaE,  2);
  675.      Inc(deltaSE, 4);
  676.      Inc(CircleX);
  677.      Dec(CircleY);
  678.    end;
  679.    CirclePoints(CircleX, CircleY);
  680.   end;
  681. end;
  682.  
  683. procedure TFilledCircle.CirclePoints(Cx, Cy: Integer);
  684. var Wx, Wy: Integer;
  685. begin
  686.   Wx:= W*Cx; Wy:= W*Cy;
  687.   FillDWord(Data[X-Cx+Wy], Cx shl 1, Color);
  688.   FillDWord(Data[X-Cx-Wy], Cx shl 1, Color);
  689.   FillDWord(Data[X-Cy+Wx], Cy shl 1, Color);
  690.   FillDWord(Data[X-Cy-Wx], Cy shl 1, Color);
  691. end;
  692.  
  693. { TBanner }
  694.  
  695. constructor TBanner.Create;
  696. begin
  697.   inherited Create;
  698.   Text:= TextBanner;
  699.   SetPencilColor(WhiteColor);
  700.   BackgroundColor:= FullyTransparent;
  701. end;
  702.  
  703. procedure TBanner.Update;
  704. begin
  705.   Clean;
  706.   ResetTextIndex;
  707.   MoveTo(50, 50);
  708.   DrawBanner;
  709. end;
  710.  
  711. procedure TBanner.ResetTextIndex;
  712. begin
  713.   T:= 1;
  714. end;
  715.  
  716. procedure TBanner.DrawBanner;
  717. var i: Integer;
  718. begin
  719.   CalculateRemainder;
  720.   for i:=1 to HeightBanner do DrawBannerLine;
  721. end;
  722.  
  723. procedure TBanner.DrawBannerLine;
  724. var i: Integer;
  725. begin
  726.   for i:= 1 to WidthBanner do PutTextPixel;
  727.   NextBannerLine;
  728. end;
  729.  
  730. procedure TBanner.PutTextPixel;
  731. begin
  732.   if Text[T] = '0' then begin
  733.     Data[X]:= Color;
  734.     Data[X+1]:= Color;
  735.     Data[X+W]:= Color;
  736.     Data[X+W+1]:= Color;
  737.   end;
  738.   NextTextPixel;
  739. end;
  740.  
  741. procedure TBanner.NextBannerLine;
  742. begin
  743.   Inc(X, Remainder);
  744. end;
  745.  
  746. procedure TBanner.NextTextPixel;
  747. begin
  748.   Inc(T);
  749.   Inc(X, 2);
  750. end;
  751.  
  752. procedure TBanner.CalculateRemainder;
  753. begin
  754.   Remainder:= 3*W - 2*WidthBanner;
  755. end;
  756.  
  757. end.
  758.  
  759.  

 

TinyPortal © 2005-2018