'' ----------------------------------------------------------------------------
'' Irrlicht Wrapper For Imperative Languages - Freebasic Examples
'' Frank Dodd (2006)
'' ----------------------------------------------------------------------------
'' Blitz-Irrlicht 1.8.3 Interface by Ed Musolino (AquaLung 2015)
'' ----------------------------------------------------------------------------
'' Example 98 : Batching Meshes
'' This example demonstrates how avoiding large numbers of scene nodes by
'' copying the nodes mesh into a single mesh multiple times can have a
'' significant improvement of the speed of the program
'' ----------------------------------------------------------------------------

'' ////////////////////////////////////////////////////////////////////////////
'' Includes For extension libraries
Framework usr.birrlicht

' COMMENT this out To add all of the nodes seperately 
Const BATCHING = True
' CHANGE this To control how many objects are added
Const ROWS_AND_COLUMNS = 50


'' ////////////////////////////////////////////////////////////////////////////
'' Global variables

' irrlicht objects
Global MiniMesh:Int
Global MeshTextureA:Int
Global MeshTextureB:Int
Global SceneNode:Int
Global OurCamera:Int
Global framerate:Int
Global fpsString:String


'' ////////////////////////////////////////////////////////////////////////////
' start the irrlicht interface
iIrr3D( 800, 600, 32, False )

' add a static Text Field For the frame rate
framerate = iStaticText( "Calculating ...", 4,492, 508,508, IRR_GUI_BORDER, IRR_GUI_NO_WRAP, False )

' set the window caption
iAppTitle( "Example 98: Batching Meshes" )

' Load a mesh this acts as a blue Print For the model
MiniMesh = iLoadMesh( "./media/cylinderY.obj" )

iScaleMesh( MiniMesh, 4.0, 0, False, False )

' For a fair test make sure that the cylinder Object is hardware accellerated
iHWAcceleratedMesh( MiniMesh, False )

' Load texture resources For texturing the scene nodes
MeshTextureA = iLoadTexture( "./media/Cross.bmp" )
MeshTextureB = iLoadTexture( "./media/Diagonal.bmp" )

If BATCHING
' Create a batching mesh that will be a collection of other meshes
meshBatch% = iCreateBatchingMesh()

' add a whole mass of meshes To the batch mesh
For i = -ROWS_AND_COLUMNS/2 To ROWS_AND_COLUMNS/2
    For j = -ROWS_AND_COLUMNS/2 To ROWS_AND_COLUMNS/2

        ' as we are going To add this mesh as a single node If we want To use
        ' different textures with different meshes we need To apply them To the
        ' mesh before we add the mesh To the batch
        If ( i + (j Mod 2)) Mod 2 = 0 Then
            ' set the texture of the mesh before you add it so that the
            ' seperate meshes have their own colors
            ' This one will be BLUE
            iMeshTexture( miniMesh, MeshTextureA, 0, False )
        Else
            ' set the texture of the mesh before you add it so that the
            ' seperate meshes have their own colors
            ' This one will be RED
            iMeshTexture( miniMesh, MeshTextureB, 0, False )
        End If
        
        ' Add this mesh To the batch at its own unique position
        iAddToBatchingMesh ( meshBatch, MiniMesh, i*10.0, j*10.0, 0, 0, 0, 0, 1.0, 1.0, 1.0 )
    Next
Next

' finish adding meshes To the batch mesh And Create an animated mesh from it
MiniMesh = iFinalizeBatchingMesh ( meshBatch )

' get more speed by making the mesh hardware accellerated
iHWAcceleratedMesh( MiniMesh, 0 )

' add the mesh To the scene as a New node, the node is an instance of the
' mesh Object supplied here
SceneNode = iAddMeshToScene( MiniMesh )

' 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 )

Else

' Add rows of seperate nodes To demonstrate the speed difference
For i = -ROWS_AND_COLUMNS/2 To ROWS_AND_COLUMNS/2
    For j = -ROWS_AND_COLUMNS/2 To ROWS_AND_COLUMNS/2
        SceneNode = iAddMeshToScene( MiniMesh )
        iPositionNode( SceneNode, i*10.0, j*10.0, 0.0 )
        If ( i + (j Mod 2)) Mod 2 = 0 Then
            iNodeTexture( SceneNode, MeshTextureA, 0 )
        Else
            iNodeTexture( SceneNode, MeshTextureB, 0 )
        End If
        iNodeMaterialFlag( SceneNode, IRR_EMF_LIGHTING, False )
    Next
Next
EndIf

' add a camera into the scene
OurCamera = iCreateFPSCamera( 0,100.0,0.5,-1,0,0,0,0.0 )
iPositionNode( OurCamera, 0, 0, ROWS_AND_COLUMNS * 10 )
iHideMouse()

iCameraCLSColor( 240, 255, 255 )
' -----------------------------------------------------------------------------
' While the irrlicht environment is still running
While iRun() And (Not iKeyHit( KEY_ESCAPE ))
    ' begin the scene
    iBeginScene()

    ' draw the scene
    iDrawScene
    
    ' format And display the framerate
    fpsString = "FPS: " + String(iGetFPS()) + "    Objects: " + String( ROWS_AND_COLUMNS*ROWS_AND_COLUMNS ) + "    Polys: " + String(iTrisDrawn()) + "    Per Object: " + String(iTrisDrawn()/(ROWS_AND_COLUMNS*ROWS_AND_COLUMNS))
    iGUISetText( framerate, fpsString )

    ' draw the GUI
    iDrawGUI()

    ' End drawing the scene And render it
    iEndScene()
Wend 

' -----------------------------------------------------------------------------
' Stop the irrlicht engine And Release resources
iEndIrr3D()


End