;; ----------------------------------------------------------------------------
;; Irrlicht Wrapper For Imperative Languages - Purebasic Examples
;; IrrlichtWrapper and FreeBasic-Example by Frank Dodd (2006)
;; Improved IrrlichtWrapper and PureBasicExample by Michael Taupitz 
;; ----------------------------------------------------------------------------
;; Example 35 : SpecialFX
;; This Example is converted from the original Irrlicht-Examples.
;; ----------------------------------------------------------------------------

EnableExplicit 

;; ////////////////////////////////////////////////////////////////////////////
;; Include the Irr3D-Requester
XIncludeFile "Irr3DRequester.pb"

;; ////////////////////////////////////////////////////////////////////////////
;; Global variables
Define *OurCamera.irr_camera
Define *roomMesh.irr_mesh
Define *roomStaticMesh.irr_mesh
Define *roomSceneNode.irr_node
Define *waterMesh.irr_mesh
Define *waterStaticMesh.irr_mesh
Define *waterSceneNode.irr_node
Define *roomTexture.irr_texture
Define *waterTexture.irr_texture
Define *stoneTexture.irr_texture
Define *billboardTexture.irr_texture
Define *billboardSceneNode.irr_node

Define *dwarfMesh.irr_mesh
Define *dwarfSceneNode.irr_node 

Define *fireTexture.irr_texture
Define *fireSceneNode.irr_node
Define particleEmitter.IRR_PARTICLE_EMITTER

Define *light.irr_node


Define fps.l=0, lastFPS.l = 0

; -----------------------------------------------------------------------------
; To Start the Irrlicht-Device we use the Irr3DRequester, to make it more comfortable
; for the Users, and also easier to test different resolutions and devices.
If Irr3DRequester() 
    ; set the window caption
    IrrSetWindowCaption( "Example 35:SpecialFX" )
    *roomMesh = IrrGetMesh( "media\room.3ds");  
    *roomStaticMesh = IrrGetStaticFromMesh(*roomMesh,0)
    IrrMakePlanarTextureMapping(*roomStaticMesh,0.004)
    If *roomMesh
      *roomSceneNode = IrrAddMeshToScene(  *roomMesh )  
      *roomTexture   = IrrGetTexture("media/wall.jpg")
      IrrSetNodeMaterialTexture(*roomSceneNode, *roomTexture,0) 
      IrrSetNodeAllMaterialSpecularColor(*roomSceneNode,0,0,0,0)  
    EndIf
    
    
    ; Now, For the first special effect: Animated water. It works like this: the 
    ; WaterSurfaceSceneNode takes a mesh as input and makes
    ; It wave like a water surface. And if we let this scene node use a nice
    ; material like the #IRR_EMT_REFLECTION_2_LAYER, It looks really cool. we are
    ; doing this with the next few lines of code. As input mesh, we create a hill
    ; plane mesh, without hills. But any other mesh could be used For this, you could
    ; even use the room.3ds (which would look really strange) If you wanted To.
  
    *stoneTexture = IrrGetTexture("media/stones.jpg");
    *waterTexture = IrrGetTexture("media/water.jpg");
  
    *billboardTexture = IrrGetTexture("media/particlewhite.bmp")
    *fireTexture = IrrGetTexture("media/fire.bmp")
  
  
    ; add Animated water 
    *waterMesh = IrrAddHillPlaneMesh("myHill",20,20,40,40, 10, 10,0,00);
    *waterStaticMesh = IrrGetStaticFromMesh(*waterMesh,0) 
    *waterSceneNode = IrrAddWaterSceneNode(*waterStaticMesh,3.0,300.0,30.0)
    IrrSetNodePosition(*waterSceneNode,0,7,0)
     
    IrrSetNodeMaterialTexture(*waterSceneNode,*stoneTexture,0)
    IrrSetNodeMaterialTexture(*waterSceneNode,*waterTexture,1)
    IrrSetNodeMaterialType(*waterSceneNode,#IRR_EMT_REFLECTION_2_LAYER);
   
  
    ; The second special effect is very basic, i bet you saw it already in some
    ; Irrlicht Engine demos: A transparent billboard combined With A dynamic light.
    ; We simply create A light scene node, let it fly around, an To make it look
    ; more cool, We attach A billboard scene node To it.
    
    ;create light 
    *light  = IrrAddLight(0,0,0, 0.6,0.7,1.0,600.0) 
    IrrAddFlyCircleAnimator(*light,0,150,0, 250,0.001) 
    
    ;create a Billboard
    *billboardSceneNode = IrrAddBillBoardToScene(50,50,0,0,0)
    IrrSetNodeMaterialTexture(*billboardSceneNode,*billboardTexture,0)
    IrrSetNodeMaterialFlag(*billboardSceneNode, #IRR_EMF_LIGHTING,#False)
    IrrSetNodeMaterialType(*billboardSceneNode, #IRR_EMT_TRANSPARENT_ADD_COLOR)
    
    ; attach billboard To light 
    IrrAddChildToParent(*billboardSceneNode,*light)
   
  
    ; The Next special effect is a lot more interesting: a particle system. The particle
    ; system in The Irrlicht Engine is Quit modular and extensible and yet easy to use.
    ; There is a particle system scene node into which you can put particle emitters, which
    ; make particles come out of nothing. These emitters are quite flexible And usually have
    ; lots of parameters like direction, amount and color of the particles they should create.
    ; These parameters are stored in a Structure, from that the Emitter is created.
    ; There are different emitters, For example a point emitter which lets particles pop out
    ; at a fixed point. If The particle emitters available in the Engine are not enough 
    ; In this example we create a box particle emitter, which creates particles randomly
    ; inside a box. The parameters define the box, direction of the particles, minimal and
    ; maximal new particles per second, color and minimal and maximal livetime of the particles.
    ; 
    ; Because only with emitters particle system would be a little bit boring,
    ; There are particle affectors, which modify particles during they fly around. they can
    ; be added to The particle system, simulating additional effects like gravity Or wind.
    ; The particle affector we use in this example is an affector, which modifies The color
    ; of the particles: it lets them fade out. 
    ; 
    ; After we set a nice material to the particle system, we have a cool looking camp fire.
    ; by adjusting material, texture, particle emitter and affector parameters, it is also
    ; easily possible To create smoke, rain, explosions, snow, And so on.
    ; 
    
    ; create a particle system
    ;
    ; add a particle system to the irrlicht scene manager, a default emitter is not
    ; created as we will define out own. the particle system is blank at the moment
    *fireSceneNode = IrrAddParticleSystemToScene( #False )
    
  
    ; when the particle system starts it creates objects similar to billboards,
    ; this command specifies how large each of those particles will be
    IrrSetParticleSize( *fireSceneNode, 20.0, 20.0 )
    
    IrrSetNodePosition(*fireSceneNode,-70,60,40)
    IrrSetNodeScale(*fireSceneNode,2,2,2)
   
    particleEmitter\min_box_x = -7
    particleEmitter\min_box_y = 0
    particleEmitter\min_box_z = -7
    particleEmitter\max_box_x = 7
    particleEmitter\max_box_y = 1
    particleEmitter\max_box_z = 7
    particleEmitter\direction_x = 0
    particleEmitter\direction_y = 0.06
    particleEmitter\direction_z = 0
    particleEmitter\min_paritlcles_per_second = 80
    particleEmitter\max_paritlcles_per_second = 100
    particleEmitter\min_start_color_red = 255
    particleEmitter\min_start_color_green = 255
    particleEmitter\min_start_color_blue = 255
    particleEmitter\max_start_color_red = 255
    particleEmitter\max_start_color_green = 255
    particleEmitter\max_start_color_blue = 255
    particleEmitter\min_lifetime = 800
    particleEmitter\max_lifetime = 2000
    particleEmitter\max_angle_degrees = 15    
    
    ; finally we add this particle emitting object to the particle system
    IrrAddParticleEmitter( *fireSceneNode, @particleEmitter )
     
    ; an affector is a mechanism that alters the particles over time, the fade out
    ; affector gradually fades the particles out so they are invisible when they
    ; are deleted this lets them smoothly vanish instead of poping out of existence
    IrrAddFadeOutParticleAffector( *fireSceneNode )
    
    IrrSetNodeMaterialFlag(*fireSceneNode ,#IRR_EMF_LIGHTING,#False)
    IrrSetNodeMaterialTexture(*fireSceneNode,*fireTexture,0)
    IrrSetNodeMaterialType(*fireSceneNode, #IRR_EMT_TRANSPARENT_VERTEX_ALPHA)
     
    ; As our last special effect, we want a dynamic shadow be casted from an animated
    ; character. For this we load a DirectX .X model And place it into our world.
    ; For creating the shadow, we simply need To call IrrAddNodeShadow().
    ; the color of Shadows is only adjustable globally For all Shadows, by calling
    ; IrrSetShadowColor(). Voila, here is our dynamic shadow.
    ; 
    ; Because the character is a little bit too small For this scene, we make it bigger
    ; using IrrSetScale(). And Because the character is lighted by a dynamic light, we need
    ; To normalize the normals To make the lighting on it correct. this is always necessary If
    ; the scale of a dynamic lighted model is Not (1,1,1). Otherwise it would get too dark Or
    ; too bright Because the normals will be scaled too.
    ; */
    ; 
    ; // add animated character

    *dwarfMesh = IrrGetMesh("media/dwarf.x")
    *dwarfSceneNode =  IrrAddMeshToScene( *dwarfMesh)
    IrrSetNodePosition(*dwarfSceneNode,-50,20,-60)
    
    ; set Animation-Speed
    IrrSetNodeAnimationSpeed(*dwarfSceneNode,15)
    
    ; // add shadow
    IrrAddNodeShadow(*dwarfSceneNode)
    IrrSetShadowColor(150,0,0,0)
    
    
    ; make the model a little bit bigger And normalize its normals
    ; Because of this For correct lighting
    
    IrrSetNodeScale(*dwarfSceneNode,2,2,2)
    IrrSetNodeMaterialFlag(*dwarfSceneNode,#IRR_EMF_NORMALIZE_NORMALS, #True)
    
    ; Finally we simply have To draw everything, that's all.
    
    *OurCamera = IrrAddFPSCamera()
    IrrSetNodePosition(*OurCamera,-50,50,-150)
    
    ; disable mouse cursor
    IrrHideMouse() 
    
    ; -----------------------------------------------------------------------------
    ; while the irrlicht environment is still running
    While IrrRunning()
      ; begin the scene, erasing the canvas with sky-blue before rendering
      IrrBeginScene( 0,0,0 )
      
      ; draw the scene to the render buffer
      IrrDrawScene()
      
      ; end drawing the scene and render it
      IrrEndScene()
      
      fps = IrrGetFPS()
      If fps <> lastFPS 
        IrrSetWindowCaption("IrrlichtWrappper - SpecialFX example FPS:" + Str(fps) )
        lastFPS = fps;
      EndIf
      
      
    Wend
    
    ; -----------------------------------------------------------------------------
    ; Stop the irrlicht engine and release resources
    IrrStop()
  EndIf


End

; jaPBe Version=3.7.2.629
; Build=0
; Language=0x0000 Language Neutral
; FirstLine=193
; CursorPosition=213
; ExecutableFormat=Windows
; DontSaveDeclare
; EOF