Home Page

R. T. RUSSELL

BBC BASIC for Windows

Direct3D lighting demo



This program displays a 'tumbling' gold pyramid, lit from the front by a single point-source light, to demonstrate the capabilities of the Direct3D lighting engine and the ease with which it can be used from BBC BASIC for Windows. It requires DirectX™ 9.0 or later to be installed on your PC. Updated to include specular reflections.

Download LIGHTING.BBC Run LIGHTING.EXE

     REM. Program to demonstrate lighting and specular reflection

     
MODE 8
     INSTALL @lib$+"D3D9LIBA"

     ON CLOSE PROCcleanup : QUIT
     ON ERROR PROC
cleanup : SYS "MessageBox", @hwnd%, REPORT$, 0, 48 : QUIT
     ON MOVE IF
@msg% <> 5 RETURN ELSE PROCcleanup : CLEAR
     VDU
20,26,12

     DIM pVB%(0), nv%(0), vf%(0), vl%(0), l%(0), m%(0), t%(0), y(0), p(0), r(0)
     DIM X(0), Y(0), Z(0), eye(2), at(2), n(2)

     REM. Initialise Direct3D:
     
pDevice% = FN_initd3d(@hwnd%, 2, 1)
     IF pDevice% = 0 ERROR 100, "Couldn't initialise Direct3D"
     SYS !(!pDevice%+228), pDevice%, 29, 1 : REM D3DRS_SPECULARENABLE

     REM. Create 3D object with surface normals:
     
F% = OPENOUT(@tmp$+"lighting.fvf")
     BPUT #F%,18 : BPUT#F%,0 : BPUT #F%,0 : BPUT#F%,0   : REM number of vertices
     
BPUT #F%,&12 : BPUT #F%,0 : BPUT#F%,24 : BPUT#F%,0 : REM vertex format and size
     
FOR V% = 0 TO 5
       READ x1, y1, z1, x2, y2, z2, x3, y3, z3
       a = x2 - x3
       b = y2 - y3
       c = z2 - z3
       d = x1 - x3
       e = y1 - y3
       f = z1 - z3
       n(0) = b*f-c*e
       n(1) = c*d-a*f
       n(2) = a*e-b*d
       n() /= MOD(n())
       PROC4(F%,x1) : PROC4(F%,y1) : PROC4(F%,z1)       : REM xyz coordinates
       
PROC4(F%,n(0)) : PROC4(F%,n(1)) : PROC4(F%,n(2)) : REM surface normal
       
PROC4(F%,x2) : PROC4(F%,y2) : PROC4(F%,z2)       : REM xyz coordinates
       
PROC4(F%,n(0)) : PROC4(F%,n(1)) : PROC4(F%,n(2)) : REM surface normal
       
PROC4(F%,x3) : PROC4(F%,y3) : PROC4(F%,z3)       : REM xyz coordinates
       
PROC4(F%,n(0)) : PROC4(F%,n(1)) : PROC4(F%,n(2)) : REM surface normal
     
NEXT
     CLOSE
#F%

     REM. Load 3D object:
     
pVB%(0) = FN_load3d(pDevice%, @tmp$+"lighting.fvf", nv%(0), vf%(0), vl%(0))
     IF pVB%(0) = 0 ERROR 101, "Couldn't load 'lighting.fvf'"

     REM. Point-source light:
     
DIM light{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%}

     light.Type% = 1              : REM. point source
     
light.Diffuse.r% = FN_f4(1)  : REM. diffuse colour RGB
     
light.Diffuse.g% = FN_f4(1)
     light.Diffuse.b% = FN_f4(1)
     light.Specular.r% = FN_f4(1) : REM. specular colour RGB
     
light.Specular.g% = FN_f4(1)
     light.Specular.b% = FN_f4(1)
     light.Position.x% = FN_f4(0) : REM. position XYZ
     
light.Position.y% = FN_f4(0)
     light.Position.z% = FN_f4(-4)
     light.Range% = FN_f4(10)     : REM. range
     
light.Attenuation0% = FN_f4(1) : REM. attenuation (constant)
     
l%(0) = light{}

     REM. Gold-coloured material:
     
DIM material{Diffuse{r%,g%,b%,a%}, Ambient{r%,g%,b%,a%}, \
     
\   Specular{r%,g%,b%,a%}, Emissive{r%,g%,b%,a%}, Power%}

     material.Diffuse.r% = FN_f4(1)  : REM. diffuse colour RGB
     
material.Diffuse.g% = FN_f4(0.7)
     material.Diffuse.b% = FN_f4(0)
     material.Specular.r% = FN_f4(1) : REM. specular colour RGB
     
material.Specular.g% = FN_f4(1)
     material.Specular.b% = FN_f4(1)
     material.Power% = FN_f4(20): REM. specular 'power'
     
m%(0) = material{}

     REM. Render the tumbling object:
     
eye() = 0, 0, -9
     at() = 0, 0, 0
     REPEAT
       
y() = TIME/200
       r() = TIME/80
       PROC_render(pDevice%, &7F7F7F, 1, l%(), 1, m%(), t%(), pVB%(), nv%(), vf%(), vl%(), \
       
\ y(), p(), r(), X(), Y(), Z(), eye(), at(), PI/6, @vdu%!208/@vdu%!212, 1, 1000, 0)
     UNTIL INKEY(1)=0
     END

     
DEF PROCcleanup
     pVB%(0) += 0  : IF pVB%(0)  PROC_release(pVB%(0))
     pDevice% += 0 : IF pDevice% PROC_release(pDevice%)
     *REFRESH ON
     ENDPROC

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

     
REM. Pyramid (6 triangles each with three vertices):
     
DATA -1, -1,  1, -1, -1, -1,  0, .414,  0
     DATA  1, -1,  1, -1, -1,  1,  0, .414,  0
     DATA  1, -1, -1,  1, -1,  1,  0, .414,  0
     DATA -1, -1, -1,  1, -1, -1,  0, .414,  0
     DATA  1, -1, -1, -1, -1, -1, -1,   -1,  1
     DATA -1, -1,  1,  1, -1,  1,  1,   -1, -1


Home - Products - Contact us

Best viewed with Any Browser Valid HTML 3.2!
© Richard Russell 2009