BBC BASIC for Windows
Programming >> Graphics and Games >> GFXLIB_RevealBackgroundWithSoftBrush (Example 2)
http://bb4w.conforums.com/index.cgi?board=graphics&action=display&num=1318385015

GFXLIB_RevealBackgroundWithSoftBrush (Example 2)
Post by David Williams on Oct 12th, 2011, 02:03am

www.bb4wgames.com/misc/revealbgsoftbrushex2.zip (compiled EXE; 451 Kb)

The real point of this demo is to show the creation of a "brush" using BB4W's native graphics commands (in this case, CIRCLE).

This brush is then used in a circular wipe/transition effect.

After this brush is created and copied from the window, it's then converted to an 8-bpp 256-level greyscale bitmap using GFXLIB_ConvertARGBToBm8 before it can be used with GFXLIB_RevealBackgroundWithSoftBrush.

Source below for the curious.

EDIT: Here's a vertical wipe effect (brush created using BB4W's RECTANGLE and LINE commands):

www.bb4wgames.com/misc/revealbgsoftbrushex2b.zip (compiled EXE; 198 Kb)



Regards,

David.



(Don't try running this!)

Code:
      *ESC OFF
      
      REM. Make 8 MB of RAM available for this program
      M% = 8
      HIMEM = LOMEM + M%*&100000
      HIMEM = (HIMEM + 3) AND -4
      
      REM. Set up simple error handler
      ON ERROR PROCerror( REPORT$, TRUE )
      
      REM. Prevent the user from resizing the program window
      REM. (although they can still minimise it)
      PROCfixWindowSize
      
      REM. Set our program window's dimensions (640 x 512)
      WinW% = 640
      WinH% = 512
      VDU 23, 22, WinW%; WinH%; 8, 16, 16, 0 : OFF
      
      INSTALL @lib$ + "GFXLIB2"
      PROCInitGFXLIB( d{}, 0 )
      
      INSTALL @lib$ + "GFXLIB_modules\Copy"
      PROCInitModule
      
      INSTALL @lib$ + "GFXLIB_modules\ConvertARGBChannelToBm8"
      PROCInitModule
      
      INSTALL @lib$ + "GFXLIB_modules\RevealBackgroundWithSoftBrush"
      PROCInitModule
      
      INSTALL @lib$ + "GFXLIB_modules\PlotAvg"
      PROCInitModule
      
      INSTALL @lib$ + "GFXLIB_modules\PlotShapeHalfIntensity"
      PROCInitModule
      
      REM. Load the 640x512 bitmaps
      bm1% = FNLoadImg( @lib$ + "GFXLIB_media\bg1_640x512x8.bmp", 0 )
      bm2% = FNLoadImg( @lib$ + "GFXLIB_media\bg3_640x512x8.bmp", 0 )
      
      REM. Load the 64x64 ball sprite
      ball% = FNLoadImg( @lib$ + "GFXLIB_media\ball1_64x64x8.bmp", 0 )
      
      REM. Make copies of the 640x512 bitmaps because they're going to get obliterated
      bm1_copy% = FNmalloc( 4 * 640*512 )
      bm2_copy% = FNmalloc( 4 * 640*512 )
      SYS GFXLIB_DWORDCopy%, bm1%, bm1_copy%, 640*512
      SYS GFXLIB_DWORDCopy%, bm2%, bm2_copy%, 640*512
      
      REM. Brush size = 200 (i.e. 200 by 200 pixels)
      bSize% = 200
      bX% = WinW% DIV 2
      bY% = WinH% DIV 2
      
      REM. We need space for both a 32-bpp brush and an 8-bpp brush
      bDataSize% = 4 * bSize%^2
      brush32% = FNmalloc(bDataSize%)
      brush8% = FNmalloc(bDataSize% DIV 4)
      
      REM. Create the brush and display it for two seconds
      *REFRESH OFF
      GCOL 1
      FOR radius% = bSize%DIV2 TO 1 STEP -1
        i& = 255 * (1 - radius%/(bSize%DIV2))^2
        COLOUR 1, i&, i&, i&
        CIRCLE FILL 2*bX%, 2*bY%, 2*radius%
      NEXT radius%
      *REFRESH
      *REFRESH ON
      WAIT 200
      
      REM. Copy and convert our 32-bpp brush to 8-bpp 256-level greyscale
      REM. (We'll quite arbitrarily use the red channel of the ARGB32 bitmap as our source channel,
      REM. although we could equally have chosen the green or blue channel)
      SYS GFXLIB_Copy%, d{}, brush32%, bSize%, bSize%, bX%-bSize%DIV2, bY%-bSize%DIV2
      SYS GFXLIB_ConvertARGBChannelToBm8%, brush32%, brush8%, bSize%^2, 0
      
      REM. Display our (initial) foreground bitmap for one second
      SYS GFXLIB_BPlot%, d{}, bm1%, 640, 512, 0, 0
      PROCdisplay : WAIT 100
      
      maxR% = WinW%DIV2 + bSize%
      
      *REFRESH OFF
      
      REPEAT
        
        FOR R% = 0 TO maxR% STEP 6
          thetaStep% = INT(48*(1-R%/maxR%)) + 1
          FOR theta% = 0 TO 359 STEP thetaStep%
            X% = (WinW% - bSize%)DIV2 + R%*SINRAD(theta%)
            Y% = (WinH% - bSize%)DIV2 + R%*COSRAD(theta%)
            SYS GFXLIB_RevealBackgroundWithSoftBrush%, d{}, bm2%, bm1%, 640, 512, brush8%, bSize%, bSize%, X%, Y%
          NEXT theta%
          SYS GFXLIB_BPlot%, d{}, bm1%, 640, 512, 0, 0
          PROC_drawRing
          PROCdisplay
        NEXT R%
        
        SYS GFXLIB_DWORDCopy%, bm1_copy%, bm1%, 640*512
        
        FOR R% = maxR% TO 0 STEP -6
          thetaStep% = INT(48*(1-R%/maxR%)) + 1
          FOR theta% = 0 TO 359 STEP thetaStep%
            X% = (WinW% - bSize%)DIV2 + R%*SINRAD(theta%)
            Y% = (WinH% - bSize%)DIV2 + R%*COSRAD(theta%)
            SYS GFXLIB_RevealBackgroundWithSoftBrush%, d{}, bm1%, bm2%, 640, 512, brush8%, bSize%, bSize%, X%, Y%
          NEXT theta%
          SYS GFXLIB_BPlot%, d{}, bm2%, 640, 512, 0, 0
          PROC_drawRing
          PROCdisplay
        NEXT R%
        
        SYS GFXLIB_DWORDCopy%, bm2_copy%, bm2%, 640*512
        
      UNTIL FALSE
      END
      :
      :
      :
      :
      DEF PROC_drawRing
      LOCAL I%, T%, X%, Y%
      PRIVATE i
      FOR I% = 0 TO 11
        X% = (WinW% - 64)/2 + 220*SINRAD(I% * 360/12 + i)
        Y% = (WinH% - 64)/2 + 220*COSRAD(I% * 360/12 + i)
        SYS GFXLIB_PlotShapeHalfIntensity%, d{}, ball%, 64, 64, X%-8, Y%-9
        SYS GFXLIB_PlotAvg%, d{}, ball%, 64, 64, X%, Y%
      NEXT I%
      i += 1
      IF i >= 360 THEN i = 0
      ENDPROC
      :
      :
      :
      :
      DEF PROCfixWindowSize
      LOCAL GWL_STYLE, WS_THICKFRAME, WS_MAXIMIZEBOX, ws%
      GWL_STYLE = -16
      WS_THICKFRAME = &40000
      WS_MAXIMIZEBOX = &10000
      SYS "GetWindowLong", @hwnd%, GWL_STYLE TO ws%
      SYS "SetWindowLong", @hwnd%, GWL_STYLE, ws% AND NOT (WS_THICKFRAME+WS_MAXIMIZEBOX)
      ENDPROC
      :
      :
      :
      :
      DEF PROCerror( msg$, L% )
      OSCLI "REFRESH ON" : ON
      COLOUR 1, &FF, &FF, &FF
      COLOUR 1
      PRINT TAB(1,1)msg$;
      IF L% THEN
        PRINT " at line "; ERL;
      ENDIF
      VDU 7
      REPEAT UNTIL INKEY(1)=0
      ENDPROC