;; ----------------------------------------------------------------------------
;; Irrlicht Wrapper for Imperative Languages - Freebasic Examples
;; Frank Dodd (2006)
;; ----------------------------------------------------------------------------
;; Blitz-Irrlicht 1.8.3 Interface by Ed Musolino (AquaLung 2015)
;; ----------------------------------------------------------------------------
;; Example 99: XEffects Dynamic Shadows Variance Shadow Maps
;; This example demonstrates the use of the XEffects module to display VSM
;; dynamic shadows.
;;
;; VSM (Variance Shadow Maps) are a shadow mapping technique like the origonal
;; shadow maps in example 99. But they can have filtering applied to them to
;; smooth out the aliasing problems that can affect the previous shadow map
;; technique. Although VSM produces higher quality shadows it does require more
;; memory and computation time.
;; ----------------------------------------------------------------------------

;; ////////////////////////////////////////////////////////////////////////////
;; Includes for extension libraries
Include "../_libs/bIrrlicht.bb"

;; ////////////////////////////////////////////////////////////////////////////
;; global variables

; irrlicht objects
Global RoomMesh%
Global MeshTexture%
Global SceneNode%
Global OurCamera%


;; ////////////////////////////////////////////////////////////////////////////
; start the irrlicht interface
iVSync( True )
iIrr3D( 800, 600, 32, False )

; Start the XEffects shader system switch on VSM, Soft Shadowing and also 32 bit
; buffers. These are highly recommended for VSM
iXFXStart( True, True, True )

; set the window caption
iAppTitle( "Example 99: XEffects Dynamic Shadows Variance Shadow Maps" )

; load a mesh this acts as a blue print for the model
SceneNode = iLoadAnimMesh( "./media/temple.obj", False )

; load texture resources for texturing the scene nodes
MeshTexture = iLoadTexture( "./media/temple_lightmap.jpg" )

; add the mesh to the scene as a new node, the node is an instance of the
; mesh object supplied here
;SceneNode = iAddMeshToScene( RoomMesh )

; scale the node up a little (this will not effect this shaders lighting)
iScaleNode( SceneNode, 14.0, 14.0, 14.0 )

; add dynamic shadows to this node
iXFXAddShadowToNode( SceneNode, EFT_8PCF, ESM_BOTH )

; apply a material to the node to give its surface color
iNodeTexture( SceneNode, MeshTexture, 0 )

; switch off lighting effects on this model, as there are no lights in this
; scene the model would otherwise render pule black
iNodeMaterialFlag( SceneNode, IRR_EMF_LIGHTING, False )

; add a dynamic shadow casting light
; 1) the size of the shadow map texure this should always be a power of two.
;    512, 1024, 2048, etc ... bigger numbers = more quality = more memory
; 2) three numbers specify the X,Y,Z position of the light
; 3) three numbers specify the X,Y,Z target of the light. a dynamic light is
;    shaped like a spotlight so it needs a target to shine at.
; 4) four numbers specify the R,G,B,A intensity of the light
; 5) two numbers specify the near and far distance of the effect of the light
; 6) the angle of the spotlight 90 degrees in this case
iXFXAddShadowLight ( 512, 200,200,0, 0,0,0, 0.9,0.9,0.6,0.0, 1.0, 1200.0, 89.99 )

; set the ambient lighting applied by the XEffects system
iXFXSetAmbientColor( 0,128,128,128)


; add a camera into the scene, the first co-ordinates represents the 3D
; location of our view point into the scene the second co-ordinates specify the
; target point that the camera is looking at
OurCamera = iCreateFPSCamera( 0, 100.0, 0.1,-1,0,0,0,0.0 )
iPositionNode( OurCamera, 150,80,100 )
iCameraTarget( OurCamera, 0,0,0 )

; hide the mouse
iHideMouse()

; -----------------------------------------------------------------------------
moveCircle# = 0.0

; while the irrlicht environment is still running
While iRun() And (Not iKeyHit( KEY_ESCAPE ))

        ; begin the scene
        iBeginScene()

        ; move the light about to show the dynamic lighting effect
        iXFXSetShadowLightPosition( 0, 200, (Cos( moveCircle ) + 1) * 75 + 50, (Sin( moveCircle ) + 1 ) * 75 + 50 )
        moveCircle = moveCircle + 2.0

        ; draw the scene
        iDrawScene()
        
        ; end drawing the scene and render it
        iEndScene()

Wend 

; -----------------------------------------------------------------------------
; Stop the irrlicht engine and release resources
iEndIrr3D()


End