Performance issues

BlitzMax Forums/BlitzMax Programming/Performance issues

Raz(Posted 2006) [#1]
Up until about an hour ago, Ive been using the blitzmax demo. I bought the full thing and upgraded to 1.2 and the decrease in performance is scary.

Granted, the coding in the program I have isnt very good (contains alot of drawline commands) but why on earth would this run fine for the demo, but badly for the full thing?

thanks


tonyg(Posted 2006) [#2]
DX, GL or both?
What example code can you provide?
What is syncmod status?
What FPS were you getting and now getting?


H&K(Posted 2006) [#3]
You do mean 1.20 and not 1.2 dont you?


Raz(Posted 2006) [#4]
Edit> and yeah I mean 1.20

I sync'd all the mods successfully

ok, currently im just using "Graphics 640,480,0" but am guessing I need to be more specific with the newer version.

I tried maxIDE for help on GLGraphics but it says the page is missing (and using GLgraphics on its own, causes an error on the first setcolor attempt)

ta for help


Raz(Posted 2006) [#5]
I know the overlap function calls drawrect_hollow a total of (enemy.count * tile.count) times and its obviously not something i plan to have in any actual game, but the problem I have is this worked so much better on the blitzmax demo than now. The coding is exactly the same, except the demo version used graphics 640,480,0 instead of graphics 640,480.

I also removed all image references for the sake of it working on other peoples machines. I dont have any fps counts or anything but the slow down is extremely obvious.

' enemy prototype

Graphics 640,480
SetMaskColor 255,0,255

'Global gfxEnemy:TImage = LoadAnimImage("Images\enemy_1.png",32,32,0,8)
'SetImageHandle gfxEnemy,15,31

Type Wall
Field x,y

	Method Draw()
	
		DrawRect x,y,32,32
	
	End Method
	
End Type
Global Wall_List:TList = CreateList()

Type Enemy
Field x#,y#,xs#,ys#,d,id
Field af,atimer
Field modea,modeb

	Method Draw()
		SetColor 255,255,255
		'DrawImage gfxEnemy,x,y,af+(4*d)
		DrawRect x-5,y-18,10,18
		SetColor 255,0,0
	
	End Method
	
	Method Animation()
	
		If atimer + 100 < MilliSecs() Then af = af+1; atimer = MilliSecs()
		If af = 4 Then af = 0
	
	End Method
	
	Method Movement()
	
		If d = 0 Then x = x - xs
		If d = 1 Then x = x + xs
		
		y = y + ys
		ys = ys + 0.1
		If ys > 3 Then ys = 3
	
	End Method
	
	
End Type
Global Enemy_List:TList = CreateList()

Function add_wall(x,y)
	Local NewWall:Wall
	NewWall = New Wall
	
	NewWall.x = x
	NewWall.y = y
	
	Wall_List.AddLast( NewWall )
	
End Function

Function add_enemy(x,y)
	Local NewEnemy:Enemy
	NewEnemy = New Enemy
	
	NewEnemy.x = x
	NewEnemy.y = y
	NewEnemy.xs = Rnd(0.5,2)
	NewEnemy.ys = Rnd(0,-2)
	NewEnemy.d = Rand(0,1)
	NewEnemy.af = 0
	NewEnemy.atimer = MilliSecs()
	NewEnemy.modea = Rand(0,2)
	NewEnemy.modeb = 0
	
	Enemy_List.AddLast( NewEnemy )
	
End Function

Function Enemy_Movement()

	For TEnemy:Enemy = EachIn Enemy_List
	
		Tenemy.Animation()
	
		Local old_y# = TEnemy.y
		Local old_x# = Tenemy.x
		Local ex# = Tenemy.x
		Local ey# = Tenemy.y
		Local d = Tenemy.d
		
		Local modea = Tenemy.modea
		Local low_col = False
		Local left_col = False
		Local right_col = False
		Local left_edge_col = 0
		Local Right_edge_col = 0
		
		Local left_jump = False
		Local right_jump = False
		Local left_jump_obstacle = False
		Local right_jump_obstacle = False
		Local overlap_low_col = False		
		
		TEnemy.Movement()

		' Bot/Left/Right collisions
		For Local TWall:Wall = EachIn Wall_List
		
			If OverLap (ex-5, ey+1, ex+5, ey+2, Twall.x, Twall.y, Twall.x+32, Twall.y+32)
				low_col = True
			EndIf
			
			If OverLap (ex-5, ey, ex+5, ey+1, Twall.x, Twall.y, Twall.x+32, Twall.y+32)
				overlap_low_col = True
			EndIf
			
			If OverLap (ex-10, ey-10, ex-7, ey-6, Twall.x, Twall.y, Twall.x+32, Twall.y+32)
				left_col = True
			EndIf
			If OverLap (ex+7, ey-10, ex+10, ey-6, Twall.x, Twall.y, Twall.x+32, Twall.y+32)
				right_col = True
			EndIf			

			If modea = 1 Or modea = 2
			
				' This stays at 0 If at an edge
				If OverLap (ex-12, ey+5, ex-8, ey+7, Twall.x, Twall.y, Twall.x+32, Twall.y+32)
					left_edge_col = left_edge_col + 1
				EndIf

				' This stays at 0 If at an edge			
				If OverLap (ex+8, ey+5, ex+12, ey+7, Twall.x, Twall.y, Twall.x+32, Twall.y+32)
					right_edge_col = right_edge_col + 1
				EndIf
				
			EndIf
			
			' If there is a platform that the enemy can jump To
			If OverLap (ex-44, ey+5, ex-42, ey+7, Twall.x, Twall.y, Twall.x+32, Twall.y+32)
				left_jump = True
			EndIf
			
			' If there	is a platform the enemy can jump to
			If OverLap (ex+42, ey+5, ex+44, ey+7, Twall.x, Twall.y, Twall.x+32, Twall.y+32)
				right_jump = True
			EndIf				

		Next
		
		' Potentially overwritten by events to come
		If low_col = True Then TEnemy.ys = 0;
		If overlap_low_col Then TEnemy.y = ey - 1
		
		' make the guy turn around
		If d = 1 And modea = 1 And low_col And right_edge_col = 0 Then TEnemy.d = Not d; tenemy.x = old_x
		If d = 0 And modea = 1 And low_col And left_edge_col = 0 Then TEnemy.d = Not d; tenemy.x = old_x
		
		' Make the guy jump
		If d = 1 And modea = 2 And low_col And right_jump And right_edge_col = 0 Then Tenemy.ys = -5
		If d = 0 And modea = 2 And low_col And left_jump And left_edge_col = 0 Then Tenemy.ys = -5		
		
		' turn around
		If d = 0 And left_col Then TEnemy.d = Not d; tenemy.x = old_x
		If d = 1 And right_col Then TEnemy.d = Not d; tenemy.x = old_x
		
	Next

End Function

Function Enemy_Render()

	For TEnemy:Enemy = EachIn Enemy_List
		TEnemy.Draw()
	Next

End Function

Function Wall_Render()

	For TWall:Wall = EachIn Wall_List
		TWall.Draw()
	Next

End Function
	
Function OverLap (x0#, y0#, x1#, y1#, x2#, y2#, x3#, y3#)
	Drawrect_hollow(x0,y0,x1,y1)
	If x0 > x3 Or x1 < x2 Then Return False
 	If y0 > y3 Or y1 < y2 Then Return False
 	Return True
End Function

SetColor 255,255,255
SetBlend Alphablend

Create_Walls()

While Not KeyDown(key_escape)

	Local mx = MouseX()
	Local my = MouseY()

	If MouseHit(1) Then add_enemy(mx,my)
	
	SetColor 255,255,255
	Wall_Render()

	Enemy_Movement()
	
	Enemy_Render()

	Flip;Cls

Wend

Function Create_Walls()
	
	For yy = 0 To 480 Step 32
		add_wall(0,yy)
	Next
	
	For yy = 0 To 480 Step 32
		add_wall(608,yy)
	Next
	
	For xx = 32 To 32 + 63 Step 32
		add_wall(xx,272)
	Next
	
	For xx = 128 To 128 + 63 Step 32
		add_wall(xx,272)
	Next
	
	For xx = 256 To 256 + 63 Step 32
		add_wall(xx,272)
	Next
	
	For xx = 32 To 607 Step 32
		add_wall(xx,480-32)
	Next
		
End Function

Function DrawRect_Hollow(x1,y1,x2,y2,crop=0)

	SetColor 255,0,0

	DrawLine x1,y1,x2,y1
	DrawLine x1,y1,x1,y2
	DrawLine x2,y1,x2,y2
	DrawLine x1,y2,x2,y2
	
End Function



Yan(Posted 2006) [#6]
Your documentation problems may indicates a dodgy installation.

I don't know which version is supplied when you buy BMax now, but you can only upgrade to 1.20 from 1.18.

Try following this procedure as it may fix things.


Dreamora(Posted 2006) [#7]
Please don't take it wrong.
But with that code its no wonder it has some performance issues.

You draw an extreme amount of lines (you draw numberOfOverlap * 4 times which means wall * enemy * 8 * 4 lines which is a significant problem as it is a 2D operation and not a 3D one.
so using an image might result in better performance if you have a system suitable for BM (at best NVIDIA or ATI, non-IGP, non TC, no intel or S3 crap)

Drop that out or use setgraphicsdriver to set the opengl driver before calling graphics and test it on that one (but be aware that OpenGL needs NVIDIA and ATI).


Raz(Posted 2006) [#8]
Yan: thanks. Yup thats how I did it but no luck as of yet.

Dreamora: Thanks for looking through it, believe me I am aware its pants coding (and as said I have no intention of using it for any proper program), but why would this work well (suprisingly so considering how many lines im drawing) on the demo, and badly in the full, updated thing?


Raz(Posted 2006) [#9]
as for using the setgraphicsdrivers command

SetGraphicsDriver GLMax2DDriver() '
Works well (much better than no setgraphicsdriver command at all)

SetGraphicsDriver GLGraphicsDriver() '
unhandled exception on setcolor

SetGraphics D3D7Max2DDriver() '
Unable to convert from D3D7... to TGraphics

Graphics 640,480 ' works but slow


tonyg(Posted 2006) [#10]
That code runs awful for me in GL mode but 'OK' in DX mode on my S3.
I think the demo was default to GL mode while full product is DX.
Try adding...
<edit> setgraphics to setgraphicsdriver
setgraphicsdriver glmax2ddriver()
to just before your graphics command.
If it makes a difference you might need to update your DX graphics drivers. I do remember a lot of people complaing about FPS decrease from 1.16+ and the general response/solution was poor DX drivers.


Dreamora(Posted 2006) [#11]
Don't know how old the demo was.
But the original BM only had OpenGL and first defaulted to OpenGL which is a 3D API.
Now on Windows it defaults to DirectX which has a 2D API part, which makes a difference if you use a 2D command.

I'm not fully sure but I think this is one of the main problems why the performance dropped that far.
Another potential problem might be that you updated your drivers in the meantime ... and the sad thing is that current drivers get more and more de-optimized for DX7 to get DX9 optimized further (at least thats what happening. no Idea if it is what they actually do or intend to do)


Raz(Posted 2006) [#12]
haha just looking now, the demo was 1.09!

welp it seems that setgraphics glmax2ddriver() is the way to go.

thanks for your help everyone :)


tonyg(Posted 2006) [#13]
... or try updating your DX graphics drivers.


Raz(Posted 2006) [#14]
DX drivers are completely up to date, but on a side note...

SetGraphics D3D7Max2DDriver()

gives me the error "Unable to convert from TD3D7Max2DDriver to TGraphics"


Grey Alien(Posted 2006) [#15]
couple of things were added to 1.20 + syncmods:

- DX now has anti-lag code in which has a big performance impact to DX, but at elast your game display won't lag!
- Windowed mode using Flip 1 now has proper VSync.

these may affect your performance...


tonyg(Posted 2006) [#16]
SetGraphicsDriver D3D7Max2DDriver()


Raz(Posted 2006) [#17]
haha oh yeah, sorry, i missed that one


TomToad(Posted 2006) [#18]
Are you running in debug mode where you might've been running release mode on the demo? Just a thought as debug mode will greatly decrease speed of things.
Another thought. Wasn't version 1.09 before automatic GC? If you didn't use flushmem() that would greatly speed things up by not doing garbage collection all the time, but would also create a major memory leak.