Recent

Author Topic: [LAMW] Put one pixel via CanvasSE2 like a pro 😎  (Read 416 times)

José Hernández

  • Newbie
  • Posts: 5
[LAMW] Put one pixel via CanvasSE2 like a pro 😎
« on: August 28, 2025, 07:12:11 am »
Hello everyone, when I need to work with graphics, I use a screen buffer. But I didn't find any procedure or function in Laz_And_GLESv2_Canvas Library could help me to do it. So this situation made me to make one.

Code: Pascal  [Select][+][-]
  1. procedure TAndroidModule1.DeployBufferToTexture(Buffer: PDWord; W, H,
  2.   IdxTexture: Integer);
  3. begin
  4.   glDisable(GL_DEPTH_BUFFER_BIT);
  5.   glBindTexture  (GL_TEXTURE_2D, CanvasES21.Textures[IdxTexture].ID);
  6.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  7.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  8.   glTexparameteri(GL_Texture_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  9.   glTexparameteri(GL_Texture_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  10.   glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE, Buffer);
  11. end;
  12.  
  13.  

Why do I prefer using a screen buffer instead of using library functions?
1. I have more control so I can do more things, my only limit is my imagination.
2. Most of the time my own functions are faster than the library's.
3. Computer graphics algorithms are based on memory access: Bresenham's line and circle, filling algorithms, etc.

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 DeployBufferToTexture(Buffer: PDWord; W, H, IdxTexture: Integer);
  28.     procedure DrawTexture(IdxTexture: Integer; x1, y1, x0, y0, Alpha: Single);
  29.   end;
  30.  
  31.   { TMyOwnPrimitives }
  32.  
  33.   TMyOwnPrimitives = class
  34.         private
  35.            Data:            PDWord;
  36.            Len:             Integer;
  37.            PencilColor:     DWord;
  38.            BackgroundColor: DWord;
  39.            W,H,X:           Integer;
  40.            HalfWidth:       Integer;
  41.            HalfHeight:      Integer;
  42.         public
  43.            constructor Create;
  44.            procedure UpdateDimensions(Width, Height: Integer);
  45.            procedure SetTheBufferUp;
  46.            procedure SetPencilColor(NewColor: DWord);
  47.            function  GetWidth:  Integer;
  48.            function  GetHeight: Integer;
  49.            function  GetBuffer: PDWord;
  50.  
  51.            procedure DrawChessBoard;
  52.            procedure DrawTwoChessBoardLine;
  53.            procedure DrawChessBoardLine;
  54.            procedure DrawTwoChessBoardSquare;
  55.            procedure MoveToInitialPoint;
  56.            procedure TakeAStep;
  57.            procedure TakeAStepBack;
  58.            procedure TakeTwoSteps;
  59.            procedure Clean;
  60.       end;
  61.  
  62. var
  63.   AndroidModule1: TAndroidModule1;
  64.   SetOfPrimiteves: TMyOwnPrimitives;
  65.  
  66. const
  67.    BlackColor   = $ff000000;
  68.    RedColor     = $ff0000bf;
  69.    GreenColor   = $ff00bf00;
  70.    BlueColor    = $ffbf0000;
  71.    WhiteColor   = $ffbfbfbf;
  72.    Z_COORDINATE_AT_THE_ORIGIN = 0;
  73.    FULLY_OPAQUE =  1.0;
  74.    RIGHT_CORNER =  1.0;
  75.    LEFT_CORNER  = -1.0;
  76.    TOP_CORNER   =  1.0;
  77.    DOWN_CORNER  = -1.0;
  78.  
  79. implementation
  80.  
  81.  
  82. {$R *.lfm}
  83.  
  84.  
  85.  
  86. { TAndroidModule1 }
  87.  
  88. procedure TAndroidModule1.AndroidModule1JNIPrompt(Sender: TObject);
  89. begin
  90.   SetOfPrimiteves:= TMyOwnPrimitives.Create;
  91.   SetOfPrimiteves.UpdateDimensions(CanvasES21.GetWidth, CanvasES21.GetHeight);
  92.   SetOfPrimiteves.SetTheBufferUp;
  93. end;
  94.  
  95. procedure TAndroidModule1.CanvasES21GLCreate(Sender: TObject);
  96. begin
  97.   CanvasES21.Shader_Compile('simon_Vert', 'simon_Frag');
  98.   CanvasES21.Shader_Link;
  99.   CanvasES21.TexturesCount:=1;
  100.  
  101.   glGenTextures(1, @CanvasES21.Textures[0].ID);
  102. end;
  103.  
  104. procedure TAndroidModule1.CanvasES21GLDraw(Sender: TObject);
  105. begin
  106.   CanvasES21.MVP:= cID4x4;
  107.   CanvasES21.SetMVP(CanvasES21.MVP);
  108.   CanvasES21.Screen_Setup(CanvasES21.GetWidth, CanvasES21.GetHeight);
  109.   CanvasES21.Screen_Clear(0, 0, 0, 1);
  110.  
  111.   with SetOfPrimiteves do begin
  112.     UpdateDimensions(CanvasES21.GetWidth, CanvasES21.GetHeight);
  113.  
  114.     Clean;
  115.     SetPencilColor(BlueColor);
  116.     DrawChessBoard;
  117.  
  118.     DeployBufferToTexture(GetBuffer, GetWidth, GetHeight, 0);
  119.   end;
  120.  
  121.   DrawTexture(0, RIGHT_CORNER, TOP_CORNER, LEFT_CORNER, DOWN_CORNER, FULLY_OPAQUE);
  122. end;
  123.  
  124. (* This procedure should be part of Laz_And_GLESv2_Canvas.
  125.    But I don't know why it isn't. 🤷  *)
  126. procedure TAndroidModule1.DeployBufferToTexture(Buffer: PDWord; W, H,
  127.   IdxTexture: Integer);
  128. begin
  129.   glDisable      (GL_DEPTH_BUFFER_BIT);
  130.   glBindTexture  (GL_TEXTURE_2D, CanvasES21.Textures[IdxTexture].ID);
  131.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  132.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  133.   glTexparameteri(GL_Texture_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  134.   glTexparameteri(GL_Texture_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  135.   glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, W, H, 0, GL_RGBA, GL_UNSIGNED_BYTE
  136.                 , Buffer);
  137. end;
  138.  
  139. procedure TAndroidModule1.DrawTexture(IdxTexture: Integer; x1, y1, x0, y0,
  140.   Alpha: Single);
  141. begin
  142.   CanvasES21.DrawTexture(  CanvasES21.Textures[IdxTexture]
  143.                          , _xy4CW(x1,y0, x0,y0, x0,y1, x1,y1)
  144.                          , Z_COORDINATE_AT_THE_ORIGIN, Alpha);
  145. end;
  146.  
  147. { TMyOwnPrimitives }
  148. constructor TMyOwnPrimitives.Create;
  149. begin
  150.   Data:= Nil; Len:=0; W:= 0; H:=0; X:=0;
  151.   HalfWidth:= 0;
  152.   HalfHeight:= 0;
  153.   PencilColor:= WhiteColor;
  154.   BackgroundColor:= BlackColor;
  155. end;
  156.  
  157. procedure TMyOwnPrimitives.UpdateDimensions(Width, Height: Integer);
  158. begin
  159.   W:= Width; H:= Height;
  160.   HalfWidth:= Width shr 1;
  161.   HalfHeight:= Height shr 1;
  162. end;
  163.  
  164. procedure TMyOwnPrimitives.SetTheBufferUp;
  165. begin
  166.   Len:= W*H;
  167.   GetMem(Data, Len*SizeOf(DWord));
  168. end;
  169.  
  170. function TMyOwnPrimitives.GetWidth: Integer;
  171. begin
  172.   Result:= W;
  173. end;
  174.  
  175. function TMyOwnPrimitives.GetHeight: Integer;
  176. begin
  177.   Result:= H;
  178. end;
  179.  
  180. function TMyOwnPrimitives.GetBuffer: PDWord;
  181. begin
  182.   Result:= Data;
  183. end;
  184.  
  185. procedure TMyOwnPrimitives.SetPencilColor(NewColor: DWord);
  186. begin
  187.   PencilColor:= NewColor;
  188. end;
  189.  
  190. procedure TMyOwnPrimitives.DrawChessBoard;
  191. var i: Integer;
  192. begin
  193.   MoveToInitialPoint;
  194.   for i:= 1 to HalfHeight do DrawTwoChessBoardLine;
  195. end;
  196.  
  197. procedure TMyOwnPrimitives.DrawTwoChessBoardLine;
  198. begin
  199.   DrawChessBoardLine;
  200.   TakeAStep;
  201.   DrawChessBoardLine;
  202.   TakeAStepBack;
  203. end;
  204.  
  205. procedure TMyOwnPrimitives.DrawChessBoardLine;
  206. var i: Integer;
  207. begin
  208.   for i:= 1 to HalfWidth do DrawTwoChessBoardSquare;
  209. end;
  210.  
  211. procedure TMyOwnPrimitives.DrawTwoChessBoardSquare;
  212. begin
  213.   Data[X]:= PencilColor;
  214.   TakeTwoSteps;
  215. end;
  216.  
  217. procedure TMyOwnPrimitives.MoveToInitialPoint;
  218. begin
  219.   X:= 0;
  220. end;
  221.  
  222. procedure TMyOwnPrimitives.TakeAStep;
  223. begin
  224.   Inc(X);
  225. end;
  226.  
  227. procedure TMyOwnPrimitives.TakeAStepBack;
  228. begin
  229.   Dec(X);
  230. end;
  231.  
  232. procedure TMyOwnPrimitives.TakeTwoSteps;
  233. begin
  234.   Inc(X, 2);
  235. end;
  236.  
  237. procedure TMyOwnPrimitives.Clean;
  238. begin
  239.   FillDWord(Data^, Len, BackgroundColor);
  240. end;
  241.  
  242. end.
  243.  
  244.  

This Code makes a Chess Board pixel by pixel. This confirms that the Screen buffer is working.  Check the images:

 

TinyPortal © 2005-2018