BBC BASIC for Windows
Programming >> Graphics and Games >> Zooming image in 3D
http://bb4w.conforums.com/index.cgi?board=graphics&action=display&num=1430066238

Zooming image in 3D
Post by David Williams on Apr 26th, 2015, 4:37pm

(Well, sort of 3D.)

http://www.proggies.uk/bb4w/zoomimg3d.zip

The program's actually a 'prototype' for a RISC OS program, but I prefer to develop initially in BB4W because the RISC OS environment is, shall we say, a little delicate. And sometimes a real PIA.

Largely indecipherable program listed below for the interested few (uncommented - sorry). If anyone seriously wants a tidied-up/commented version then ask.


Image source:

http://www.hivestock.com/photo.php?id=2401190&environ=2&q=woman


David.
--

Code:
      *ESC OFF
      *FLOAT 64
      HIMEM = PAGE + 2*&100000

      ScrW% = 480
      ScrH% = 480
      PROCFixWndSz
      VDU 23,22,ScrW%;ScrH%;8,16,16,0 : OFF

      INSTALL @lib$ + "GFXLIB2"
      PROCInitGFXLIB( d{}, 0 )
      D% = d{}

      INSTALL @lib$ + "GFXLIB_modules\BPlotScaleBlend"
      PROCInitModule(0)

      img% = FNLoadImg( @dir$ + "img2_480x480.bmp", 0 )

      srcSprW% = 480
      srcSprH% = 480

      cX% = ScrW% DIV 2
      cY% = ScrH% DIV 2

      DIM p(srcSprH%, 2), q(srcSprH%, 2), m(2,2), Y%( 512 )
      DIM bgCol{ r%, g%, b% }

      dZ% = 1300
      minZ% = srcSprH% + 1
      maxZ% = minZ% + dZ% + (dZ% DIV 2)
      scale% = 925

      FOR I% = 0 TO srcSprH%-1
        p(I%, 0) = srcSprW%/2
        p(I%, 1) = I% - srcSprH%/2
        p(I%, 2) = 0
      NEXT I%

      *REFRESH OFF

      REPEAT
        T% = TIME
        bgCol.r% = 128+127*SIN(T%/800)
        bgCol.g% = 128+127*SIN(T%/990 + 1.34)
        bgCol.b% = 128+127*SIN(T%/1006 - 0.85)
        SYS GFXLIB_Clr%, d{}, FNrgb(bgCol.r%, bgCol.g%, bgCol.b%)
  
        zo% = minZ% + dZ% + (dZ% DIV 2)*SIN(T%/60)*SIN(T%/200 + 1.85)
  
        angle = 4*PI*SIN(T%/400)*SIN(T%/600 + 1.7)
        sin = SIN(angle)
        cos = COS(angle)
        m() = 1,0,0, 0,cos,-sin, 0,sin,cos
        q() = p().m()
  
        Y%() = FALSE
  
        FOR I% = 0 TO srcSprH%-1
          z% = q(I%,2)
          z = scale%/(z% + zo%)
          dx% = q(I%,0)*z
          dy% = q(I%,1)*z
          x1% = cX% - dx%
          y1% = cY% + dy%
          x2% = cX% + dx%
          y2% = cY% + dy%
          blend% = 255*(1 - ((z%+zo%)/maxZ%)^2)
          IF NOT Y%(y1%) THEN
            SYS GFXLIB_BPlotScaleBlend%, D%, img% + 4*480*I%, 480, 1, x2%-x1%, 1, x1%, y1%, blend%
            Y%(y1%) = TRUE
          ENDIF
        NEXT I%
  
        PROCdisplay
      UNTIL FALSE
      END

      DEF PROCFixWndSz
      LOCAL W%
      SYS"GetWindowLong",@hwnd%,-16 TO W%
      SYS"SetWindowLong",@hwnd%,-16,W% ANDNOT&40000 ANDNOT&10000
      ENDPROC
 


Re: Zooming image in 3D
Post by David Williams on May 1st, 2015, 6:43pm

A bitmap rotating in 3D (about all three Cartesian axes):

http://www.proggies.uk/bb4w/rotzoom3d_bb4W.zip (EXE; 275 Kb)

The code is BASIC, uses GFXLIB.

It's a more-or-less direct port of the ARM BBC BASIC version which runs at 60 fps on the Raspberry Pi 2, using nothing more than RISC OS's famously slow SpriteOp routines (however, that version lacks the distance-dependent opacity changes of the BB4W version).

David.
--

Image source: Flickr (creative commons w/ permission to modify)
https://farm2.staticflickr.com/1315/4601782906_fcf1e39bc7_s.jpg
Re: Zooming image in 3D
Post by David Williams on May 1st, 2015, 10:01pm

The previous version wasn't quite real-time (it used pre-rotated images - hence the eye-watering memory usage), but this version linked-to below is 100% real-time, and still runs at 60 fps on my laptop.

http://www.proggies.uk/bb4w/RotZoom3D_BB4W_ii.zip [EXE; 292 Kb]


David.
--
Re: Zooming image in 3D
Post by David Williams on Dec 1st, 2015, 4:47pm

Here's a different (and rather impractical) approach to what is essentially 'fake texture mapping'.
A 64x64 grid of coloured squares is rotated in 3D. I only wrote this (initially on the Raspberry Pi) to see how slow it is.

Frame rates? On my laptop, drawing 4096 individually coloured quadrilaterals per frame::



http://www.proggies.uk/bb4w/face64.zip (includes EXE's and source)

Raspberry Pi version: http://www.proggies.uk/riscos/arc/face64 (Set to file type &3FB and use !SparkFS to open)


EDIT: A variation!
http://www.proggies.uk/bb4w/face64_2.zip


Of course, to do it the sensible way you should use something like D3DLIB!

Previous BB4W efforts in a similar vein, using different methods (but none of them perform real texture mapping):

http://www.proggies.uk/bb4w/zoomimg3d.zip
http://www.proggies.uk/bb4w/rotzoom3d_bb4W.zip
http://www.proggies.uk/bb4w/RotZoom3D_BB4W_ii.zip


Finally, I rediscovered an early attempt at a 3D maze (this uses the graphics hardware to do real texture mapping, very fast):

http://www.proggies.uk/bb4w/3dmazedemo2.zip

(Use the arrow keys to move)


David.
--