Accessing scan lines (TBGRABitmap.ScanLine) lazarus / 39-Graphics ---------------------------------------------------------------------- Tibb · 2019-12-13 20:29 Hello, I'm trying to draw a grid in perspective using BGRABitmap. 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 Trender.render;begin  calc_projection;     //<< calculating 2D screen points for 3D grid points  make_fastBitmap;     //<< making bitmap (Trender.FfastBitmap) using the output of calc_projection  Fdisplay.ReDraw(FfastBitmap);   //<< drawing the bitmap on screen (see below)end; 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 TDisplay.ReDraw(AfastBitmap: TfastBitmap);var  x, y: Integer;  p: PBGRAPixel;begin  for y := 0 to AfastBitmap.Size.y-1 do begin    p := fbgra.ScanLine[y];                for x := 0 to AfastBitmap.Size.x-1 do begin      PInteger(p)^ := AfastBitmap.Pixels[x, y];      Inc(p);  end;  end;  Fbgra.InvalidateBitmap;  Fbgra.draw(image.Canvas, 0, 0, false);      //image >> TImage   end; After calling 'TDisplay.Redraw' method, i can see the grid but after recalculating the 2D coordinates of the grid ('calc_projection') using new eye coordinates, nothing happens. Is there anything wrong with calling this method the second time without any re-initialization process? Any idea? Thank You. ---------------------------------------------------------------------- winni · 2019-12-13 21:27 Hi! Hard to say without your code, but * Is AfastBitmap a TBGRABitmap??? * Do you draw to the bitmap again (make_fastBitmap) after your recalculation ( calc_projection) ?? And for ReDraw your doing too much work: 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 TDisplay.ReDraw(AfastBitmap: TfastBitmap);beginAfastBitmap.Draw(image.canvas,0,0, false);end;  Winni ---------------------------------------------------------------------- Tibb · 2019-12-13 23:07 Hello winni TFastBitmap (from 'https://wiki.freepascal.org/Fast_direct_pixel_access'): 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   TFastBitmap = class  private    FPixelsData: PByte;    FSize: TPoint;    function GetPixel(X, Y: Integer): TFastBitmapPixel; inline;    procedure SetPixel(X, Y: Integer; const AValue: TFastBitmapPixel); inline;    procedure SetSize(const AValue: TPoint);  public    constructor Create;    destructor Destroy; override;    property Size: TPoint read FSize write SetSize;    property Pixels[X, Y: Integer]: TFastBitmapPixel read GetPixel write SetPixel;  end; 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 function TFastBitmap.GetPixel(x, y: Integer): TFastBitmapPixel;begin  Result := PFastBitmapPixel(FPixelsData + (y * FSize.x + x) * SizeOf(TFastBitmapPixel))^;end; procedure TFastBitmap.SetPixel(x, y: Integer; const AValue: TFastBitmapPixel);begin  PFastBitmapPixel(FPixelsData + (y * FSize.x + x) * SizeOf(TFastBitmapPixel))^ := AValue;end; procedure TFastBitmap.SetSize(const AValue: TPoint);begin  if (FSize.x = AValue.x) and (FSize.y = AValue.x) then    exit;  FSize := AValue;  FPixelsData := ReAllocMem(FPixelsData, FSize.x * FSize.y * SizeOf(TFastBitmapPixel));end; constructor TFastBitmap.Create;begin  Size := Point(0, 0);end; destructor TFastBitmap.Destroy;begin  FreeMem(FPixelsData);  inherited Destroy;end; Do you draw to the bitmap again (make_fastBitmap) after your recalculation ( calc_projection) ?? Yes, a call Trender.render every time i change the 'eye' level. And for ReDraw your doing too much work: Is that a faster method (just calling TBGRABitmap.Draw)? I have read about scan lines access from the above web page (and from here: https: //wiki.freepascal.org/BGRABitmap_tutorial_4#Add_a_painting_handler) as a method for fast pixel access. Thank You! ---------------------------------------------------------------------- winni · 2019-12-13 23:54 Hi! Too much different types and classes. Don't mix FastBitmap and BGRABitmaps -  it only might confuse a newbie. Use BGRABitmap in all cases. * Compute your 3D-Points * Draw them with the desired eye position an a BGRABitmap * Draw the BGRABitmap on the Image.canvas And then change the points or the perspective. And again. And about chapter 4 of the BGRABitmap tutorial:  The do my step 2 and 3 in one step. Your case is a little bit more complicated, so draw on a BGRAbitmap in a separate step/procedure. It is easier to keep control. So my idea is: Forget about FastBitmap and use BGRAbitmap. (Or vice versa) Winni ---------------------------------------------------------------------- circular · 2019-12-14 09:27 Hi Assigning with PInteger(p)^ is ambiguous. The alpha channel might not be set. If then you draw the image as not opaque, it might show nothing. What is exactly the type of the color? Rather use explicit conversion. Or use only TBGRABitmap which provide SetPixel and GetPixel (and much more). ---------------------------------------------------------------------- Tibb · 2019-12-14 10:54 I changed tFastbitmap to TBGRAbitmap. Now, when i try to set pixels by 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 Fbgra.pixels[round(x), round(y)] := fp;  //fp >> TBGRApixel I get 'No palette available' on this line. ---------------------------------------------------------------------- Tibb · 2019-12-14 11:11 Ok now i'm using: 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 Fbgra.SetPixel(round(x), round(y), clRed);//Fbgra.InvalidateBitmap;  //<< Should i use this?Fbgra.draw(image.Canvas, 0, 0, false); I see the grid and not getting the 'No palette available' message. But, 1: Is not the scanline method faster? 2: What is the fastest method to clear the 'display' before i redraw the 'scene'? Thank You! ---------------------------------------------------------------------- winni · 2019-12-14 12:31 Hi! BGRAbitmap.setpixel (and getpixel)  use internal scanline. Only if your implementation is more intelligent than the BGRA it will be faster. To clear a complete BGRAbitmap use MyBitmap.Fill (clWhite); // or green or blue or ..... OR MyBitmap.fill (BGRAPixelTransparent); Winni ---------------------------------------------------------------------- Tibb · 2019-12-15 11:52 Quote from: winni on December 14, 2019, 01:31:54 pmHi! BGRAbitmap.setpixel (and getpixel)  use internal scanline. Only if your implementation is more intelligent than the BGRA it will be faster. To clear a complete BGRAbitmap use MyBitmap.Fill (clWhite); // or green or blue or ..... OR MyBitmap.fill (BGRAPixelTransparent); Winni All is fine for now, thank you!