I'm idiot or the TList are very slow ????

BlitzMax Forums/BlitzMax Programming/I'm idiot or the TList are very slow ????

Hi

I'm working on a piece of blitz3D code converted to bmax, it's a little
realtime raytracer that i have find from DBF forum

The first code use array to store scene primitive object
the program start very quick.

This the code :
'' <a href="http://p212.ezboard.com/fdbffrm50" target="_blank">http://p212.ezboard.com/fdbffrm50</a>

Framework BRL.GLMax2D
Import BRL.Random
SetGraphicsDriver GLMax2DDriver()


Const width = 320
Const height = 240

Graphics width,height,32,75

SeedRnd MilliSecs()

Global RenderImage:Timage=CreateImage(width,height,DYNAMICIMAGE)

Global sphere_list:TList=New TList
Global plane_list:TList=New TList

Type TBBType
	Field _list:TList
	Field _link:TLink

	Method Remove()
		_list.remove Self
	End Method
End Type

Type bbplane Extends TBBType
        Field nx#
        Field ny#
        Field nz#

        Field dis#
        Field argb
End Type

Type bbsphere Extends TBBType
        Field x#
        Field y#
        Field z#
        Field xv#
        Field yv#
        Field zv#
        Field argb
End Type

' ---------------
' FPS Counter var
' ---------------
Global Frames:Int
Global RenderTime:Int
Global Fps:Int

' ---------
' Other var
' ,--------
Global planes = 1
Global spheres = 8

Global p:bbplane[planes+1]
Global s:bbsphere[spheres+1]

Global normalx#[width+1,height+1]
Global normaly#[width+1,height+1]
Global normalz#[width+1,height+1]

Global sphererad# = 80.0
Global sphererad2# = Float(sphererad# * sphererad#)

Global camerax# =0
Global cameray# =0
Global cameraz# = -800.0

Global lightx# = 200.0
Global lighty# = 400.0
Global lightz# = -200.0

Global spec# = 90.0
Global grav# = 1.15
Global fric# = 0.65

' --------------
' Setup 3D scene
' --------------
DrawText "COMPUTING",10,10
Flip

setupplanes()
setupspheres()
setupnormals()

While Not KeyHit(KEY_ESCAPE)
	Cls

	raytrace()
	
	'SetScale 1.01,1.01
	DrawImage RenderIMage,0,0
	'SetScale 1,1
	
	' -----------------------
	' Apply gravity to sphere
	' -----------------------
	For i = 0 To spheres - 1
		s(i).x# = s(i).x# + s(i).xv#
		s(i).y# = s(i).y# + s(i).yv#
		s(i).z# = s(i).z# + s(i).zv#
		s(i).yv# = s(i).yv# - grav#
			
		' ---------------------------------------
		' Detecting if the sphere touch the plane
		' ---------------------------------------
		If s(i).y# - sphererad# < -p(0).dis#
			s(i).y# = -p(0).dis# + sphererad#
			s(i).xv# = Float(s(i).xv# * fric#)
			s(i).yv# = Float(-s(i).yv# * fric#)
			s(i).zv# = Float(s(i).zv# * fric#)
	
			If s(i).xv# > -fric# Or s(i).xv# < fric# Then s(i).xv# = 0
			If s(i).zv# > -fric# Or s(i).zv# < fric# Then s(i).zv# = 0
		EndIf
	Next

	If KeyDown(KEY_LEFT) Then camerax# = camerax# - 50.0
	If KeyDown(KEY_RIGHT) Then camerax# = camerax# + 50.0
	
	If KeyDown(KEY_UP) Then cameraz# = cameraz# + 50.0
	If KeyDown(KEY_DOWN) Then cameraz# = cameraz# - 50.0
	
	If KeyDown(KEY_PAGEUP) Then cameray# = cameray# + 50.0
	If KeyDown(KEY_PAGEDOWN) Then cameray# = cameray# - 50.0
	
	' --------------------
	' Made jump the sphere
	' --------------------
	If KeyHit(KEY_SPACE)
		For i = 0 To spheres - 1
			s(i).yv# = Rnd(16,20)
		Next
	EndIf
	
	DrawText "FPS "+Fps+" / "+MemUsage(),10,10
	
	RefreshFPS()
	
	FlushMem
	Flip
Wend

' --------
' Quit app
' --------
For i = 0 To planes - 1
	p(i).Remove()
Next

For i = 0 To spheres - 1
	s(i).Remove()
Next

End

' ---------------------
' Setup plane primitive
' ---------------------
Function setupplanes()
	For i = 0 To planes - 1
        p:bbplane(i) = New bbplane
        p(i).ny# = 1.0
        p(i).dis# = Float(sphererad# * 4.0)
        p(i).argb = Rand($686868,$FFFFFF)
	Next
End Function

' ----------------------
' Setup sphere primitive
' ----------------------
Function setupspheres()
	Local sr# = Float(sphererad# * 2.5)
	
	For i = 0 To spheres - 1
        s:bbsphere(i) = New bbsphere

        s(i).x# = Rnd(-sr#,sr#)
        s(i).y# = Rnd(0,sphererad#)
        s(i).z# = Rnd(-sr#,sr#)

        s(i).xv# = Rnd(-10.0,10.0)
        s(i).yv# = Rnd(-2.0,7.0)
        s(i).zv# = Rnd(-10.0,10.0)

        s(i).argb = Rand($111111,$FFFFFF)
	Next
End Function

Function setupnormals()
	Local nx#
	Local ny#
	Local nz# = 250.0
	Local dis#
	
	For y = 0 To height - 1
        ny# = Float(height Shr 1) - Float(y)
    
	    For x = 0 To width - 1
                nx# = Float(width Shr 1) - Float(x)
                dis# = Sqr(Float(nx# * nx#) + Float(ny# * ny#) + Float(nz# * nz#))
                normalx#(x,y) = -Float(nx# / dis#)
                normaly#(x,y) = Float(ny# / dis#)
                normalz#(x,y) = Float(nz# / dis#)
        Next
	Next
End Function

' ------------------
' Raytrace the image
' ------------------
Function raytrace()
	Local argb

	Local RenderMap=LockImage(RenderImage)
	
	For y = 0 To height - 1
        For x = 0 To width - 1
			argb = ray(camerax#,cameray#,cameraz#,normalx#(x,y),normaly#(x,y),normalz#(x,y),256)

			If argb <> $00000000 Then WritePixel RenderMap,x,y,argb
        Next
	Next

	UnlockImage (RenderImage)
	RenderMap=Null
End Function

' ----------------------
' Raytracing computation
' ----------------------
Function ray(ex#,ey#,ez#,evx#,evy#,evz#,c)
	If c <= 32 Then Return
	Local plane:bbplane
	Local sphere:bbsphere
	
	Local z# = 10000
	Local svx#
	Local svy#
	Local svz#
	
	Local ix#
	Local iy#
	Local iz#
	Local nx#
	Local ny#
	Local nz#
	
	Local rnx#
	Local rny#
	Local rnz#
	
	Local lvx#
	Local lvy#
	Local lvz#
	
	Local dxis#
	Local ydis#
	Local zdis#
	
	Local dxis2#
	Local ydis2#
	Local zdis2#
	
	Local dis#
	Local dis2#
	
	Local l#
	
	Local c1
	Local c2
	Local c3

	Local a
	Local r
	Local g
	Local b

	For i = 0 To planes - 1
        plane:bbplane = p(i)
        nx# = plane.nx#
        ny# = plane.ny#
        nz# = plane.nz#
        dis# = Float(Float(nx# * evx#) + Float(ny# * evy#) + Float(nz# * evz#))

        If dis# < 0
                dis2# = Float(-Float(plane.dis# + Float(Float(nx# * ex#) + Float(ny# * ey#) + Float(nz# * ez#))) / dis#)
                ix# = ex# + Float(evx# * dis2#)
                iy# = ey# + Float(evy# * dis2#)
                iz# = ez# + Float(evz# * dis2#)

                lvx# = Float(lightx# - ix#)
                lvy# = Float(lighty# - iy#)
                lvz# = Float(lightz# - iz#)

                dis# = Sqr(Float(lvx# * lvx#) + Float(lvy# * lvy#) + Float(lvz# * lvz#))

                lvx# = Float(lvx# / dis#)
                lvy# = Float(lvy# / dis#)
                lvz# = Float(lvz# / dis#)

                l# = Float(Float(nx# * lvx#) + Float(ny# * lvy#) + Float(nz# * lvz#))

                dis# = Float(Float(Float(nx# * evx#) + Float(ny# * evy#) + Float(nz# * evz#)) * 2.0)

                rnx# = evx# - Float(nx# * dis#)
                rny# = evy# - Float(ny# * dis#)
                rnz# = evz# - Float(nz# * dis#)

                c1 = Int(l# * 256.0)
                c2 = Int(Float(Float(rnx# * lvx#) + Float(rny# * lvy#) + Float(rnz# * lvz#))^spec# * 256.0)
                argb = plane.argb
                z# = dis2#
        EndIf

	Next

	For i = 0 To spheres - 1
        sphere:bbsphere = s(i)
        svx# = sphere.x# - ex#
        svy# = sphere.y# - ey#
        svz# = sphere.z# - ez#

        dis2# = Float(Float(svx# * evx#) + Float(svy# * evy#) + Float(svz# * evz#))
        dis# = Float(Float(svx# * svx#) + Float(svy# * svy#) + Float(svz# * svz#)) - Float(dis2# * dis2#)
        
		If dis# <= sphererad2#
                dis2# = dis2# - Sqr(sphererad2# - dis#)
 				

                If dis2# > 0 And dis2# < z#
                        ix# = ex# + Float(evx# * dis2#)
                        iy# = ey# + Float(evy# * dis2#)
                        iz# = ez# + Float(evz# * dis2#)

                        nx# = Float(Float(ix# - sphere.x#) / sphererad#)
                        ny# = Float(Float(iy# - sphere.y#) / sphererad#)
                        nz# = Float(Float(iz# - sphere.z#) / sphererad#)

                        lvx# = Float(lightx# - ix#)
                        lvy# = Float(lighty# - iy#)
                        lvz# = Float(lightz# - iz#)

                        dis# = Sqr(Float(lvx# * lvx#) + Float(lvy# * lvy#) + Float(lvz# * lvz#))

                        lvx# = Float(lvx# / dis#)
                        lvy# = Float(lvy# / dis#)
                        lvz# = Float(lvz# / dis#)

                        l# = Float(Float(nx# * lvx#) + Float(ny# * lvy#) + Float(nz# * lvz#))

                        dis# = Float(Float(Float(nx# * evx#) + Float(ny# * evy#) + Float(nz# * evz#)) * 2.0)

                        rnx# = evx# - Float(nx# * dis#)
                        rny# = evy# - Float(ny# * dis#)
                        rnz# = evz# - Float(nz# * dis#)

                        c1 = Int(l# * 256.0)
                        c2 = Int(Float(Float(rnx# * lvx#) + Float(rny# * lvy#) + Float(rnz# * lvz#))^spec# * 256.0)
                        argb = sphere.argb
                        z# = dis2#
                EndIf
        EndIf
	Next

	If shadowed(ix#,iy#,iz#)
        c1 = 30
        c2 = 0
	Else
        If c1 < 30 Then c1 = 30
        If c2 < 0 Then c2 = 0
	EndIf

	c3 = (c1 * c) Shr 8

	r = ((argb & $00FF0000) * c3) Shr 8
	g = ((argb & $0000FF00) * c3) Shr 8
	b = ((argb & $000000FF) * c3) Shr 8

	r = r + (c2 Shl 16)
	g = g + (c2 Shl 8)
	b = b + c2




	If argb <> $00000000 Then argb = ray(ix#,iy#,iz#,rnx#,rny#,rnz#,c - 32)

	r = r + (argb & $00FF0000)
	g = g + (argb & $0000FF00)
	b = b + (argb & $000000FF)

	If r > $00FF0000
        r = $00FF0000
	Else
        r = r & $00FF0000
	EndIf

	If g > $0000FF00
        g = $0000FF00
	Else
        g = g & $0000FF00
	EndIf

	If b > $000000FF
        b = $000000FF
	Else
        b = b & $000000FF
	EndIf

	Return $FF000000 | r | g | b
End Function

' --------------
' Compute shadow
' --------------
Function shadowed(x#,y#,z#)
	Local plane:bbplane
	Local sphere:bbsphere
	Local shad = False
	Local evx# = Float(lightx# - x#)
	Local evy# = Float(lighty# - y#)
	Local evz# = Float(lightz# - z#)
	Local dis# = Sqr(Float(evx# * evx#) + Float(evy# * evy#) + Float(evz# * evz#))
	Local dis2#
	
	evx# = Float(evx# / dis#)
	evy# = Float(evy# / dis#)
	evz# = Float(evz# / dis#)
	
	For i = 0 To planes - 1
        plane:bbplane = p(i)
        nx# = plane.nx#
        ny# = plane.ny#
        nz# = plane.nz#
        dis# = Float(Float(nx# * evx#) + Float(ny# * evy#) + Float(nz# * evz#))
        If dis# < 0
                shad = True
                i = planes - 1
        EndIf
	Next
	
	If shad = False
        For i = 0 To spheres - 1
                sphere:bbsphere = s(i)
                svx# = sphere.x# - x#
                svy# = sphere.y# - y#
                svz# = sphere.z# - z#
                dis2# = Float(Float(svx# * evx#) + Float(svy# * evy#) + Float(svz# * evz#))
                dis# = Float(Float(svx# * svx#) + Float(svy# * svy#) + Float(svz# * svz#)) - Float(dis2# * dis2#)
                If dis2# > 0 And dis# < sphererad2#
                    shad = True
               		i = spheres - 1
                EndIf
        Next
	EndIf
	
	Return shad
End Function

' ------------
' For know FPS
' ------------
Function RefreshFPS()
	Frames=Frames+1
	
	If MilliSecs()-RenderTime=>1000 Then
		Fps=Frames 
		Frames=0
	 	RenderTime=MilliSecs()
	EndIf
End Function


And the second code is the same than the first !!! the only difference ?
i use TList to store all objects, the result is 6x more long to start ??? and the program run very very slowwwwww ....

Here is code :
'' <a href="http://p212.ezboard.com/fdbffrm50" target="_blank">http://p212.ezboard.com/fdbffrm50</a>

Framework BRL.GLMax2D
Import BRL.Random
SetGraphicsDriver GLMax2DDriver()

Const width = 320
Const height = 240

Graphics width,height,32,75

SeedRnd MilliSecs()

Global RenderImage:Timage=CreateImage(width,height,DYNAMICIMAGE)

Global ScenePlane=10
Global SceneSphere=20

Global SceneEntityList:TList=CreateList()

Type SceneEntity
	Field EntityType
	Field X#
	Field Y#
	Field Z#
	
	Field nx#
	Field ny#
	Field nz#
	
	Field xv#
	Field yv#
	Field zv#
	
	Field dis#
	Field argb	
End Type




' ---------------
' FPS Counter var
' ---------------
Global Frames:Int
Global RenderTime:Int
Global Fps:Int

Global SceneGround:SceneEntity

' ---------
' Other var
' --------
Global normalx#[width+1,height+1]
Global normaly#[width+1,height+1]
Global normalz#[width+1,height+1]

Global sphererad# = 80.0
Global sphererad2# = Float(sphererad# * sphererad#)

Global camerax# =0
Global cameray# =0
Global cameraz# = -800.0

Global lightx# = 200.0
Global lighty# = 400.0
Global lightz# = -200.0

Global spec# = 90.0
Global grav# = 1.15
Global fric# = 0.65



' --------------
' Setup 3D scene
' --------------
DrawText "COMPUTING",10,10
Flip


setupplanes()
setupspheres()
setupnormals()

While Not KeyHit(KEY_ESCAPE)
	Cls

	raytrace()
	
	'SetScale 1.01,1.01
	DrawImage RenderIMage,0,0
	'SetScale 1,1
	
	' -----------------------
	' Apply gravity to sphere
	' -----------------------
	For O:SceneEntity = EachIn SceneEntityList
		If O.EntityType=SceneSphere Then
			
			O.x# = O.x# + O.xv#
			O.y# = O.y# + O.yv#
			O.z# = O.z# + O.zv#
			O.yv# = O.yv# - grav#
			
			' ---------------------------------------
			' Detecting if the sphere touch the plane
			' ---------------------------------------
			If O.y# - sphererad# < -SceneGround.dis#
				O.y# = -SceneGround.dis# + sphererad#
				O.xv# = Float(O.xv# * fric#)
				O.yv# = Float(-O.yv# * fric#)
				O.zv# = Float(O.zv# * fric#)
	
				If O.xv# > -fric# Or O.xv# < fric# Then O.xv# = 0
				If O.zv# > -fric# Or O.zv# < fric# Then O.zv# = 0
			EndIf	
		EndIf
	Next


	If KeyDown(KEY_LEFT) Then camerax# = camerax# - 50.0
	If KeyDown(KEY_RIGHT) Then camerax# = camerax# + 50.0
	
	If KeyDown(KEY_UP) Then cameraz# = cameraz# + 50.0
	If KeyDown(KEY_DOWN) Then cameraz# = cameraz# - 50.0
	
	If KeyDown(KEY_PAGEUP) Then cameray# = cameray# + 50.0
	If KeyDown(KEY_PAGEDOWN) Then cameray# = cameray# - 50.0
	
	' --------------------
	' Made jump the sphere
	' --------------------
	'If KeyHit(KEY_SPACE)
	'	For i = 0 To spheres - 1
	'		s(i).yv# = Rnd(16,20)
	'	Next
	'EndIf
	
	DrawText "FPS "+Fps+" / "+MemUsage(),10,10
	
	RefreshFPS()
	
	FlushMem
	Flip
Wend

' --------
' Quit app
' --------
'For i = 0 To planes - 1
'	p(i).Remove()
'Next

'For i = 0 To spheres - 1
'	s(i).Remove()
'Next

End

' ---------------------
' Setup plane primitive
' ---------------------
Function setupplanes()
	SceneGround:SceneEntity = New SceneEntity
	SceneGround.EntityType=ScenePlane
	SceneGround.ny#=1.0
	SceneGround.dis#=Float(sphererad# * 4.0)
	SceneGround.argb=Rand($00686868,$00FFFFFF)
	
	SceneEntityList.AddLast(SceneGround)
End Function

' ----------------------
' Setup sphere primitive
' ----------------------
Function setupspheres()
	For i=1 To 8
	' --------------
	' Setup sphere 1
	' --------------
	Local sr# = Float(sphererad# * 2.5)
	Local O:SceneEntity
	
	O = New SceneEntity
	O.EntityType=SceneSphere
	
	O.X#=Rnd(-sr#,sr#)
	O.Y#=Rnd(0,sphererad#)
	O.Z#=Rnd(-sr#,sr#)
	
	O.xv#=Rnd(-10.0,10.0)
	O.yv#=Rnd(-2.0,7.0)
	O.zv#=Rnd(-10.0,10.0)

	O.argb=Rand($111111,$FFFFFF)

	SceneEntityList.AddLast(O)	
	Next 
	
	
	' --------------
	' Setup sphere 1
	' --------------
	'Local sr# = Float(sphererad# * 2.5)
	'Local O:SceneEntity
	
	'O = New SceneEntity
	'O.EntityType=SceneSphere
	
	'O.X#=-60
	'O.Y#=sphererad#
	'O.Z#=0
	
	'O.xv#=Rnd(-10.0,10.0)
	'O.yv#=Rnd(-2.0,7.0)
	'O.zv#=Rnd(-10.0,10.0)

	'O.argb=$00FF0000

	'SceneEntityList.AddLast(O)

	
	' --------------
	' Setup sphere 2
	' --------------	
	'O = New SceneEntity
	'O.EntityType=SceneSphere
	
	'O.X#=60
	'O.Y#=sphererad#
	'O.Z#=0
	
	'O.xv#=Rnd(-10.0,10.0)
	'O.yv#=Rnd(-2.0,7.0)
	'O.zv#=Rnd(-10.0,10.0)

	'O.argb=$0000FF00

	'SceneEntityList.AddLast(O)
End Function

Function setupnormals()
	Local nx#
	Local ny#
	Local nz# = 250.0
	Local dis#
	
	For y = 0 To height - 1
        ny# = Float(height Shr 1) - Float(y)
    
	    For x = 0 To width - 1
                nx# = Float(width Shr 1) - Float(x)
                dis# = Sqr(Float(nx# * nx#) + Float(ny# * ny#) + Float(nz# * nz#))
                normalx#(x,y) = -Float(nx# / dis#)
                normaly#(x,y) = Float(ny# / dis#)
                normalz#(x,y) = Float(nz# / dis#)
        Next
	Next
End Function

' ------------------
' Raytrace the image
' ------------------
Function raytrace()
	Local argb

	Local RenderMap=LockImage(RenderImage)
	
	For y = 0 To height - 1
        For x = 0 To width - 1
			argb = ray(camerax#,cameray#,cameraz#,normalx#(x,y),normaly#(x,y),normalz#(x,y),256)

			If argb <> $00000000 Then WritePixel RenderMap,x,y,argb
        Next
	Next

	UnlockImage (RenderImage)
	RenderMap=Null
End Function

' ----------------------
' Raytracing computation
' ----------------------
Function ray(ex#,ey#,ez#,evx#,evy#,evz#,c)
	If c <= 32 Then Return
	Local z# = 10000
	Local svx#
	Local svy#
	Local svz#
	
	Local ix#
	Local iy#
	Local iz#
	Local nx#
	Local ny#
	Local nz#
	
	Local rnx#
	Local rny#
	Local rnz#
	
	Local lvx#
	Local lvy#
	Local lvz#
	
	Local dxis#
	Local ydis#
	Local zdis#
	
	Local dxis2#
	Local ydis2#
	Local zdis2#
	
	Local dis#
	Local dis2#
	
	Local l#
	
	Local c1
	Local c2
	Local c3

	Local a
	Local r
	Local g
	Local b

	
	For O:SceneEntity = EachIn SceneEntityList
		If O.EntityType=ScenePlane Then
			nx# = O.nx#
			ny# = O.ny#
			nz# = O.nz#
			
			dis# = Float(Float(nx# * evx#) + Float(ny# * evy#) + Float(nz# * evz#))

			If dis# < 0
				dis2# = Float(-Float(O.dis# + Float(Float(nx# * ex#) + Float(ny# * ey#) + Float(nz# * ez#))) / dis#)
				ix# = ex# + Float(evx# * dis2#)
				iy# = ey# + Float(evy# * dis2#)
				iz# = ez# + Float(evz# * dis2#)



				lvx# = Float(lightx# - ix#)
				lvy# = Float(lighty# - iy#)
				lvz# = Float(lightz# - iz#)

				dis# = Sqr(Float(lvx# * lvx#) + Float(lvy# * lvy#) + Float(lvz# * lvz#))

				lvx# = Float(lvx# / dis#)
				lvy# = Float(lvy# / dis#)
				lvz# = Float(lvz# / dis#)

				l# = Float(Float(nx# * lvx#) + Float(ny# * lvy#) + Float(nz# * lvz#))

				dis# = Float(Float(Float(nx# * evx#) + Float(ny# * evy#) + Float(nz# * evz#)) * 2.0)

				rnx# = evx# - Float(nx# * dis#)
				rny# = evy# - Float(ny# * dis#)
				rnz# = evz# - Float(nz# * dis#)

				c1 = Int(l# * 256.0)
				c2 = Int(Float(Float(rnx# * lvx#) + Float(rny# * lvy#) + Float(rnz# * lvz#))^spec# * 256.0)
				argb = O.argb
				z# = dis2#
			EndIf
		EndIf
	Next


	For O:SceneEntity = EachIn SceneEntityList
		If O.EntityType=SceneSphere Then
        	svx# = O.x# - ex#
        	svy# = O.y# - ey#
        	svz# = O.z# - ez#

        	dis2# = Float(Float(svx# * evx#) + Float(svy# * evy#) + Float(svz# * evz#))
        	dis# = Float(Float(svx# * svx#) + Float(svy# * svy#) + Float(svz# * svz#)) - Float(dis2# * dis2#)
        
			If dis# <= sphererad2#
                dis2# = dis2# - Sqr(sphererad2# - dis#)
 				

                If dis2# > 0 And dis2# < z#
                        ix# = ex# + Float(evx# * dis2#)
                        iy# = ey# + Float(evy# * dis2#)
                        iz# = ez# + Float(evz# * dis2#)

                        nx# = Float(Float(ix# - O.x#) / sphererad#)
                        ny# = Float(Float(iy# - O.y#) / sphererad#)
                        nz# = Float(Float(iz# - O.z#) / sphererad#)

                        lvx# = Float(lightx# - ix#)
                        lvy# = Float(lighty# - iy#)
                        lvz# = Float(lightz# - iz#)

                        dis# = Sqr(Float(lvx# * lvx#) + Float(lvy# * lvy#) + Float(lvz# * lvz#))

                        lvx# = Float(lvx# / dis#)
                        lvy# = Float(lvy# / dis#)
                        lvz# = Float(lvz# / dis#)

                        l# = Float(Float(nx# * lvx#) + Float(ny# * lvy#) + Float(nz# * lvz#))

                        dis# = Float(Float(Float(nx# * evx#) + Float(ny# * evy#) + Float(nz# * evz#)) * 2.0)

                        rnx# = evx# - Float(nx# * dis#)
                        rny# = evy# - Float(ny# * dis#)
                        rnz# = evz# - Float(nz# * dis#)

                        c1 = Int(l# * 256.0)
                        c2 = Int(Float(Float(rnx# * lvx#) + Float(rny# * lvy#) + Float(rnz# * lvz#))^spec# * 256.0)
                        argb = O.argb
                        z# = dis2#
                EndIf
			EndIf
        EndIf
	Next







	If shadowed(ix#,iy#,iz#)
        c1 = 30
        c2 = 0
	Else
        If c1 < 30 Then c1 = 30
        If c2 < 0 Then c2 = 0
	EndIf

	c3 = (c1 * c) Shr 8

	r = ((argb & $00FF0000) * c3) Shr 8
	g = ((argb & $0000FF00) * c3) Shr 8
	b = ((argb & $000000FF) * c3) Shr 8

	r = r + (c2 Shl 16)
	g = g + (c2 Shl 8)
	b = b + c2

	If argb <> $00000000 Then argb = ray(ix#,iy#,iz#,rnx#,rny#,rnz#,c - 32)

	r = r + (argb & $00FF0000)
	g = g + (argb & $0000FF00)
	b = b + (argb & $000000FF)

	If r > $00FF0000
        r = $00FF0000
	Else
        r = r & $00FF0000
	EndIf

	If g > $0000FF00
        g = $0000FF00
	Else
        g = g & $0000FF00
	EndIf

	If b > $000000FF
        b = $000000FF
	Else
        b = b & $000000FF
	EndIf

	Return $FF000000 | r | g | b
End Function

' --------------
' Compute shadow
' --------------
Function shadowed(x#,y#,z#)
	Local shad = False
	Local evx# = Float(lightx# - x#)
	Local evy# = Float(lighty# - y#)
	Local evz# = Float(lightz# - z#)
	Local dis# = Sqr(Float(evx# * evx#) + Float(evy# * evy#) + Float(evz# * evz#))
	Local dis2#
	
	evx# = Float(evx# / dis#)
	evy# = Float(evy# / dis#)
	evz# = Float(evz# / dis#)
	
	For O:SceneEntity = EachIn SceneEntityList
		If O.EntityType=ScenePlane Then
			nx# = O.nx#
			ny# = O.ny#
			nz# = O.nz#
			
			dis# = Float(Float(nx# * evx#) + Float(ny# * evy#) + Float(nz# * evz#))
			
			If dis# < 0
				shad = True
			EndIf
		EndIf
	Next
				
	If shad = False
		For O:SceneEntity = EachIn SceneEntityList
			If O.EntityType=SceneSphere Then
				svx# = O.x# - x#
				svy# = O.y# - y#
				svz# = O.z# - z#
				
                dis2# = Float(Float(svx# * evx#) + Float(svy# * evy#) + Float(svz# * evz#))
                dis# = Float(Float(svx# * svx#) + Float(svy# * svy#) + Float(svz# * svz#)) - Float(dis2# * dis2#)
               
				If dis2# > 0 And dis# < sphererad2#
                    shad = True
                EndIf
			EndIf
		Next
	EndIf
	
	Return shad
End Function

' ------------
' For know FPS
' ------------
Function RefreshFPS()
	Frames=Frames+1
	
	If MilliSecs()-RenderTime=>1000 Then
		Fps=Frames 
		Frames=0
	 	RenderTime=MilliSecs()
	EndIf
End Function


Any idea about program start longer ?