`jGfx Plugin: GInst Example - Texture Atlases with seamless wrapping and filtering
`==========================================================================================
`This example shows how to use texture atlasing to apply materials on a per-instance basis
Sw = Desktop Width()
Sh = Desktop Height()
Set Display Mode Sw,Sh,32,1
Sync On : Sync Rate 0
Color Backdrop 0
Autocam Off



`Example Settings
InstanceCount = 100		`Number of instances to create



`Setup Instance Source Object
ObjectID = 1
Load Object "Media\TreeTrunk.dbo", ObjectID
Convert Object FVF ObjectID, 0x002 || 0x010 || 0x100 //XYZ + Normal + Tex1

`Load a specially prepared atlas texture
AtlasFN$ = "Media\DiffuseAtlas.DDS" `4x4 atlas (contains 16 materials)
AtlasTilesX = 4	
AtlasTilesY = 4

AtlasTexID = 1
Load Image AtlasFN$, AtlasTexID
Texture Object ObjectID, 0, AtlasTexID


`load GInst texture atlas effect
EffectID = 1
Load Effect "Media\GInst_DiffuseAtlas.fx", EffectID, 0

`Set effect texture atlas settings
Null=Make Vector4(1)
TileScaleX# = (1.0/AtlasTilesX)*0.5	//usable size of each tile
TileScaleY# = (1.0/AtlasTilesY)*0.5
Set Vector4 1,TileScaleX#,TileScaleY#,TileScaleX#*0.5,TileScaleY#*0.5 //float4(TileScale.xy, TileGutter.xy)
Set Effect Constant Vector EffectID,"AtlasData",1




`Create a GInst, and setup it's render resources
pGInst = GInst_MakeNew()
GInst_SetObject pGInst, ObjectID
GInst_SetEffect pGInst, EffectID

`Add a custom element to store per-instance texture atlas tile coordinates and scaling
GInst_DeclareCustomElements pGInst, 1
	GInst_AddCustomElement pGInst, D3DDECLTYPE_FLOAT4, D3DDECLUSAGE_TEXCOORD `Custom Element 1
GInst_FinishCustomElements pGInst




`Create a GInstBuffer and fill it with random instance data
pInstBuffer = GInstBuffer_MakeNew(pGInst, InstanceCount)

`Setup Instances
Randomize 20000
For i=1 To InstanceCount

	`Instance transforms
	GInstBuffer_SetPosition pInstBuffer, i, Rnd(1000)-500, 0.0, Rnd(1000)-500
	GInstBuffer_SetRotation pInstBuffer, i, 0.0, Rnd(360), 0.0
	InstScale = Rnd(100)+50
	GInstBuffer_SetScale pInstBuffer, i, InstScale
	GInstBuffer_UpdateInstance pInstBuffer, i

	`Instance texture settings
	TileX = Rnd(AtlasTilesX-1)			`Get a random atlas tile
	TileY = Rnd(AtlasTilesY-1)
	TileU# = TileX*(1.0/AtlasTilesX)	`Calculate tile UV
    TileV# = TileY*(1.0/AtlasTilesY)
    TexScale = Int(InstScale/50.0)		`Scale texture based on instance size.
	GInstBuffer_SetFloat4 pInstBuffer, i, 1, TileU#, TileV#, TexScale, TexScale
	
Next i
GInstBuffer_Update pInstBuffer








Position Camera -600, 350, -600
Rotate Camera 25, 45, 0

`TBM Setup
TimeSpeed# = 0.5
LastTime = Timer()

Do
	Set Cursor 0,0
	Print "FPS = ",Screen Fps()
	Print "Press spacebar to re-randomize textures"
	
	`TBM
	Now=Timer()
	TimePassed# = (Now - LastTime)*TimeSpeed#
	LastTime = Now

	`Camera control
	Move Camera (UpKey()-DownKey())*TimePassed#
	Move Camera Right (RightKey()-LeftKey())*TimePassed#
	Rotate Camera Wrapvalue(Camera Angle X()+MouseMoveY()),  Wrapvalue(Camera Angle Y()+MouseMoveX()), 0

	`Randomize textures
	SPKey = SpaceKey()
	If SPKey
		If SPHeld=0
			SPHeld=1
			For i=1 To InstanceCount
			`Set instance texture
				TileX = Rnd(AtlasTilesX-1)			`Get a random atlas tile
				TileY = Rnd(AtlasTilesY-1)
				TileU# = TileX*(1.0/AtlasTilesX)	`Calculate tile UV
    			TileV# = TileY*(1.0/AtlasTilesY)
				GInstBuffer_SetFloat2 pInstBuffer, i, 1, TileU#, TileV# `Update element as Float2 to retain texture scale values
			Next i
			GInstBuffer_Update pInstBuffer, 0
		Endif
	Else
		SPHeld=0
	Endif

	Sync
Loop
