[LAMW] DrawCircle using jCanvasES2 lazarus / 43-Android ---------------------------------------------------------------------- Handoko · 2019-03-26 11:22 This post is the answer for a request by a friend here. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {Hint: save all files to location: /home/handoko/Desktop/GLES_Circle/GLES_Circle/jni }unit unit1; {$mode delphi} interface uses  Classes, SysUtils, AndroidWidget, Laz_And_Controls, Laz_And_GLESv2_Canvas;  type   { TAndroidModule1 }   TAndroidModule1 = class(jForm)    jCanvasES2_1: jCanvasES2;    jTextView1: jTextView;    jTimer1: jTimer;    procedure AndroidModule1Destroy(Sender: TObject);    procedure AndroidModule1JNIPrompt(Sender: TObject);    procedure jCanvasES2_1GLCreate(Sender: TObject);    procedure jCanvasES2_1GLDown(Sender: TObject; Touch: TMouch);    procedure jCanvasES2_1GLDraw(Sender: TObject);    procedure jCanvasES2_1GLUp(Sender: TObject; Touch: TMouch);    procedure jTimer1Timer(Sender: TObject);  private    isPressing: Boolean;    CircleX: Single;    CircleY: Single;    CircleR: Single;  end; var  AndroidModule1: TAndroidModule1; implementation  {$R *.lfm} { TAndroidModule1 } procedure TAndroidModule1.AndroidModule1JNIPrompt(Sender: TObject);begin  isPressing := False;  jCanvasES2_1.Screen_Setup(jCanvasES2_1.Width, jCanvasES2_1.Height, xp2D);  jTimer1.Enabled := True;end; procedure TAndroidModule1.AndroidModule1Destroy(Sender: TObject);begin  jTimer1.Enabled := False;end; procedure TAndroidModule1.jCanvasES2_1GLCreate(Sender: TObject);begin  jCanvasES2_1.Shader_Compile('simon_Vert', 'simon_Frag');  jCanvasES2_1.Shader_Link;end; procedure TAndroidModule1.jCanvasES2_1GLDown(Sender: TObject; Touch: TMouch);begin  jTextView1.Visible := False;  CircleX            := (Touch.Pt.X/jCanvasES2_1.Width*2) - 1;  CircleY            := 1 - (Touch.Pt.Y/jCanvasES2_1.Height*2);  CircleR            := 0.1;  isPressing         := True;end; Procedure DrawCircleNew(XY: TXY; Z, L: Single; AColor: TRGBA; AWidth: Single = 0.3);var  i : Integer;begin  For i := 0 to 70 do    AndroidModule1.jCanvasES2_1.DrawLine(      _XYZ(cCircle[(i+0)*2]  *L+XY.X, cCircle[(i+0)*2+1]*L+XY.Y, Z),      _XYZ(cCircle[(i+0)*2+2]*L+XY.X, cCircle[(i+0)*2+3]*L+XY.Y, Z),      AColor, AWidth      );  AndroidModule1.jCanvasES2_1.DrawLine(    _XYZ(cCircle[0]  *L+XY.X, cCircle[1]*L+XY.Y, Z),    _XYZ(cCircle[142]*L+XY.X, cCircle[143]*L+XY.Y, Z),    AColor, AWidth  );end; procedure TAndroidModule1.jCanvasES2_1GLDraw(Sender: TObject);begin   jCanvasES2_1.MVP:= cID4x4;  jCanvasES2_1.SetMVP(jCanvasES2_1.MVP);  jCanvasES2_1.Screen_Clear(0, 0, 0, 1);   if isPressing then    DrawCircleNew(_XY(CircleX, CircleY), 0, CircleR, _RGBA(1, 0, 0, 0.1), 0.02); end; procedure TAndroidModule1.jCanvasES2_1GLUp(Sender: TObject; Touch: TMouch);begin  isPressing := False;end; procedure TAndroidModule1.jTimer1Timer(Sender: TObject);begin  CircleR := CircleR + 0.02;  if CircleR > 0.8 then CircleR := 0.1;  jCanvasES2_1.Refresh;end; end. jCanvasES2.DrawCircle has a serious bug, alternatively I wrote DrawCircleNew, see line #69. I will inform the developer of LAMW later.Previously I used DrawPolyFill to clear the OpenGL's screen. Now I use jCanvasES2.Screen_Clear (see line #91), which is much simpler.This code does not support device rotation, which I still unable to solve.The circle drawn actually is an ellipse because it does not calculate the aspect ratio of the jCanvasES.The circle drawn is not very smooth. This happens because the original author of DrawCircle uses only 72 points to construct the circle and the data are rounded to 2 digits only (which greatly reduces the accuracy).Tested on Android 7.1.2 ARM device, binary compiled using Lazarus 1.8.4 64-bit Linux LAMW rev 754. ---------------------------------------------------------------------- Handoko · 2019-03-26 11:22 And this is the apk: ---------------------------------------------------------------------- José Hernández · 2025-08-25 19:51 I found a blunder in this code by accident. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TAndroidModule1.AndroidModule1JNIPrompt(Sender: TObject);begin  isPressing := False;  jCanvasES2_1.Screen_Setup(jCanvasES2_1.Width, jCanvasES2_1.Height, xp2D);// This shouldn't be here  jTimer1.Enabled := True;end;  This cause weird effects like those: ---------------------------------------------------------------------- José Hernández · 2025-08-25 20:16 When you change the position, it doesn't adjust correctly the image. Also The Alpha Channel(or Transparency) doesn´t work. The solution is changing this 2 functions: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TAndroidModule1.AndroidModule1JNIPrompt(Sender: TObject);begin  isPressing := False;    // No more any bad code  jTimer1.Enabled := True;end;procedure TAndroidModule1.jCanvasES2_1GLDraw(Sender: TObject);begin   jCanvasES2_1.MVP:= cID4x4;  jCanvasES2_1.SetMVP(jCanvasES2_1.MVP);  jCanvasES2_1.Screen_Setup(jCanvasES2_1.Width, jCanvasES2_1.Height, xp2D);// This the Correct place.  jCanvasES2_1.Screen_Clear(0, 0, 0, 1);   if isPressing then    DrawCircleNew(_XY(CircleX, CircleY), 0, CircleR, _RGBA(1, 0, 0, 0.1), 0.02); end;   Now when you change the position the image adjusts correctly and the Alpha Channel works. Here is the attached code: