Results 1 to 10 of 12

Thread: TBItmap scanline

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    thanks , but i changed the direction
    i mean it was just my attempt to create a game from scratch (frame buffer) , instead of VCL i used API and CreateDIBSection (much easier) , but even i use assembly code for ploting pixels , i failed to make a smooth sprite movment .

    now i am using SDL
    Last edited by AirPas; 13-07-2011 at 08:58 AM.

  2. #2
    hi again

    could some one correct me , i've tryed to make a procedure that plot a given pixel ( x ,y , color) into TBitmap class

    Code:
    procedure SetScanLinePixel(x,y,c : integer; var _bmp : TBitmap);
    type
      pRGBTripleArray = ^TRGBTripleArray;
      TRGBTripleArray = array[0..32768-1] of TRGBTriple;
    var
      raw : pRGBTripleArray;
    begin
      raw := _bmp.ScanLine[y];
      raw[x].rgbtBlue  := ( c and $ff);
      raw[x].rgbtGreen := ( c shl 8 ) and $ff;
      raw[x].rgbtRed:= ( c shl 16) and $ff; //error :constant expression violates subrange bounds 
    end;
    i don't understand the last compiler error ,

  3. #3
    Disable the compiler's range check error in project options or use {$R-} flag at top of your unit. Also change "c" to be Cardinal and change "shl" to "shr".
    Last edited by LP; 20-09-2011 at 04:27 PM.

  4. #4
    @Lifepower : thanks , i also didn't swap the color
    so this is the correct code

    Code:
    procedure SetScanLinePixel(x,y: integer; c : cardinal; var _bmp : TBitmap);
    type
      pRGBTripleArray = ^TRGBTripleArray;
      TRGBTripleArray = array[0..32768-1] of TRGBTriple;
    var
      raw : pRGBTripleArray;
    begin
      raw := _bmp.ScanLine[y];
      raw[x].rgbtRed    :=  ( c and $ff);  
      raw[x].rgbtGreen :=   ( c shr 8 ) and $ff;
      raw[x].rgbtBlue   :=  ( c shr 16) and $ff;  
    end;
    Last edited by AirPas; 21-09-2011 at 08:50 AM.

  5. #5
    I'd consider optimizing that down to a few less operations...

    Code:
    procedure SetScanLinePixel(x,y:integer; c:longword; var surface:TBitmap);
    type
    	pRGBTriple=^tRGBTriple;
    	pWord=^word;
    var
    	p:pRGBTriple;
    begin
    	{ this typecast makes X add by multiples of 3 }
    	p:=pRGBTriple(surface.scanline[y])+x;
    	word(p^.g):=c and $0000FFFF;
    	p^.r:=(c shr 16) and $000000FF;
    end;
    Probably why NOBODY uses 24 bit bitmap formats -- I'd REALLY recommend upping to RGBA/32 bit format even if you aren't going to use the alpha channel, just for the speed boost, lesser code, etc, etc... Just not having pixels end up breaking qword boundaries would be a huge speedup.

    Assuming built from RGBQuad instead of triple:
    Code:
    procedure SetScanLinePixel(x,y:integer; c:longword; var surface:TBitmap);
    type
    	pLongWord=^longWord;
    var
    	p:pLongWord;
    begin
    	p:=pLongWord(surface.scanline[y])+x;
    	p^:=c;
    end;
    3 byte per pixel graphics sucks... slow, painfully bad math... there's a reason you rarely see anyone use it.

    Mind you, the above works in FPC, no clue if delphi allows for that type of pointer math.
    Last edited by deathshadow; 25-09-2011 at 01:01 PM.
    The accessibility of a website from time to time must be refreshed with the blood of designers and owners. It is its natural manure

  6. #6
    Quote Originally Posted by deathshadow View Post
    Probably why NOBODY uses 24 bit bitmap formats -- I'd REALLY recommend upping to RGBA/32 bit format even if you aren't going to use the alpha channel, just for the speed boost, lesser code, etc, etc... Just not having pixels end up breaking qword boundaries would be a huge speedup.
    Also, 24-bit pixel format is not supported on any of the today's video cards. It's only useful for storage because you save some 1/4th of disk space. I wouldn't worry about the speed implications of the multiplication, on the modern CPUs (including Intel Atom) it's pretty fast; you'll be more limited by memory bandwidth anyway.

    Mind you, the above works in FPC, no clue if delphi allows for that type of pointer math.
    The same code for Delphi would be:
    Code:
    // 24-bit version
    procedure SetScanLinePixel24(x, y: Integer; c: Cardinal; Image: TBitmap);
    var
     DestPtr: Pointer;
    begin
     DestPtr:= Pointer(NativeInt(Image.Scanline[y]) + x * 3);
     // you can replace Move() with two lines of code moving a word and then a byte manually.
     Move(c, DestPtr^, 3);
    end;
    
    // 32-bit version
    procedure SetScanLinePixel32(x, y: Integer; c: Cardinal; Image: TBitmap);
    begin
     // for FPC, replace "NativeInt" with "PtrInt".
     PLongWord(NativeInt(Image.Scanline[y]) + x * 4)^:= c;
    end;

  7. #7
    here is another procedure work with index instead of xy

    Code:
    procedure SetScanLineIndex32(indx:longword; c:cardinal; var image : Tbitmap);
    begin
           Plongword(longword(image.scanline[indx div image.Height]) + indx mod image.Width * 4)^ := c;
    end;

  8. #8
    Quote Originally Posted by Lifepower View Post
    Also, 24-bit pixel format is not supported on any of the today's video cards.
    Not internally, but it is as texture. If you don't use alpha, it is better to keep it 24-bit, and only expand during uploading, otherwise you afaik waste videocard bandwidth (example: showing images from camera's)

    And effective texture upload sizes aren't getting faster as quickly as rendering.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •