Author |
Topic: Direct3D Rotating Globe (Read 1412 times) |
|
admin
Administrator
member is offline


Posts: 1145
|
 |
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:
 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 » |
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
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 » |
Logged
|
|
|
|
|