Bizarre graphics timing / resolution problem

BlitzMax Forums/BlitzMax Beginners Area/Bizarre graphics timing / resolution problem

Hi guys, I've been experimenting with trying to get movement as solid as possible, so I've been messing around with various frame timing techniques.

Along the way I've been noticing weird flickering and glitching at certain resolutions and vsync settings and I can't figure out if the problem is down to my coding, my pc, my monitor or some weird bug deep down inside blitzmax.

I've put together this test app which hopefully will show the problem:

SuperStrict

Global NativeWidth% = 1600
Global NativeHeight% = 1200

'======================================================================================================================================
'Test case 1 - Noticable constant flickering in d3d mode, no flickering at all in opengl
Global DRV$="D3D", WIDTH% = NativeWidth, 	HEIGHT% = NativeHeight, DEPTH% = 32, VSYNC% = 1, DRAWTOBOTHBUFFERS% = 1,  CLEARSCREEN% = 0
'Global DRV$="OGL", WIDTH% = NativeWidth, 	HEIGHT% = NativeHeight, DEPTH% = 32, VSYNC% = 1, DRAWTOBOTHBUFFERS% = 1,  CLEARSCREEN% = 0

'Test case 2 - Both drivers act pretty much the same, constant flickering with a much bigger flicker/glitch at regular intervals ( about 2.5 seconds )
'Global DRV$="D3D", WIDTH% = 1024, 	HEIGHT% = 768, DEPTH% = 32, VSYNC% = 1, DRAWTOBOTHBUFFERS% = 1,  CLEARSCREEN% = 0
'Global DRV$="OGL", WIDTH% = 1024, 	HEIGHT% = 768, DEPTH% = 32, VSYNC% = 1, DRAWTOBOTHBUFFERS% = 1,  CLEARSCREEN% = 0

'Test Case 3 - Very bad constant flickering in d3d, smooth as silk in opengl
'Notice this is half of my monitors native resolution
'Global DRV$="D3D", WIDTH% = 800, HEIGHT% = 600, DEPTH% = 32, VSYNC% = 1, DRAWTOBOTHBUFFERS% = 1, CLEARSCREEN% = 0
'Global DRV$="OGL", WIDTH% = 800, HEIGHT% = 600, DEPTH% = 32, VSYNC% = 1,  DRAWTOBOTHBUFFERS% = 1, CLEARSCREEN% = 0

'Test Case 4 - Movement of starts quite smooth in both cases
'Global DRV$="D3D", WIDTH% = NativeWidth, 	HEIGHT% = NativeHeight, DEPTH% = 32, VSYNC% = 1, DRAWTOBOTHBUFFERS% = 0,  CLEARSCREEN% = 1
'Global DRV$="OGL", WIDTH% = NativeWidth, 	HEIGHT% = NativeHeight, DEPTH% = 32, VSYNC% = 1, DRAWTOBOTHBUFFERS% = 0,  CLEARSCREEN% = 1

'Test Case 5 - I can spot a noticeable judder of the stars movement at regular intervals
'Notice this is half of my monitors native resolution
'Global DRV$="D3D", WIDTH% = 800, HEIGHT% = 600, DEPTH% = 32, VSYNC% = 1, DRAWTOBOTHBUFFERS% = 0, CLEARSCREEN% = 1
'Global DRV$="OGL", WIDTH% = 800, HEIGHT% = 600, DEPTH% = 32, VSYNC% = 1,  DRAWTOBOTHBUFFERS% = 0, CLEARSCREEN% = 1

Global HERTZ% = 60
'======================================================================================================================================

'------------------------------------------------------------------------------------------------------------------------
' Start Program
If DRV="OGL" Then
	SetGraphicsDriver( GLMax2DDriver() ) 
Else
	SetGraphicsDriver( D3D7Max2DDriver() ) 
End If

Graphics WIDTH,HEIGHT,DEPTH,HERTZ

HideMouse

Const Star_Count:Int 	= 1500			' Stars Count
Const MAX_SIZE:Int		= 12        	' Maximum stars
Const MAX_ROTSPD!		= 50.0			' How much rotation goin on

Global Delta_X!, Delta_Y!, Delta_Ang! = 0, tick! = 0
Global DeltaTime:Double = 0.017

'------------------------------------------------------------------------------------------------------------------------
Type TSTARFIELD_Entity
	Field x:Double, y:Double
	Method Update() Abstract
	Method Draw() Abstract
EndType

'------------------------------------------------------------------------------------------------------------------------
Type TStar Extends TSTARFIELD_Entity

	Field s:Double
	Field size#			'Size of the star in both directions
	Field alp# 			'alpha blend values
	Field rot#
	Field tcol%[3]	
	Field vtype:Int
	Field rotv#

	Method Update( )
	
		Local cs!, sn!		'Sin and cos for global starfield rotation
		Local tx!, ty!		'Previous frame's coordinates
		
		'Move the stars out from the center
		x :+ Double( x - 319.99999 ) * ( s * DeltaTime )
		y :+ Double( y - 239.99999 ) * ( s * DeltaTime )

		x = x - 320
		y = y - 240
		
		cs = Cos( Delta_Ang )
		sn = Sin( Delta_Ang )

		tx = x
		ty = y
		
		'This is the rotation of the entire starfield
		x = tx * cs - ty * sn
		y = tx * sn + ty * Cs

		x = x + 320
		y = y + 240

		'Pitch Horizontal and Vertical
		x = x + ( Delta_X / s ) * 0.017
		y = y + ( Delta_Y / s ) * 0.017

		'Check screen edges
		'If( ( x < -300 ) Or ( x > WIDTH + 300 ) )
		If( ( x < 10 ) Or ( x > WIDTH - 10 ) )		
		x = Rnd ( WIDTH )
			alp = 0
		EndIf
		
		'If( ( y < -300 ) Or ( y > HEIGHT + 300 ) )
		If( ( y < 10 ) Or ( y > HEIGHT - 10 ) )
			y = Rnd( HEIGHT )
			alp = 0
		EndIf
		
		If( alp < 1 )
 			alp = alp + .05
		EndIf
		
		SetBlend( LIGHTBLEND )
		SetRotation( rot )
		SetAlpha( alp )
		
		'Update the star rotation
		rot = rot + rotv	
		
		Draw()
		
	End Method

	Method Draw( )
		SetBlend( LIGHTBLEND )
		SetColor( tcol[0], tcol[1], tcol[2] )
		
		Select( vtype )
			Case 0
				SetHandle( size * .5, .5 )
				DrawRect( x, y, size, 1 )
				SetHandle( .5, size * .5 )
				DrawRect( x, y, 1, size )
				SetHandle( 0, 0 )
			Case 1
				SetHandle( size * .5, size * .5 )
				DrawRect( x, y, size, size )
				SetHandle( 0, 0 )
		End Select
		
	End Method
	
	'Creates a new star
	Function CreateStar:TStar( )
		Local s:TStar = New TStar
		Local r% = Rand( 128 )
		s.x = Rnd( WIDTH )
		s.y = Rnd( HEIGHT )
		s.s = Rnd( 1, 2 )
		s.tcol = [ r, r, r ]
		s.size = Rnd( 1, MAX_SIZE )
		s.vtype = Rnd( 0, 1 )
		s.rotv = Rnd( -5.0, 5.0 )
		Return s
	EndFunction
	
End Type

'------------------------------------------------------------------------------------------------------------------------
Type TStarfield

	Field StarList:TList

	Method Init( )
		
		Local a%
		
		StarList = New TList
		
		'Initialise Stars
		For a= 0 To Star_Count-1
			StarList.AddLast( TStar.CreateStar() )
		Next 
		
	End Method 
	
	Method Update( )
		
		Delta_X = ( 1000 * Cos( tick ) ) * DeltaTime
		Delta_Y = ( 1000 * Sin( tick ) ) * DeltaTime
	
		Delta_Ang = ( MAX_ROTSPD * Cos( tick ) )  * DeltaTime
		tick = tick + .5
		
		Local c:TSTARFIELD_Entity
		
		For c = EachIn StarList
			c.Update
		Next
		
	End Method
	
	
	Method Draw()
		
		Local c:TSTARFIELD_Entity
		
		For c = EachIn StarList
			c.Draw()
		Next
		
	End Method
	
End Type

Local Starfield:TStarfield = New TStarfield
Starfield.Init( )

Cls
Flip
Cls

'------------------------------------------------------------------------------------------------------------------------
' Main Loop
While Not KeyHit( KEY_ESCAPE )
	
	If( CLEARSCREEN = 1 )
		Cls
	End If
	
	SetRotation( 0 )
	SetBlend( SOLIDBLEND )
	SetColor 32,32,32		'So I can see what ATI tray tools is writing in the top right of the screen!
	DrawRect( WIDTH-310, 0, WIDTH, 40 )
		
	Starfield.Update( )
	
	Flip( VSYNC )

	If( DRAWTOBOTHBUFFERS=1 )
		SetRotation( 0 )
		SetBlend( SOLIDBLEND )
		SetColor 32,32,32		'So I can see what ATI tray tools is writing in the top right of the screen!
		DrawRect( WIDTH-310, 0, WIDTH, 40 )
		
		Starfield.Draw() 	
		Flip( VSYNC )
	End If
	
Wend




It's a modified version of the starfield example from the blitzmax examples. I've set up lots of test case at the start of the program, please try uncommenting them one at a time and running the program. Hopefully it should be fairly obvious what is happening differently in each case.

I'd be very interested in whether or not people spot the same results as me.

As I think it could be a hardware thing, my spec is: Acer Ferrari laptop running into an external monitor. Athlon XP64 processor, ATI mobilty radeon 9700 and a Dell 2001fp LCD monitor ( native resolution 1600*1200 at 60hz ).

Thanks in advance to anyone who takes the time to help me out! :)

-duplicate post removed :)