BBC BASIC for Windows
« Direct3D Rotating Globe »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 11:10pm



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: Direct3D Rotating Globe  (Read 1412 times)
admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Direct3D Rotating Globe
« Thread started on: Nov 9th, 2013, 1:12pm »

I was requested to do this by the Liberty BASIC folks, so it's only fair to do a BBC BASIC version too (it's much simpler, because it can call upon the D3DLIB library). You will need to download bbcworld.zip which contains the image world.jpg and the data file sphere.b3d used by the program:

User Image

Code:
      REM. Direct3D Rotating Globe in BBC BASIC for Windows
      REM (C) R.T.Russell 2013, http://www.rtrussell.co.uk/

      MODE 8
      DIM l%(0), b%(0), n%(0), f%(0), s%(0), m%(0), t%(0), y(0), p(0), r(0), X(0), Y(0), Z(0), e(2), a(2)

      INSTALL @lib$+"D3DLIB"

      ON CLOSE PROCcleanup:QUIT
      ON ERROR PROCcleanup:PRINT REPORT$:END

      d% = FN_initd3d(@hwnd%, 1, 0)
      IF d% = 0 ERROR 100, "Can't initialise Direct3D"

      b%(0) = FN_load3d(d%, @dir$+"SPHERE.B3D", n%(0), f%(0), s%(0))
      IF b%(0) = 0 ERROR 100, "Can't load SPHERE.B3D"

      t%(0) = FN_loadtexture(d%, @dir$+"WORLD.JPG")
      IF t%(0) = 0 ERROR 100, "Can't load WORLD.JPG"

      e() = 0, 0, -9
      a() = 0, 0, 0
      REPEAT
        y() = -TIME/200
        PROC_render(d%, &FF000040, 0, l%(), 1, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), 0.4, 5/4, 1, 1000)
      UNTIL INKEY(1)=0
      END

      DEF PROCcleanup
      b%(0) += 0:IF b%(0) PROC_release(b%(0))
      d% += 0   :IF d%    PROC_release(d%)
      ENDPROC 

Richard.
« Last Edit: Nov 9th, 2013, 3:36pm by admin » User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: Direct3D Rotating Globe
« Reply #1 on: Nov 10th, 2013, 2:44pm »

Adding a directional light, and tilting the earth's axis of rotation, gives a more interesting (and accurate) result. To ensure the 'terminator' (transition from light to shadow) is acceptably smooth I have increased the number of triangles from 512 to 2048:

Code:
      REM. Direct3D Rotating Globe in BBC BASIC for Windows
      REM (C) R.T.Russell 2013, http://www.rtrussell.co.uk/

      MODE 8 : OFF
      DIM l%(0), b%(0), n%(0), f%(0), s%(0), m%(0), t%(0), y(0), p(0), r(0), X(0), Y(0), Z(0), e(2), a(2)

      INSTALL @lib$+"D3DLIB"

      ON CLOSE PROCcleanup:QUIT
      ON ERROR PROCcleanup:PRINT REPORT$:END

      d% = FN_initd3d(@hwnd%, 1, 1)
      IF d% = 0 ERROR 100, "Can't initialise Direct3D"

      file% = OPENOUT(@tmp$+"SPHERE.B3D")
      PROC4(file%, 6144) : REM vertex count
      PROC4(file%, &00240152) : REM vertex format and size
      PROCtriangulate(5, file%,  1,  0,  0,   0,  0,  1,   0,  1,  0)
      PROCtriangulate(5, file%,  0,  1,  0,   0,  0,  1,  -1,  0,  0)
      PROCtriangulate(5, file%, -1,  0,  0,   0,  0,  1,   0, -1,  0)
      PROCtriangulate(5, file%,  0, -1,  0,   0,  0,  1,   1,  0,  0)
      PROCtriangulate(5, file%,  1,  0,  0,   0,  1,  0,   0,  0, -1)
      PROCtriangulate(5, file%,  0,  1,  0,  -1,  0,  0,   0,  0, -1)
      PROCtriangulate(5, file%, -1,  0,  0,   0, -1,  0,   0,  0, -1)
      PROCtriangulate(5, file%,  0, -1,  0,   1,  0,  0,   0,  0, -1)
      CLOSE #file%

      b%(0) = FN_load3d(d%, @tmp$+"SPHERE.B3D", n%(0), f%(0), s%(0))
      IF b%(0) = 0 ERROR 100, "Can't load SPHERE.B3D"

      t%(0) = FN_loadtexture(d%, @dir$+"WORLD.JPG")
      IF t%(0) = 0 ERROR 100, "Can't load WORLD.JPG"

      DIM D3Dlight8{Type%, Diffuse{r%,g%,b%,a%}, Specular{r%,g%,b%,a%}, \
      \ Ambient{r%,g%,b%,a%}, Position{x%,y%,z%}, Direction{x%,y%,z%}, \
      \ Range%, Falloff%, Attenuation0%, Attenuation1%, Attenuation2%, \
      \ Theta%, Phi% }
      D3Dlight8.Type% = 1 : REM point source
      D3Dlight8.Diffuse.r% = FN_f4(1)
      D3Dlight8.Diffuse.g% = FN_f4(1)
      D3Dlight8.Diffuse.b% = FN_f4(1)
      D3Dlight8.Position.x% = FN_f4(-20)
      D3Dlight8.Position.z% = FN_f4(-20)
      D3Dlight8.Range% = FN_f4(200)
      D3Dlight8.Attenuation0% = FN_f4(0.2)
      l%(0) = D3Dlight8{}

      e() = 0, 0, -9
      a() = 0, 0, 0
      REPEAT
        y() = -TIME/200
        r() = -0.4 * COS(y(0))
        p() = 0.4 * SIN(y(0))
        PROC_render(d%, &00000030, 1, l%(), 1, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), 0.4, 5/4, 1, 1000)
      UNTIL INKEY(1)=0
      END

      DEF PROCcleanup
      b%(0) += 0:IF b%(0) PROC_release(b%(0))
      d% += 0   :IF d%    PROC_release(d%)
      ENDPROC

      DEF PROCtriangulate(L%, F%, x0, y0, z0, x1, y1, z1, x2, y2, z2)
      L% -= 1
      IF L% THEN
        LOCAL a(), b(), c() : DIM a(2), b(2), c(2)
        a(0) = x0 + x2 : a(1) = y0 + y2 : a(2) = z0 + z2 : a() /= MOD(a())
        b(0) = x0 + x1 : b(1) = y0 + y1 : b(2) = z0 + z1 : b() /= MOD(b())
        c(0) = x1 + x2 : c(1) = y1 + y2 : c(2) = z1 + z2 : c() /= MOD(c())
        PROCtriangulate(L%, F%, x0, y0, z0, b(0), b(1), b(2), a(0), a(1), a(2))
        PROCtriangulate(L%, F%, b(0), b(1), b(2), x1, y1, z1, c(0), c(1), c(2))
        PROCtriangulate(L%, F%, a(0), a(1), a(2), b(0), b(1), b(2), c(0), c(1), c(2))
        PROCtriangulate(L%, F%, a(0), a(1), a(2), c(0), c(1), c(2), x2, y2, z2)
      ELSE
        LOCAL u0, u1, u2, v0, v1, v2
        PROCvertex(x0, y0, z0, u0, v0)
        PROCvertex(x1, y1, z1, u1, v1)
        PROCvertex(x2, y2, z2, u2, v2)
        IF (u1 - u0) > 0.5 u0 += 1.0
        IF (u0 - u1) > 0.5 u1 += 1.0
        IF (u2 - u1) > 0.5 u1 += 1.0
        IF (u1 - u2) > 0.5 u2 += 1.0
        IF (u0 - u2) > 0.5 u2 += 1.0
        IF (u2 - u0) > 0.5 u0 += 1.0
        PROC4(F%, FN_f4(-x0)) : PROC4(F%, FN_f4(z0)) : PROC4(F%, FN_f4(y0))
        PROC4(F%, FN_f4(-x0)) : PROC4(F%, FN_f4(z0)) : PROC4(F%, FN_f4(y0))
        PROC4(F%, &FFFFFF)    : PROC4(F%, FN_f4(u0)) : PROC4(F%, FN_f4(v0))
        PROC4(F%, FN_f4(-x1)) : PROC4(F%, FN_f4(z1)) : PROC4(F%, FN_f4(y1))
        PROC4(F%, FN_f4(-x1)) : PROC4(F%, FN_f4(z1)) : PROC4(F%, FN_f4(y1))
        PROC4(F%, &FFFFFF)    : PROC4(F%, FN_f4(u1)) : PROC4(F%, FN_f4(v1))
        PROC4(F%, FN_f4(-x2)) : PROC4(F%, FN_f4(z2)) : PROC4(F%, FN_f4(y2))
        PROC4(F%, FN_f4(-x2)) : PROC4(F%, FN_f4(z2)) : PROC4(F%, FN_f4(y2))
        PROC4(F%, &FFFFFF)    : PROC4(F%, FN_f4(u2)) : PROC4(F%, FN_f4(v2))
      ENDIF
      ENDPROC

      DEF PROCvertex(x, y, z, RETURN u, RETURN v)
      u = FNatan2(x, y) / PI / 2 + 0.5
      v = FNatan2(z, SQR(x^2 + y^2)) / PI + 0.5
      IF u < 0 OR v < 0 OR u > 1 OR v > 1 STOP
      ENDPROC

      DEF FNatan2(y,x) : ON ERROR LOCAL = SGN(y)*PI/2
      IF x>0 THEN = ATN(y/x) ELSE IF y>0 THEN = ATN(y/x)+PI ELSE = ATN(y/x)-PI

      DEF PROC4(F%, A%)
      BPUT#F%,A% : BPUT#F%,A%>>8 : BPUT#F%,A%>>16 : BPUT#F%,A%>>24
      ENDPROC 

Richard.
« Last Edit: Nov 10th, 2013, 2:50pm by admin » 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