BBC BASIC for Windows
Programming >> Graphics and Games >> GFXLIB2 and Graphics Viewport
http://bb4w.conforums.com/index.cgi?board=graphics&action=display&num=1348502570

GFXLIB2 and Graphics Viewport
Post by bobgidden on Sep 24th, 2012, 4:02pm

I have a routine which uses PlotRotate to show a portion of a compass card in a window. I need this for a simulator. But when I define a graphics viewport (to use Richard's term) as a subset of the window, with the rest of the window showing other things, the rotate splurges all over (and is garbled); ie it doesn't seem to respect my viewport definition. I have searched the forum and documentation but can't locate any info. Could someone please point me at what I am doing wrong, or omitting? TIA.

Bob Gidden

Re: GFXLIB2 and Graphics Viewport
Post by admin on Sep 24th, 2012, 9:33pm

on Sep 24th, 2012, 4:02pm, bobgidden wrote:
Could someone please point me at what I am doing wrong, or omitting?

I expect David Williams will give you the answer from a GFXLIB2 perspective, but an alternative method might be to use the PlgBlt (parallelogram blit) API to do the rotation, which will respect the graphics viewport. The code listed below demonstrates that method (if you're not running Windows XP you will need to substitute an alternative image).

Richard.

Code:
      VDU 23,22,640;480;8,16,16,128
      VDU 24,400;300;600;700; : REM Set graphics viewport
      
      LR_LOADFROMFILE = 16
      image$ = "C:\windows\coffee bean.bmp"
      SYS "LoadImage", 0, image$, 0, 0, 0, LR_LOADFROMFILE TO himg%
      IF himg%=0 ERROR 100, "Cannot load image " + image$
      angle = 0
      REPEAT
        PROCDrawImageRot(himg%, 200, 180, 128, 128, angle)
        angle += PI/90
        WAIT 4
      UNTIL FALSE
      END
      
      REM Draw a rotated image
      DEF PROCDrawImageRot(himage%,x%,y%,dx%,dy%,angle)
      LOCAL hdctemp%,diag%,bmp{},plg{},rc{},ca,sa
      DIM bmp{Type%,Width%,Height%,WidthBytes%,Planes{l&,h&},BitsPixel{l&,h&},Bits%}
      DIM plg{x1%,y1%,x2%,y2%,x3%,y3%}, rc{l%,t%,r%,b%}
      diag%=SQR(dx%^2+dy%^2)+1 : ca=COS(angle) : sa=SIN(angle)
      plg.x1%=x%+diag%/2-dx%/2*ca-dy%/2*sa
      plg.y1%=y%+diag%/2-dy%/2*ca+dx%/2*sa
      plg.x2%=x%+diag%/2+dx%/2*ca-dy%/2*sa
      plg.y2%=y%+diag%/2-dy%/2*ca-dx%/2*sa
      plg.x3%=x%+diag%/2-dx%/2*ca+dy%/2*sa
      plg.y3%=y%+diag%/2+dy%/2*ca+dx%/2*sa
      rc.l% = x% : rc.t% = y% : rc.r% = x%+diag% : rc.b% = y%+diag%
      SYS "CreateCompatibleDC", @memhdc% TO hdctemp%
      SYS "SelectObject", hdctemp%, himage%
      SYS "GetObject", himage%, DIM(bmp{}), bmp{}
      SYS "SelectClipRgn", @memhdc%, @vdu.hr%
      SYS "PatBlt", @memhdc%, x%, y%, diag%, diag%, &FF0062
      SYS "PlgBlt", @memhdc%, plg{}, hdctemp%, 0, 0, bmp.Width%, bmp.Height%, 0, 0, 0
      SYS "InvalidateRect", @hwnd%, rc{}, 0
      SYS "DeleteDC", hdctemp%
      ENDPROC 

Re: GFXLIB2 and Graphics Viewport
Post by David Williams on Sep 25th, 2012, 06:34am

GFXLIB doesn't support viewports, but you may be able to use a workaround like the one demonstrated in the example code below (Copy, Paste, and Run):

Code:
      MODE 8
      OFF
      
      INSTALL @lib$ + "GFXLIB2"
      PROCInitGFXLIB
      
      INSTALL @lib$ + "GFXLIB_modules\PlotRotateScale2"
      PROCInitModule
      
      gfxlib% = FNLoadImg( @lib$ + "GFXLIB_media\gfxlib_480x128x8.BMP", 0 )
      
      ball% = FNLoadImg( @lib$ + "GFXLIB_media\ball1_64x64x8.BMP", 0 )
      
      bmW% = 200
      bmH% = 120
      bm% = FNmalloc( 4 * bmW% * bmH% )
      
      bmW2% = 280
      bmH2% = 190
      bm2% = FNmalloc( 4 * bmW2% * bmH2% )
      
      angle = 0.0
      scale = 1.0
      
      *REFRESH OFF
      
      REPEAT
        
        SYS GFXLIB_Clr%, dispVars{}, FNrgb( 0, 20, 60 )
        
        R% = RND( -12345678 )
        FOR I% = 1 TO 50
          SYS GFXLIB_Plot%, dispVars{}, ball%, 64, 64, RND(640)-32, RND(512)-32
        NEXT I%
        
        SYS GFXLIB_Plot%, dispVars{}, gfxlib%, 480, 128, (640-480)/2, 32
        
        SYS GFXLIB_SaveAndSetDispVars%, dispVars{}, bm%, bmW%, bmH%
        SYS GFXLIB_Clr%, dispVars{}, FNrgb( 0, 0, 0 )
        SYS GFXLIB_PlotRotateScale2%, dispVars{}, gfxlib%, 480, 128, \
        \ bmW%/2, bmH%/2, &10000*angle, &10000*scale
        SYS GFXLIB_RestoreDispVars%, dispVars{}
        SYS GFXLIB_Plot%, dispVars{}, bm%, bmW%, bmH%, 60, 270
        
        SYS GFXLIB_SaveAndSetDispVars%, dispVars{}, bm2%, bmW2%, bmH2%
        SYS GFXLIB_Clr%, dispVars{}, FNrgb( 0, 0, 0 )
        SYS GFXLIB_PlotRotateScale2%, dispVars{}, gfxlib%, 480, 128, \
        \ bmW2%/2, bmH2%/2, &10000*(-angle), &10000*scale
        SYS GFXLIB_RestoreDispVars%, dispVars{}
        SYS GFXLIB_BPlot%, dispVars{}, bm2%, bmW2%, bmH2%, 320, 270
        
        angle += 1
        IF angle >= 360 THEN angle -= 360
        
        PROCdisplay
        
      UNTIL FALSE
 



Regards,

David.

Re: GFXLIB2 and Graphics Viewport
Post by bobgidden on Sep 25th, 2012, 9:00pm

Thank you both for your rapid and helpful replies - purely because Richard was first off the mark, I tried his code with my own bitmap, and it worked fine under Windows 7. The root of my problem was my new laptop, which refuses to accept Direct3D, so my program, which worked fine on my earlier PC, stopped dead, and I was forced to a re-write.

I have been using BBC Basic since the first BBC Micro (having driven up to Northamptonshire, I think, to take delivery), and I have been delighted to have BB4W available now.

Best regards,
Bob Gidden.