BBC BASIC for Windows
« Bitmap clipper & plotter (BASIC prototypes) »

Welcome Guest. Please Login or Register.
Apr 6th, 2018, 12:03am



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Bitmap clipper & plotter (BASIC prototypes)  (Read 1240 times)
David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: Bitmap clipper & plotter (BASIC prototypes)
« Reply #4 on: Mar 5th, 2012, 03:18am »

Here is a speed test comparing DrawIconRTR and GFXLIB_PlotScaleBlend.

The two routines, admittedly, do slightly different things:

DrawIconRTR alphablends on a pixel-by-pixel basis (using the alpha value of each source bitmap pixel, and pre-multiplied alphas of background pixels).

GFXLIB_PlotScaleBlend uses a single, global alpha (or opacity) value for all pixels, and doesn't read background alphas.

So the two routines do quite similar things.

GFXLIB_PlotScaleBlend doesn't make use of any MMX/SIMD instructions.

DrawIconRTR is certainly faster until larger scale factors are specified, and much clipping needs to be done. Eventually, GFXLIB_PlotScaleBlend overtakes. I think I know why this is, but it's currently 4:12 AM and I'm too tired to explain my thoughts.

GFXLIB is required to run the source code below.

Here's a link to the EXE (+ .BBC source):

http://www.bb4wgames.com/temp/plotspeedtest.zip

Code:
      REM. -----------------
      REM. PlotSpeedTest.BBC
      REM. -----------------
      REM.
      REM. Compare -- not too scientifically! -- plotting speeds of
      REM. DrawIconRTR and GFXLIB_PlotScaleBlend
      
      MODE 8
      
      SOUND 1, 0, 0, 0 : SOUND OFF
      
      ON ERROR OSCLI "REFRESH ON" : ON : CLS : REPORT : PRINT " at line "; ERL : VDU 7 : END
      
      INSTALL @lib$ + "GFXLIB2.BBC" : PROCInitGFXLIB(d{}, 0)
      INSTALL @lib$ + "GFXLIB_modules\PlotScaleBlend.BBC" : PROCInitModule
      
      GetTickCount% = FNSYS_NameToAddress( "GetTickCount" )
      
      DIM mc% 255
      OSCLI "LOAD """ + @lib$ + "DrawIconRTR.bin"" " + STR$~mc%
      DrawIconRTR% = mc% + 3
      
      DIM Buffer{T%,W%,H%,B%,P%,M%}
      Buffer.W% = @vdu%!208 : Buffer.H% = @vdu%!212 : Buffer.M% = d.bmBuffAddr%
      
      REM. Create a 'test' 128x80, 32-bpp ARGB bitmap
      bmW% = 128 : bmH% = 80 : bm% = FN_createTestBitmap( bmW%, bmH% )
      DIM Bitmap{T%,W%,H%,B%,P%,M%}
      Bitmap.W% = bmW% : Bitmap.H% = bmH% : Bitmap.M% = bm%
      
      COLOUR 15 : PRINT '" DrawIconRTR vs. GFXLIB_PlotScaleBlend"' : COLOUR 7
      INPUT '" Enter a scale factor (1.0) "; scale
      INPUT '" How many iterations? (10000) "; N%
      IF N% <= 0 THEN N% = 10000
      IF scale = 0 THEN scale = 1.0
      IF scale < 0 THEN scale *= -1.0
      
      DIM pt{X%,Y%}
      
      dx% = bmW%*scale
      dy% = bmH%*scale
      pt.X% = 320
      pt.Y% = 256
      
      bmW2% = scale * bmW%
      bmH2% = scale * bmH%
      
      OFF : WAIT 50
      
      SYS "GetCurrentProcess" TO hprocess%
      SYS "SetPriorityClass", hprocess%, &80
      
      REM. Display the 'test bitmap' using DrawIconRTR
      SYS DrawIconRTR%, Buffer{}, pt.X%, pt.Y%, Bitmap{}, dx%, dy%
      SYS "InvalidateRect", @hwnd%, 0, 0
      *REFRESH
      
      REM. Time DrawIconRTR%
      PRINT '" Timing DrawIconRTR ("; N%; " calls; scale factor: ";scale;")..." : WAIT 50
      *REFRESH OFF
      SYS GetTickCount% TO timeA_0%
      FOR I% = 1 TO N%
        SYS DrawIconRTR%, Buffer{}, pt.X%, pt.Y%, Bitmap{}, dx%, dy%
      NEXT
      SYS GetTickCount% TO timeA_1%
      
      *REFRESH ON
      
      REM. Display the 'test bitmap' using GFXLIB_PlotScaleBlend
      SYS GFXLIB_PlotScaleBlend%, d{}, bm%, bmW%, bmH%, bmW2%, bmH2%, pt.X%, pt.Y%, 254
      SYS "InvalidateRect", @hwnd%, 0, 0
      *REFRESH
      
      REM. Time GFXLIB_PlotScaleBlend
      PRINT '" Timing GFXLIB_PlotScaleBlend ("; N%; " calls; scale factor: ";scale;")..." : WAIT 50
      *REFRESH OFF
      SYS GetTickCount% TO timeB_0%
      FOR I% = 1 TO N%
        SYS GFXLIB_PlotScaleBlend%, d{}, bm%, bmW%, bmH%, bmW2%, bmH2%, pt.X%, pt.Y%, 254
      NEXT
      SYS GetTickCount% TO timeB_1%
      
      *REFRESH ON
      
      SYS "GetCurrentProcess" TO hprocess%
      SYS "SetPriorityClass", hprocess%, &20
      
      PRINT '" " + STRING$(40,"-")'
      PRINT '" DrawIconRTR took "; (timeA_1% - timeA_0%)/1000; " s."
      PRINT '" GFXLIB_PlotScaleBlend took "; (timeB_1% - timeB_0%)/1000; " s."
      
      COLOUR 3 : PRINT ''" Finished." : COLOUR 7
      SOUND 1, -10, 220, 1
      ON
      END
      
      DEF FN_createTestBitmap( bmW%, bmH% )
      LOCAL bm%, I%, X%, Y%, r%
      
      DIM bm% 4 * bmW%*bmH% +3 : REM. Needs extra 4 bytes (not 3!) for memory alignment
      bm% = (bm% + 3) AND -4   : REM. Ensures bitmap base address is DWORD-aligned (divisible by 4)
      
      REM. Fill our bitmap with the colour "SlateBlue" (= &6A5ACD)
      FOR I% = bm% TO bm% + (4*bmW%*bmH% - 1) STEP 4
        !I% = &6A5ACD
      NEXT I%
      
      REM. Give our bitmap a bright yellow border
      FOR X% = 0 TO bmW%-1
        bm%!(4*X%) = &FFFF00
        bm%!(4*(bmW%*(bmH%-1) + X%)) = &FFFF00
      NEXT X%
      FOR Y% = 0 TO bmH%-1
        bm%!(4*Y%*bmW%) = &FFFF00
        bm%!(4*(Y%*bmW% + (bmW%-1))) = &FFFF00
      NEXT Y%
      
      REM. Draw a sine wave on the bitmap
      FOR X% = 0 TO bmW%-1
        Y% = bmH%DIV2 + bmH%DIV4*SIN(4*PI * X%/(bmW%-1))
        bm%!(4*(Y%*bmW% + X%)) = &FFFFFF
      NEXT X%
      
      REM. Draw a circle on our bitmap
      FOR I% = 0 TO 359
        r% = 0.25 * SQR((bmW%/2)^2 + (bmH%/2)^2)
        X% = bmW%/2 + r%*SINRADI%
        Y% = bmH%/2 + r%*COSRADI%
        IF X% < 0 X% = 0
        IF Y% < 0 Y% = 0
        IF X% > bmW%-1 X% = bmW%-1
        IF Y% > bmH%-1 Y% = bmH%-1
        bm%!(4*(Y%*bmW% + X%)) = &00FF00
      NEXT I%
      
      = bm%
 



David.

« Last Edit: Jan 2nd, 2013, 05:01am by David Williams » User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: Bitmap clipper & plotter (BASIC prototypes)
« Reply #5 on: Mar 5th, 2012, 4:44pm »

on Mar 5th, 2012, 03:18am, David Williams wrote:
DrawIconRTR alphablends on a pixel-by-pixel basis (using the alpha value of each source bitmap pixel, and pre-multiplied alphas of background pixels).

I don't really know what you mean by "pre-multiplied alphas of background pixels" here. In what sense do 'background' pixels have an alpha anyway? I don't guarantee that my routine will do anything sensible with the 'alpha' byte in the background bitmap: it may well corrupt it. I treat it as a 'don't care' byte.

Quote:
So the two routines do quite similar things

Does yours have the 'reflect' (about either axis) option? That added a significant degree of complexity, as I recollect.

My routine is, of course, optimised for no clipping, since (at least in my applications) clipping is very much an exceptional case.

Richard.
« Last Edit: Mar 5th, 2012, 4:54pm by admin » User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: Bitmap clipper & plotter (BASIC prototypes)
« Reply #6 on: Mar 6th, 2012, 03:21am »

on Mar 5th, 2012, 4:44pm, Richard Russell wrote:
I don't really know what you mean by "pre-multiplied alphas of background pixels" here.


Neither do I (lol).

I now know that what I wrote was nonsense.


on Mar 5th, 2012, 4:44pm, Richard Russell wrote:
Does yours have the 'reflect' (about either axis) option? That added a significant degree of complexity, as I recollect.


No, mine doesn't.

The only GFXLIB routine that performs any kind of flipping/reflection is GFXLIB_PlotFlip (and a variant of it). This may be about to change, however.


David.
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls