strage behavior on different GPUs with direct3d9

BlitzMax Forums/BlitzMax Programming/strage behavior on different GPUs with direct3d9

I changed the d3dx to one I had so you will need change it back to one you want to use.

Changes that I remember doing :)
If D3DDevice.CreateIndexBuffer(tri_array_size*INDEXSIZE,D3DUSAGE_WRITEONLY, D3D_INDEX_FORMAT, D3DPOOL_DEFAULT, IndexBufferObj, Null) <> D3D_OK Then
				Assert "Failed to create IB"
			EndIf


Need to multiply by indexsize since tri_array_size is number of elements not number of bytes added back D3DUSAGE_WRITEONLY directx9 debugger complained it needed to be there counter to documentation.

Method BeginScene()
		Direct3DDevice9.Clear(0,Null,D3DCLEAR_TARGET,clsColor,0,0);
    	Return Direct3DDevice9.BeginScene()=0
	End Method


You are expecting this to be true if succesful. All DirectX call return zero on succuss, if winapi returns HRESULT 0 means success.

There is a bunch of debug code i put in to track down to bad indexbuffer size.

Let me know if it now shows what you expect.

Doug




Strict

Global d3dx9Lib=LoadLibraryA( "d3dx9_35" )
If  d3dx9Lib Print "d3dx9Lib loaded"
Global D3DXMatrixPerspectiveFovLH( 	pOutMatrix:Float Ptr ,  fovy:Float,  Aspect:Float,  zn:Float,zf:Float ) "win32"=GetProcAddress( d3dx9Lib,"D3DXMatrixPerspectiveFovLH" )										
Global D3DXMatrixLookAtLH:Float Ptr(pOutMatrix:Float Ptr, pEyeVector:Float Ptr,  pAtVector:Float Ptr,pUpVector:Float Ptr ) "win32" = GetProcAddress( d3dx9Lib,"D3DXMatrixLookAtLH" )
Global _DX9GRAPHICSEXWINDOWCLASS:Byte Ptr="DX9WinClass".ToCString()


'#################################################################################### 


Local hwnd = CreateGameWindow(800,600)
Local d3d9Graphics:Direct3d = New Direct3d
d3d9Graphics._Init(hwnd,800,600,True)


'####################################################################################

TDXRenderable.D3DDevice = d3d9Graphics.GetDevice()
TDXCamera.D3DDevice = d3d9Graphics.GetDevice()
Local lpD3DDevice:IDirect3DDevice9 = d3d9Graphics.GetDevice()


'####################################################################################
	
Local cam:TDXCamera = New TDXCamera

Local cube:TDXMesh = New TDXMesh.CreateCube() 
cube.PositionEntity(- 1.5, 0, 0) 
'Rem
Local sphere:TDXMesh = New TDXMesh.CreateSphere() 
sphere.PositionEntity(1.5, 0, 0) 
'End Rem
'####################################################################################

Repeat

	If d3d9Graphics.BeginScene()

		cam.Update() 
		cube.TurnEntity(0.0, 0.6, 0.0) 
	sphere.TurnEntity(0.0, 0.6, 0.0) 
		cube.Update() 
		sphere.Update() 
		d3d9Graphics.EndScene()

	EndIf

	'lpD3DDevice.Present(Null,Null,Null,Null);

Until KeyHit(Key_Escape)
End




'####################################################################################

Type TDXCamera
	Global D3DDevice:IDirect3DDevice9
	
	Method Update() 
	
		Local ViewMatrix:Float[16] 
		Local pos:Float[] =[0.0, 0.0, - 10.0] 
		Local lookAt:Float[] =[0.0, 0.0, 0.0] 
		Local up:Float[] =[0.0, 1.0, 0.0] 
    	D3DXMatrixLookAtLH(ViewMatrix, pos, lookAt, up) 
    	D3DDevice.SetTransform(D3DTS_VIEW, ViewMatrix) 

		Local ProjMatrix:Float[16] 
	    D3DXMatrixPerspectiveFovLH(ProjMatrix, Pi / 4, 800.0 / 600.0, 1.0, 300.0) 
	    D3DDevice.SetTransform(D3DTS_PROJECTION, ProjMatrix) 
		
	End Method
	
End Type

'####################################################################################

Type TDXRenderable

	Const VERTEXSIZE:Int = 44
	Const INDEXSIZE:Int = 2
	'                                  12            12              4             8              8
	Global D3D_VERTEX_FORMAT:Int = (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX0 | D3DFVF_TEX1) 
	Global D3D_INDEX_FORMAT:Int = D3DFMT_INDEX16
	Global D3DDevice:IDirect3DDevice9
	
	Field VertexBufferObj:IDirect3DVertexBuffer9
	Field verts:Byte Ptr
	Field no_verts:Int
	Field vert_array_size:Int
	
	Field IndexBufferObj:IDirect3DIndexBuffer9
	Field tris:Short[] 
	Field no_tris:Int
	Field tri_array_size:Int
	
	Field mat:TMatrix
	
	Method New() 
		verts = MemAlloc(1) 
		vert_array_size = 1
		tri_array_size = 1
	End Method
	
	Method Delete() 
		MemFree verts
		tris = tris[..0] 
		If VertexBufferObj Then VertexBufferObj.Release_() 
		If IndexBufferObj Then IndexBufferObj.Release_() 
	End Method
	
	Method AddVertex:Int(x:Float, y:Float, z:Float, u:Float = 0.0, v:Float = 0.0, w:Float = 0.0) 
	
		no_verts:+1
		
		If no_verts * VERTEXSIZE > vert_array_size Then
			
			Local oldSize:Int = vert_array_size
			
			Repeat
				vert_array_size = vert_array_size * 2
			Until vert_array_size > no_verts * VERTEXSIZE
			Print "newsize"+vert_array_size
			Local tmp_verts:Byte Ptr = MemAlloc(vert_array_size) 
			MemCopy(tmp_verts, verts, oldSize) 
			MemFree(verts) 
			verts = tmp_verts
		
		EndIf
		
		Local vId:Int = (no_verts - 1) 
		SetVertexPos(vId, x, y, z) 
		SetVertexColor(vId, 1.0, 1.0, 1.0) 
		'SetVertexTexCoord(vId, u, v, 0) 
		'SetVertexTexCoord(vId, u, v, 1) 
		Return vId
		
	End Method
	
	Method SetVertexPos(vId:Int, x:Float, y:Float, z:Float) 
		vId:*VERTEXSIZE
		Local p:Float Ptr = Float Ptr(verts + vId ) 
		p[0] = x; p[1] = y; p[2] = z
	End Method
	
	Method SetVertexNormal(vId:Int, nx:Float, ny:Float, nz:Float) 
		vId:*VERTEXSIZE
		Local p:Float Ptr = Float Ptr(verts + vId + 12) 
		p[0] = nx; p[1] = ny; p[2] = nz
	End Method
	
	Method SetVertexColor(vId:Int, r:Float, g:Float, b:Float, a:Float = 1.0) 
		vId:*VERTEXSIZE
		Local p:Int Ptr = Int Ptr(verts + vId + 24) 
		'p[0] = Int((Int(a * 255.0) Shl 24) | (Int(r * 255.0) Shl 16) | (Int(g * 255.0) Shl 8) | Int(b * 255.0)) 
		p[0] = Int((255 Shl 24) | (Rand(0, 255) Shl 16) | (Rand(0, 255) Shl 8) | Rand(0, 255)) 
	End Method
	 
	Method SetVertexTexCoord(vId:Int, u:Float, v:Float, coord:Int) 
		vId = vId * VERTEXSIZE + coord * 8
		Local p:Float Ptr = Float Ptr(verts + vId + 28) 
		p[0] = u; p[1] = v
	End Method
	
	Method GetVertexPos:Float[] (vId:Int) 
		vId:*VERTEXSIZE
		Local p:Float Ptr = Float Ptr(verts + vId) 
		Return[p[0] , p[1] , p[2] ] 
	End Method
	
	Method GetVertexNormal:Float[] (vId:Int) 
		vId:*VERTEXSIZE
		Local p:Float Ptr = Float Ptr(verts + vId + 12) 
		Return[p[0] , p[1] , p[2] ] 
	End Method
	
	Method GetVertexColor:Float[] (vId:Int) 
		vId:*VERTEXSIZE
		Local color:Int = (Float Ptr(verts + vId + 24))[0] 
		Return[Float(((color & $ff000000) Shr 24) / 255.0), Float(((color & $00ff0000) Shr 16) / 255.0),  ..
			   Float(((color & $0000ff00) Shr 8) / 255.0), Float((color & $000000ff) / 255.0)] 
	End Method
	 
	Method GetVertexTexCoord:Float[] (vId:Int, coord:Int) 
		vId = vId * VERTEXSIZE + coord * 8
		Local p:Float Ptr = Float Ptr(verts + vId + 28) 
		Return[p[0] , p[1] ] 
	End Method
	
	Method AddTriangle:Int(v0:Int, v1:Int, v2:Int) 
	
		no_tris = no_tris + 1
		
		' resize array
		If no_tris * 3 >= tri_array_size
		
			Repeat
				tri_array_size=tri_array_size*2
			Until tri_array_size > no_tris * 3
		
			tris = tris[..tri_array_size] 
			
		EndIf
		
		Local vid:Int = (no_tris * 3) 
	
		tris[vid - 3] = v2
		tris[vid - 2] = v1
		tris[vid - 1] = v0
		
		Return no_tris
		
	End Method
	
	Method SetTriAngles:Int(start:Int, count:Int, triangles:Short Ptr, srcOffset:Int = 0) 
		If tris.length < start+count Then 
			tris = tris[..(start+count)]
			no_tris =  tris.length / 3
		EndIf 
		Local dstPtr:Byte Ptr = tris
		MemCopy(dstPtr+start*2, Byte Ptr(triangles)+srcOffset*2 , count*2 )  
	End Method 
	
	Method GetTriangles:Short Ptr() 
		Return tris
	End Method 
		
	Method OverrideVertexCount(count:Int) 
		no_verts = Count
	End Method
	
	Method OverrideTrisCount(count:Int)
		no_Tris = Count
	End Method
	
	Method Clear(clear_verts:Int = True, clear_tris:Int = True) 
	
		If clear_verts
			no_verts = 0
			MemFree verts		
			vert_array_size = 1
		EndIf
		
		If clear_tris
			no_tris = 0
			tris = tris[..0] 
			tri_array_size = 1
		EndIf
	
	End Method
	
	Method FreeVBO() 
		If VertexBufferObj Then VertexBufferObj.Release_() 
		If IndexBufferObj Then IndexBufferObj.Release_() 
	End Method
	
	Method SetMatrix(Matrix:TMatrix) 
		mat = Matrix
	End Method

	Method EnableVBO(vbo_enabled:Int) 
		If vbo_enabled Then
		    Print "VBSize"+vert_array_size
			If D3DDevice.CreateVertexBuffer(vert_array_size, D3DUSAGE_WRITEONLY, D3D_VERTEX_FORMAT, D3DPOOL_DEFAULT, VertexBufferObj, Null) <> D3D_OK Then
				Assert "Failed to create VB"
			EndIf
			Print "IBSize"+tri_array_size
			If D3DDevice.CreateIndexBuffer(tri_array_size*INDEXSIZE,D3DUSAGE_WRITEONLY, D3D_INDEX_FORMAT, D3DPOOL_DEFAULT, IndexBufferObj, Null) <> D3D_OK Then
				Assert "Failed to create IB"
			EndIf
		EndIf
	End Method

	Method Update()
		If D3DDevice.SetTransform(D3DTS_WORLD, mat.grid)  Print "Failed"
		If D3DDevice.SetFVF(D3D_VERTEX_FORMAT) Print "Failed"
		If D3DDevice.SetStreamSource(0, VertexBufferObj, 0, VERTEXSIZE) Print "Failed"
		If D3DDevice.SetIndices(IndexBufferObj) Print "Failed"
		If D3DDevice.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, no_verts, 0, no_tris) Print "Failed"
	End Method
	
	Method CountTriangles:Int() 
		Return no_tris
	End Method
	
	Method CountVertices:Int() 
		Return no_verts
	End Method
	
	Method UpdateVBO:Int(reset_vbo:Int Var) 
		
		If Not VertexBufferObj Or Not IndexBufferObj Or reset_vbo <> 0 Then
		
			EnableVBO(True) 
						
			Local VertexBufferStart:Byte Ptr
			Local IndexBufferStart:Byte Ptr
			
			If VertexBufferObj.Lock(0, no_verts * VERTEXSIZE, VertexBufferStart,0) = D3D_OK Then
				MemCopy(VertexBufferStart, verts, no_verts * VERTEXSIZE) 
				VertexBufferObj.Unlock() 
			EndIf
			 
			If IndexBufferObj.Lock(0, no_tris * 3 * INDEXSIZE, IndexBufferStart, 0) = D3D_OK Then
				MemCopy(IndexBufferStart, Byte Ptr(tris), no_tris * 3 * INDEXSIZE) 
				IndexBufferObj.Unlock() 
			Else
			    Print "Requested"+no_tris * 3 * INDEXSIZE
			    Print "Actual size"+tri_array_size
				Throw "Bad lock"	
			EndIf
			

			
			reset_vbo = False
			
		EndIf

		Return True
		
	End Method
	
End Type


Type TDXEntity
	
	Field rx:Float, ry:Float, rz:Float
	Field px:Float, py:Float, pz:Float
	Field sx:Float, sy:Float, sz:Float
	
	Field mat:TMatrix = New TMatrix
	
	Method New() 
		sx = 1.0; sy = 1.0; sz = 1.0
	End Method
	
	Method PositionEntity(x:Float, y:Float, z:Float) 
	
		px=x
		py=y
		pz = z
		UpdateMat(True) 
			
	End Method
	
	Method Turnentity(x:Float, y:Float, z:Float) 
	
		Local tx:Float = -x
		Local ty:Float = y
		Local tz:Float = z
				
		rx=rx+tx
		ry=ry+ty
		rz=rz+tz
		UpdateMat(True) 

	End Method
	
	Method RotateEntity(x:Float, y:Float, z:Float) 

		rx = -x
		ry = y
		rz = z
		UpdateMat(True) 
			
	End Method
	
	Method ScaleEntity(x:Float, y:Float, z:Float, glob = False) 

		sx = x
		sy = y
		sz = z
		UpdateMat(True) 
		
	End Method
	
	Method UpdateMat(load_identity = False) 

		If load_identity=True
			mat.LoadIdentity()
			mat.Translate(px,py,pz)
			mat.Rotate(rx,ry,rz)
			mat.Scale(sx,sy,sz)
		Else
			mat.Translate(px,py,pz)
			mat.Rotate(rx,ry,rz)
			mat.Scale(sx, sy, sz) 
		EndIf
	
	End Method
	

End Type


Type TDXSurface
	
	Field rederable:TDXRenderable = New TDXRenderable
	Field reset_vbo:Int
	Field new_bounds:Int
	
	Method Delete()
		rederable.FreeVBO() 
	End Method
	
	
	Method ClearSurface(clear_verts = True, clear_tris = True) 
		Self.rederable.Clear(clear_verts,clear_tris)
	End Method
			
	Method AddVertex(x#,y#,z#,u#=0.0,v#=0.0,w#=0.0)
		Return Self.rederable.AddVertex(x,y,z,u,v,W)
	End Method
	
	Method AddTriangle(v0,v1,v2)
		reset_vbo:|1 | 2 | 16
		new_bounds=True
		Return Self.rederable.AddTriangle(v0,v1,v2)
	End Method
	
	Method CountVertices()
		Return Self.rederable.CountVertices()
	End Method
	
	Method CountTriangles()
		Return Self.rederable.CountTriangles()
	End Method
	
	Method VertexCoords(vid,x#,y#,z#)
		Self.rederable.SetVertexPos(vid,x,y,z)
		reset_vbo:|1
	End Method
			
	Method VertexColor(vid,r#,g#,b#,a#=1.0)
		Self.rederable.SetVertexColor(vid,r,G,b,a)
		reset_vbo:|8
	End Method
	
	Method VertexNormal(vid,nx#,ny#,nz#)
		Self.rederable.SetVertexNormal(vid,nx#,ny#,nz#)
		reset_vbo:|4
	End Method
	
	Method VertexTexCoords(vid,u#,v#,w#=0.0,coord_set=0)
		Self.rederable.SetVertexTexCoord(vid,u#,v#,coord_set )	
		reset_vbo:|2
	End Method
		
	Method VertexX#(vid)
		Return Self.rederable.GetVertexPos(vid)[0]
	End Method

	Method VertexY#(vid)
		Return Self.rederable.GetVertexPos(vid)[1]
	End Method
	
	Method VertexZ#(vid)
		Return Self.rederable.GetVertexPos(vid)[2] 
	End Method
	
	Method VertexRed#(vid)
		Return Self.rederable.GetVertexColor(vid)[0]*255
	End Method
	
	Method VertexGreen#(vid)
		Return Self.rederable.GetVertexColor(vid)[1]*255
	End Method
	
	Method VertexBlue#(vid)
		Return Self.rederable.GetVertexColor(vid)[2]*255
	End Method
	
	Method VertexAlpha#(vid)
		Return Self.rederable.GetVertexColor(vid)[3]*255
	End Method
	
	Method VertexNX#(vid)
		Return Self.rederable.GetVertexNormal(vid)[0]
	End Method
	
	Method VertexNY#(vid)
		Return Self.rederable.GetVertexNormal(vid)[1]
	End Method
	
	Method VertexNZ#(vid)
		Return Self.rederable.GetVertexNormal(vid)[2]
	End Method
	
	Method VertexU#(vid,coord_set=0)
		Return Self.rederable.GetVertexTexCoord(vid,coord_set)[0]
	End Method
	
	Method VertexV#(vid,coord_set=0)
		Return Self.rederable.GetVertexTexCoord(vid,coord_set)[1]
	End Method
	
	Method VertexW#(vid,coord_set=0)
		Return 0
	End Method
	
	Method TriangleVertex(tri_no,corner)
		Local tris:Short Ptr = Self.rederable.GetTriAngles()
		Local vid[3]
		tri_no=(tri_no+1)*3
		vid[0]=tris[tri_no-1]
		vid[1]=tris[tri_no-2]
		vid[2]=tris[tri_no-3]
		Return vid[corner]
	End Method
	
	Method UpdateNormals()
		'rederable.UpdateNormals()
	End Method
	
	Method TriangleNX#(tri_no)

		Local v0=Self.TriangleVertex(tri_no,0)
		Local v1=Self.TriangleVertex(tri_no,1)
		Local v2=Self.TriangleVertex(tri_no,2)
	
		'Local ax#=VertexX#(v1)-VertexX#(v0)
		Local ay#=Self.VertexY#(v1)-Self.VertexY#(v0)
		Local az#=Self.VertexZ#(v1)-Self.VertexZ#(v0)
		
		'Local bx#=VertexX#(v2)-VertexX#(v1)
		Local by#=Self.VertexY#(v2)-Self.VertexY#(v1)
		Local bz#=Self.VertexZ#(v2)-Self.VertexZ#(v1)
		
		Return (ay#*bz#)-(az#*by#)
		
	End Method

	Method TriangleNY#(tri_no)
	
		Local v0=Self.TriangleVertex(tri_no,0)
		Local v1=Self.TriangleVertex(tri_no,1)
		Local v2=Self.TriangleVertex(tri_no,2)

		Local ax#=Self.VertexX#(v1)-Self.VertexX#(v0)
		'Local ay#=VertexY#(v1)-VertexY#(v0)
		Local az#=Self.VertexZ#(v1)-Self.VertexZ#(v0)
		
		Local bx#=Self.VertexX#(v2)-Self.VertexX#(v1)
		'Local by#=VertexY#(v2)-VertexY#(v1)
		Local bz#=Self.VertexZ#(v2)-Self.VertexZ#(v1)
	
		Return (az#*bx#)-(ax#*bz#)
			
	End Method

	Method TriangleNZ#(tri_no)
	
		Local v0=Self.TriangleVertex(tri_no,0)
		Local v1=Self.TriangleVertex(tri_no,1)
		Local v2=Self.TriangleVertex(tri_no,2)
		
		Local ax#=Self.VertexX#(v1)-Self.VertexX#(v0)
		Local ay#=Self.VertexY#(v1)-Self.VertexY#(v0)
		'Local az#=VertexZ#(v1)-VertexZ#(v0)
		
		Local bx#=Self.VertexX#(v2)-Self.VertexX#(v1)
		Local by#=Self.VertexY#(v2)-Self.VertexY#(v1)
		'Local bz#=VertexZ#(v2)-VertexZ#(v1)
		
		Return (ax#*by#)-(ay#*bx#)
		
	End Method
	
	Method UpdateVBO()
		Self.rederable.UpdateVBO(reset_vbo)
		Return True
	End Method
	
	Method FreeVBO()
		Self.rederable.FreeVBO()
		Return True
	End Method
	
End Type

Type TDXMesh Extends TDXEntity
	
	Field surf_list:TList = CreateList() 
	
	
	Method CreateCube:TDXMesh() 
		Local surf:TDXSurface = New TDXSurface
		
		'DebugStop
		surf.AddVertex(-1.0,-1.0,-1.0)
		surf.AddVertex(-1.0, 1.0,-1.0)
		surf.AddVertex( 1.0, 1.0,-1.0)
		surf.AddVertex( 1.0,-1.0,-1.0)
		
		surf.AddVertex(-1.0,-1.0, 1.0)
		surf.AddVertex(-1.0, 1.0, 1.0)
		surf.AddVertex( 1.0, 1.0, 1.0)
		surf.AddVertex( 1.0,-1.0, 1.0)
			
		surf.AddVertex(-1.0,-1.0, 1.0)
		surf.AddVertex(-1.0, 1.0, 1.0)
		surf.AddVertex( 1.0, 1.0, 1.0)
		surf.AddVertex( 1.0,-1.0, 1.0)
		
		surf.AddVertex(-1.0,-1.0,-1.0)
		surf.AddVertex(-1.0, 1.0,-1.0)
		surf.AddVertex( 1.0, 1.0,-1.0)
		surf.AddVertex( 1.0,-1.0,-1.0)

		surf.AddVertex(-1.0,-1.0, 1.0)
		surf.AddVertex(-1.0, 1.0, 1.0)
		surf.AddVertex( 1.0, 1.0, 1.0)
		surf.AddVertex( 1.0,-1.0, 1.0)
		
		surf.AddVertex(-1.0,-1.0,-1.0)
		surf.AddVertex(-1.0, 1.0,-1.0)
		surf.AddVertex( 1.0, 1.0,-1.0)
		surf.AddVertex( 1.0,-1.0,-1.0)

		surf.VertexNormal(0,0.0,0.0,-1.0)
		surf.VertexNormal(1,0.0,0.0,-1.0)
		surf.VertexNormal(2,0.0,0.0,-1.0)
		surf.VertexNormal(3,0.0,0.0,-1.0)
	
		surf.VertexNormal(4,0.0,0.0,1.0)
		surf.VertexNormal(5,0.0,0.0,1.0)
		surf.VertexNormal(6,0.0,0.0,1.0)
		surf.VertexNormal(7,0.0,0.0,1.0)
		
		surf.VertexNormal(8,0.0,-1.0,0.0)
		surf.VertexNormal(9,0.0,1.0,0.0)
		surf.VertexNormal(10,0.0,1.0,0.0)
		surf.VertexNormal(11,0.0,-1.0,0.0)
				
		surf.VertexNormal(12,0.0,-1.0,0.0)
		surf.VertexNormal(13,0.0,1.0,0.0)
		surf.VertexNormal(14,0.0,1.0,0.0)
		surf.VertexNormal(15,0.0,-1.0,0.0)
	
		surf.VertexNormal(16,-1.0,0.0,0.0)
		surf.VertexNormal(17,-1.0,0.0,0.0)
		surf.VertexNormal(18,1.0,0.0,0.0)
		surf.VertexNormal(19,1.0,0.0,0.0)
				
		surf.VertexNormal(20,-1.0,0.0,0.0)
		surf.VertexNormal(21,-1.0,0.0,0.0)
		surf.VertexNormal(22,1.0,0.0,0.0)
		surf.VertexNormal(23,1.0,0.0,0.0)

		surf.VertexTexCoords(0,0.0,1.0)
		surf.VertexTexCoords(1,0.0,0.0)
		surf.VertexTexCoords(2,1.0,0.0)
		surf.VertexTexCoords(3,1.0,1.0)
		
		surf.VertexTexCoords(4,1.0,1.0)
		surf.VertexTexCoords(5,1.0,0.0)
		surf.VertexTexCoords(6,0.0,0.0)
		surf.VertexTexCoords(7,0.0,1.0)
		
		surf.VertexTexCoords(8,0.0,1.0)
		surf.VertexTexCoords(9,0.0,0.0)
		surf.VertexTexCoords(10,1.0,0.0)
		surf.VertexTexCoords(11,1.0,1.0)
			
		surf.VertexTexCoords(12,0.0,0.0)
		surf.VertexTexCoords(13,0.0,1.0)
		surf.VertexTexCoords(14,1.0,1.0)
		surf.VertexTexCoords(15,1.0,0.0)
	
		surf.VertexTexCoords(16,0.0,1.0)
		surf.VertexTexCoords(17,0.0,0.0)
		surf.VertexTexCoords(18,1.0,0.0)
		surf.VertexTexCoords(19,1.0,1.0)
				
		surf.VertexTexCoords(20,1.0,1.0)
		surf.VertexTexCoords(21,1.0,0.0)
		surf.VertexTexCoords(22,0.0,0.0)
		surf.VertexTexCoords(23,0.0,1.0)

		surf.VertexTexCoords(0,0.0,1.0,0.0,1)
		surf.VertexTexCoords(1,0.0,0.0,0.0,1)
		surf.VertexTexCoords(2,1.0,0.0,0.0,1)
		surf.VertexTexCoords(3,1.0,1.0,0.0,1)
		
		surf.VertexTexCoords(4,1.0,1.0,0.0,1)
		surf.VertexTexCoords(5,1.0,0.0,0.0,1)
		surf.VertexTexCoords(6,0.0,0.0,0.0,1)
		surf.VertexTexCoords(7,0.0,1.0,0.0,1)
		
		surf.VertexTexCoords(8,0.0,1.0,0.0,1)
		surf.VertexTexCoords(9,0.0,0.0,0.0,1)
		surf.VertexTexCoords(10,1.0,0.0,0.0,1)
		surf.VertexTexCoords(11,1.0,1.0,0.0,1)
			
		surf.VertexTexCoords(12,0.0,0.0,0.0,1)
		surf.VertexTexCoords(13,0.0,1.0,0.0,1)
		surf.VertexTexCoords(14,1.0,1.0,0.0,1)
		surf.VertexTexCoords(15,1.0,0.0,0.0,1)
	
		surf.VertexTexCoords(16,0.0,1.0,0.0,1)
		surf.VertexTexCoords(17,0.0,0.0,0.0,1)
		surf.VertexTexCoords(18,1.0,0.0,0.0,1)
		surf.VertexTexCoords(19,1.0,1.0,0.0,1)
				
		surf.VertexTexCoords(20,1.0,1.0,0.0,1)
		surf.VertexTexCoords(21,1.0,0.0,0.0,1)
		surf.VertexTexCoords(22,0.0,0.0,0.0,1)
		surf.VertexTexCoords(23,0.0,1.0,0.0,1)
				
		surf.AddTriangle(0,1,2) ' front
		surf.AddTriangle(0,2,3)
		surf.AddTriangle(6,5,4) ' back
		surf.AddTriangle(7,6,4)
		surf.AddTriangle(6+8,5+8,1+8) ' top
		surf.AddTriangle(2+8,6+8,1+8)
		surf.AddTriangle(0+8,4+8,7+8) ' bottom
		surf.AddTriangle(0+8,7+8,3+8)
		surf.AddTriangle(6+16,2+16,3+16) ' right
		surf.AddTriangle(7+16,6+16,3+16)
		surf.AddTriangle(0+16,1+16,5+16) ' left
		surf.AddTriangle(0 + 16, 5 + 16, 4 + 16) 
		
		surf_list.AddLast(surf) 
		
		Return Self
	End Method
	
	' Function by Coyote
	Method CreateSphere:TDXMesh(segments = 8) 

		If segments<2 Or segments>100 Then Return Null
		
		Local thissurf:TDXSurface = New TDXSurface

		Local div#=Float(360.0/(segments*2))
		Local height#=1.0
		Local upos#=1.0
		Local udiv#=Float(1.0/(segments*2))
		Local vdiv#=Float(1.0/segments)
		Local RotAngle#=90	
	
		If segments=2 ' diamond shape - no center strips
		
			For Local i=1 To (segments*2)
				Local np=thissurf.AddVertex(0.0,height,0.0,upos#-(udiv#/2.0),0)'northpole
				Local sp=thissurf.AddVertex(0.0,-height,0.0,upos#-(udiv#/2.0),1)'southpole
				Local XPos#=-Cos(RotAngle#)
				Local ZPos#=Sin(RotAngle#)
				Local v0=thissurf.AddVertex(XPos#,0,ZPos#,upos#,0.5)
				RotAngle#=RotAngle#+div#
				If RotAngle#>=360.0 Then RotAngle#=RotAngle#-360.0
				XPos#=-Cos(RotAngle#)
				ZPos#=Sin(RotAngle#)
				upos#=upos#-udiv#
				Local v1=thissurf.AddVertex(XPos#,0,ZPos#,upos#,0.5)
				thissurf.AddTriangle(np,v0,v1)
				thissurf.AddTriangle(v1,v0,sp)	
			Next
			
		Else ' have center strips now
		
			' poles first
			For Local i=1 To (segments*2)
				
				Local np=thissurf.AddVertex(0.0,height,0.0,upos#-(udiv#/2.0),0)'northpole
				Local sp=thissurf.AddVertex(0.0,-height,0.0,upos#-(udiv#/2.0),1)'southpole
				
				Local YPos#=Cos(div#)
				
				Local XPos#=-Cos(RotAngle#)*(Sin(div#))
				Local ZPos#=Sin(RotAngle#)*(Sin(div#))
				
				Local v0t=thissurf.AddVertex(XPos#,YPos#,ZPos#,upos#,vdiv#)
				Local v0b=thissurf.AddVertex(XPos#,-YPos#,ZPos#,upos#,1-vdiv#)
				
				RotAngle#=RotAngle#+div#
				
				XPos#=-Cos(RotAngle#)*(Sin(div#))
				ZPos#=Sin(RotAngle#)*(Sin(div#))
				
				upos#=upos#-udiv#
	
				Local v1t=thissurf.AddVertex(XPos#,YPos#,ZPos#,upos#,vdiv#)
				Local v1b=thissurf.AddVertex(XPos#,-YPos#,ZPos#,upos#,1-vdiv#)
				
				thissurf.AddTriangle(np,v0t,v1t)
				thissurf.AddTriangle(v1b,v0b,sp)	
				
			Next
			
			' then center strips
	
			upos#=1.0
			RotAngle#=90
			For Local i=1 To (segments*2)
			
				Local mult#=1
				Local YPos#=Cos(div#*(mult#))
				Local YPos2#=Cos(div#*(mult#+1.0))
				Local Thisvdiv#=vdiv#
				For Local j=1 To (segments-2)
	
					
					Local XPos#=-Cos(RotAngle#)*(Sin(div#*(mult#)))
					Local ZPos#=Sin(RotAngle#)*(Sin(div#*(mult#)))
	
					Local XPos2#=-Cos(RotAngle#)*(Sin(div#*(mult#+1.0)))
					Local ZPos2#=Sin(RotAngle#)*(Sin(div#*(mult#+1.0)))
								
					Local v0t=thissurf.AddVertex(XPos#,YPos#,ZPos#,upos#,Thisvdiv#)
					Local v0b=thissurf.AddVertex(XPos2#,YPos2#,ZPos2#,upos#,Thisvdiv#+vdiv#)
				
					' 2nd tex coord set
					thissurf.VertexTexCoords(v0t,upos#,Thisvdiv#,0.0,1)
					thissurf.VertexTexCoords(v0b,upos#,Thisvdiv#+vdiv#,0.0,1)
				
					Local tempRotAngle#=RotAngle#+div#
				
					XPos#=-Cos(tempRotAngle#)*(Sin(div#*(mult#)))
					ZPos#=Sin(tempRotAngle#)*(Sin(div#*(mult#)))
					
					XPos2#=-Cos(tempRotAngle#)*(Sin(div#*(mult#+1.0)))
					ZPos2#=Sin(tempRotAngle#)*(Sin(div#*(mult#+1.0)))				
				
					Local temp_upos#=upos#-udiv#
	
					Local v1t=thissurf.AddVertex(XPos#,YPos#,ZPos#,temp_upos#,Thisvdiv#)
					Local v1b=thissurf.AddVertex(XPos2#,YPos2#,ZPos2#,temp_upos#,Thisvdiv#+vdiv#)
					
					' 2nd tex coord set
					thissurf.VertexTexCoords(v1t,temp_upos#,Thisvdiv#,0.0,1)
					thissurf.VertexTexCoords(v1b,temp_upos#,Thisvdiv#+vdiv#,0.0,1)
					
					thissurf.AddTriangle(v1t,v0t,v0b)
					thissurf.AddTriangle(v1b,v1t,v0b)
					
					Thisvdiv#=Thisvdiv#+vdiv#			
					mult#=mult#+1
					YPos#=Cos(div#*(mult#))
					YPos2#=Cos(div#*(mult#+1.0))
				
				Next
				upos#=upos#-udiv#
				RotAngle#=RotAngle#+div#
			Next
	
		EndIf
	
		'thissphere.UpdateNormals() 
	
		surf_list.AddLast(thissurf) 
		Return Self
	End Method
	
	Method Update() 
		For Local surf:TDXSurface = EachIn surf_list
			If surf.reset_vbo Then surf.UpdateVBO() 
			surf.rederable.SetMatrix(mat) 
			surf.rederable.Update() 
		Next
	End Method
	           
End Type

Type Direct3d

	Field clsColor				:Int 					= $FF000000
	Field Direct3D9 			:IDirect3D9				= Null 
	Field Direct3DDevice9		:IDirect3DDevice9		= Null
	Field BackBuffer			:IDirect3DSurface9 		= Null
	Field PParams				:D3DPRESENT_PARAMETERS  = Null
	Field hwnd					:Int 					= 0

	Method _Init(hwnd:Int, w:Int, h:Int, bWindowed:Int = False) 


		Self.hwnd = hwnd
		
		Direct3D9 = Direct3DCreate9( $900 )

		If Not Direct3D9  Then 
			Assert "error creating d3d9interface!"
		EndIf
		
		PParams = New D3DPRESENT_PARAMETERS
		
		PParams.SwapEffect       = D3DSWAPEFFECT_DISCARD;
	    PParams.hDeviceWindow    = hwnd;
	    PParams.Windowed         = bWindowed;
	    PParams.BackBufferWidth  = w;
	    PParams.BackBufferHeight = h;
	    PParams.BackBufferFormat = D3DFMT_A8R8G8B8;
		
		
		If Direct3D9.CreateDevice(0, D3DDEVTYPE_HAL, hwnd , D3DCREATE_PUREDEVICE | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, PParams, Direct3DDevice9) <> D3D_OK
			
			If Direct3D9.CreateDevice(0, D3DDEVTYPE_HAL, hwnd , D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, PParams, Direct3DDevice9) <> D3D_OK
				
				If Direct3D9.CreateDevice(0, D3DDEVTYPE_HAL, hwnd , D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, PParams, Direct3DDevice9) <> D3D_OK
				    Assert "failed To create device _D3dDev9"
				End If
				Print "Sofware"
			
			Else
			Print "hardware"
			End If
		Else
			Print "Pure"	
		EndIf
		


		Direct3DDevice9.GetBackBuffer(0,0, D3DBACKBUFFER_TYPE_MONO, BackBuffer );


		Direct3DDevice9.SetRenderState(D3DRS_AMBIENT, $00FFFFFF) 
		Direct3DDevice9.SetRenderState(D3DRS_LIGHTING, False) 
		Direct3DDevice9.SetRenderState(D3DRS_CULLMODE, D3DCULL_CW) 
		Direct3DDevice9.SetRenderState(D3DRS_DITHERENABLE, True) 
		

	End Method 

	Method SetClsColor(r:Int,g:Int,b:Int)
		clsColor = Int(( 255 Shl 24)| (r Shl 16)| (g Shl 8)| b )
	End Method 

	Method BeginScene()
		Direct3DDevice9.Clear(0,Null,D3DCLEAR_TARGET,clsColor,0,0);
    	Return Direct3DDevice9.BeginScene()=0
	End Method 

	Method EndScene()
		Direct3DDevice9.EndScene();
    	Direct3DDevice9.Present(Null,Null,Null,Null);
	End Method 

	Method GetDevice:IDirect3DDevice9()
		Return 	Direct3DDevice9
	End Method 

	Method GetBackBuffer:IDirect3DSurface9()
		Return BackBuffer
	End Method 

	Method SetAmbientLight(color:Int = $00FFFFFF)
		Direct3DDevice9.SetRenderState(D3DRS_AMBIENT, color) 
	End Method 

	Method SetLightningEnable(enable:Int)
		Direct3DDevice9.SetRenderState(D3DRS_LIGHTING, enable) 
	End Method 

	Method SetCullMode(mode:Int = D3DCULL_CW )
		Direct3DDevice9.SetRenderState(D3DRS_CULLMODE, mode ) 
	End Method 
	
	Method SetDitherEnable(enable:Int = True)
		Direct3DDevice9.SetRenderState(D3DRS_DITHERENABLE, enable) 
	End Method 

End Type

Type TMatrix

	Field grid#[4,4]
	

	
	Method LoadIdentity()
	
		grid[0,0]=1.0
		grid[1,0]=0.0
		grid[2,0]=0.0
		grid[3,0]=0.0
		grid[0,1]=0.0
		grid[1,1]=1.0
		grid[2,1]=0.0
		grid[3,1]=0.0
		grid[0,2]=0.0
		grid[1,2]=0.0
		grid[2,2]=1.0
		grid[3,2]=0.0
		
		grid[0,3]=0.0
		grid[1,3]=0.0
		grid[2,3]=0.0
		grid[3,3]=1.0
	
	End Method
	
	' copy - create new copy and returns it
	
	Method Copy:TMatrix()
	
		Local mat:TMatrix=New TMatrix
	
		mat.grid[0,0]=grid[0,0]
		mat.grid[1,0]=grid[1,0]
		mat.grid[2,0]=grid[2,0]
		mat.grid[3,0]=grid[3,0]
		mat.grid[0,1]=grid[0,1]
		mat.grid[1,1]=grid[1,1]
		mat.grid[2,1]=grid[2,1]
		mat.grid[3,1]=grid[3,1]
		mat.grid[0,2]=grid[0,2]
		mat.grid[1,2]=grid[1,2]
		mat.grid[2,2]=grid[2,2]
		mat.grid[3,2]=grid[3,2]
		
		' do not remove
		mat.grid[0,3]=grid[0,3]
		mat.grid[1,3]=grid[1,3]
		mat.grid[2,3]=grid[2,3]
		mat.grid[3,3]=grid[3,3]
		
		Return mat
	
	End Method
	
	' overwrite - overwrites self with matrix passed as parameter
	
	Method Overwrite(mat:TMatrix)
	
		grid[0,0]=mat.grid[0,0]
		grid[1,0]=mat.grid[1,0]
		grid[2,0]=mat.grid[2,0]
		grid[3,0]=mat.grid[3,0]
		grid[0,1]=mat.grid[0,1]
		grid[1,1]=mat.grid[1,1]
		grid[2,1]=mat.grid[2,1]
		grid[3,1]=mat.grid[3,1]
		grid[0,2]=mat.grid[0,2]
		grid[1,2]=mat.grid[1,2]
		grid[2,2]=mat.grid[2,2]
		grid[3,2]=mat.grid[3,2]
		
		grid[0,3]=mat.grid[0,3]
		grid[1,3]=mat.grid[1,3]
		grid[2,3]=mat.grid[2,3]
		grid[3,3]=mat.grid[3,3]
		
	End Method
	
	Method Inverse:TMatrix()

		Local mat:TMatrix=New TMatrix
	
		Local tx#=0
		Local ty#=0
		Local tz#=0
	
	  	' The rotational part of the matrix is simply the transpose of the
	  	' original matrix.
	  	mat.grid[0,0] = grid[0,0]
	  	mat.grid[1,0] = grid[0,1]
	  	mat.grid[2,0] = grid[0,2]
	
		mat.grid[0,1] = grid[1,0]
		mat.grid[1,1] = grid[1,1]
		mat.grid[2,1] = grid[1,2]
	
		mat.grid[0,2] = grid[2,0]
		mat.grid[1,2] = grid[2,1]
		mat.grid[2,2] = grid[2,2]
	
		' The right column vector of the matrix should always be [ 0 0 0 1 ]
		' in most cases. . . you don't need this column at all because it'll 
		' never be used in the program, but since this code is used with GL
		' and it does consider this column, it is here.
		mat.grid[0,3] = 0 
		mat.grid[1,3] = 0
		mat.grid[2,3] = 0
		mat.grid[3,3] = 1
	
		' The translation components of the original matrix.
		tx = grid[3,0]
		ty = grid[3,1]
		tz = grid[3,2]
	
		' Result = -(Tm * Rm) To get the translation part of the inverse
		mat.grid[3,0] = -( (grid[0,0] * tx) + (grid[0,1] * ty) + (grid[0,2] * tz) )
		mat.grid[3,1] = -( (grid[1,0] * tx) + (grid[1,1] * ty) + (grid[1,2] * tz) )
		mat.grid[3,2] = -( (grid[2,0] * tx) + (grid[2,1] * ty) + (grid[2,2] * tz) )
	
		Return mat

	End Method

	Method Multiply(mat:TMatrix)
	
		Local m00# = grid#[0,0]*mat.grid#[0,0] + grid#[1,0]*mat.grid#[0,1] + grid#[2,0]*mat.grid#[0,2] + grid#[3,0]*mat.grid#[0,3]
		Local m01# = grid#[0,1]*mat.grid#[0,0] + grid#[1,1]*mat.grid#[0,1] + grid#[2,1]*mat.grid#[0,2] + grid#[3,1]*mat.grid#[0,3]
		Local m02# = grid#[0,2]*mat.grid#[0,0] + grid#[1,2]*mat.grid#[0,1] + grid#[2,2]*mat.grid#[0,2] + grid#[3,2]*mat.grid#[0,3]
		'Local m03# = grid#[0,3]*mat.grid#[0,0] + grid#[1,3]*mat.grid#[0,1] + grid#[2,3]*mat.grid#[0,2] + grid#[3,3]*mat.grid#[0,3]
		Local m10# = grid#[0,0]*mat.grid#[1,0] + grid#[1,0]*mat.grid#[1,1] + grid#[2,0]*mat.grid#[1,2] + grid#[3,0]*mat.grid#[1,3]
		Local m11# = grid#[0,1]*mat.grid#[1,0] + grid#[1,1]*mat.grid#[1,1] + grid#[2,1]*mat.grid#[1,2] + grid#[3,1]*mat.grid#[1,3]
		Local m12# = grid#[0,2]*mat.grid#[1,0] + grid#[1,2]*mat.grid#[1,1] + grid#[2,2]*mat.grid#[1,2] + grid#[3,2]*mat.grid#[1,3]
		'Local m13# = grid#[0,3]*mat.grid#[1,0] + grid#[1,3]*mat.grid#[1,1] + grid#[2,3]*mat.grid#[1,2] + grid#[3,3]*mat.grid#[1,3]
		Local m20# = grid#[0,0]*mat.grid#[2,0] + grid#[1,0]*mat.grid#[2,1] + grid#[2,0]*mat.grid#[2,2] + grid#[3,0]*mat.grid#[2,3]
		Local m21# = grid#[0,1]*mat.grid#[2,0] + grid#[1,1]*mat.grid#[2,1] + grid#[2,1]*mat.grid#[2,2] + grid#[3,1]*mat.grid#[2,3]
		Local m22# = grid#[0,2]*mat.grid#[2,0] + grid#[1,2]*mat.grid#[2,1] + grid#[2,2]*mat.grid#[2,2] + grid#[3,2]*mat.grid#[2,3]
		'Local m23# = grid#[0,3]*mat.grid#[2,0] + grid#[1,3]*mat.grid#[2,1] + grid#[2,3]*mat.grid#[2,2] + grid#[3,3]*mat.grid#[2,3]
		Local m30# = grid#[0,0]*mat.grid#[3,0] + grid#[1,0]*mat.grid#[3,1] + grid#[2,0]*mat.grid#[3,2] + grid#[3,0]*mat.grid#[3,3]
		Local m31# = grid#[0,1]*mat.grid#[3,0] + grid#[1,1]*mat.grid#[3,1] + grid#[2,1]*mat.grid#[3,2] + grid#[3,1]*mat.grid#[3,3]
		Local m32# = grid#[0,2]*mat.grid#[3,0] + grid#[1,2]*mat.grid#[3,1] + grid#[2,2]*mat.grid#[3,2] + grid#[3,2]*mat.grid#[3,3]
		'Local m33# = grid#[0,3]*mat.grid#[3,0] + grid#[1,3]*mat.grid#[3,1] + grid#[2,3]*mat.grid#[3,2] + grid#[3,3]*mat.grid#[3,3]
	
		grid[0,0]=m00
		grid[0,1]=m01
		grid[0,2]=m02
		'grid[0,3]=m03
		grid[1,0]=m10
		grid[1,1]=m11
		grid[1,2]=m12
		'grid[1,3]=m13
		grid[2,0]=m20
		grid[2,1]=m21
		grid[2,2]=m22
		'grid[2,3]=m23
		grid[3,0]=m30
		grid[3,1]=m31
		grid[3,2]=m32
		'grid[3,3]=m33
		
	End Method

	Method Translate(x#,y#,z#)
	
		grid[3,0] = grid#[0,0]*x# + grid#[1,0]*y# + grid#[2,0]*z# + grid#[3,0]
		grid[3,1] = grid#[0,1]*x# + grid#[1,1]*y# + grid#[2,1]*z# + grid#[3,1]
		grid[3,2] = grid#[0,2]*x# + grid#[1,2]*y# + grid#[2,2]*z# + grid#[3,2]

	End Method
		
	Method Scale(x#,y#,z#)
	
		grid[0,0] = grid#[0,0]*x#
		grid[0,1] = grid#[0,1]*x#
		grid[0,2] = grid#[0,2]*x#

		grid[1,0] = grid#[1,0]*y#
		grid[1,1] = grid#[1,1]*y#
		grid[1,2] = grid#[1,2]*y#

		grid[2,0] = grid#[2,0]*z#
		grid[2,1] = grid#[2,1]*z#
		grid[2,2] = grid#[2,2]*z# 
	
	End Method
	
	Method Rotate(rx#,ry#,rz#)
	
		Local cos_ang#,sin_ang#
	
		' yaw
	
		cos_ang#=Cos(ry#)
		sin_ang#=Sin(ry#)
	
		Local m00# = grid#[0,0]*cos_ang + grid#[2,0]*-sin_ang#
		Local m01# = grid#[0,1]*cos_ang + grid#[2,1]*-sin_ang#
		Local m02# = grid#[0,2]*cos_ang + grid#[2,2]*-sin_ang#

		grid[2,0] = grid#[0,0]*sin_ang# + grid#[2,0]*cos_ang
		grid[2,1] = grid#[0,1]*sin_ang# + grid#[2,1]*cos_ang
		grid[2,2] = grid#[0,2]*sin_ang# + grid#[2,2]*cos_ang

		grid[0,0]=m00#
		grid[0,1]=m01#
		grid[0,2]=m02#
		
		' pitch
		
		cos_ang#=Cos(rx#)
		sin_ang#=Sin(rx#)
	
		Local m10# = grid#[1,0]*cos_ang + grid#[2,0]*sin_ang
		Local m11# = grid#[1,1]*cos_ang + grid#[2,1]*sin_ang
		Local m12# = grid#[1,2]*cos_ang + grid#[2,2]*sin_ang

		grid[2,0] = grid#[1,0]*-sin_ang + grid#[2,0]*cos_ang
		grid[2,1] = grid#[1,1]*-sin_ang + grid#[2,1]*cos_ang
		grid[2,2] = grid#[1,2]*-sin_ang + grid#[2,2]*cos_ang

		grid[1,0]=m10
		grid[1,1]=m11
		grid[1,2]=m12
		
		' roll
		
		cos_ang#=Cos(rz#)
		sin_ang#=Sin(rz#)

		m00# = grid#[0,0]*cos_ang# + grid#[1,0]*sin_ang#
		m01# = grid#[0,1]*cos_ang# + grid#[1,1]*sin_ang#
		m02# = grid#[0,2]*cos_ang# + grid#[1,2]*sin_ang#

		grid[1,0] = grid#[0,0]*-sin_ang# + grid#[1,0]*cos_ang#
		grid[1,1] = grid#[0,1]*-sin_ang# + grid#[1,1]*cos_ang#
		grid[1,2] = grid#[0,2]*-sin_ang# + grid#[1,2]*cos_ang#

		grid[0,0]=m00#
		grid[0,1]=m01#
		grid[0,2]=m02#
	
	End Method
	
	Method RotatePitch(ang#)
	
		Local cos_ang#=Cos(ang#)
		Local sin_ang#=Sin(ang#)
	
		Local m10# = grid#[1,0]*cos_ang + grid#[2,0]*sin_ang
		Local m11# = grid#[1,1]*cos_ang + grid#[2,1]*sin_ang
		Local m12# = grid#[1,2]*cos_ang + grid#[2,2]*sin_ang

		grid[2,0] = grid#[1,0]*-sin_ang + grid#[2,0]*cos_ang
		grid[2,1] = grid#[1,1]*-sin_ang + grid#[2,1]*cos_ang
		grid[2,2] = grid#[1,2]*-sin_ang + grid#[2,2]*cos_ang

		grid[1,0]=m10
		grid[1,1]=m11
		grid[1,2]=m12

	End Method
	
	Method RotateYaw(ang#)
	
		Local cos_ang#=Cos(ang#)
		Local sin_ang#=Sin(ang#)
	
		Local m00# = grid#[0,0]*cos_ang + grid#[2,0]*-sin_ang#
		Local m01# = grid#[0,1]*cos_ang + grid#[2,1]*-sin_ang#
		Local m02# = grid#[0,2]*cos_ang + grid#[2,2]*-sin_ang#

		grid[2,0] = grid#[0,0]*sin_ang# + grid#[2,0]*cos_ang
		grid[2,1] = grid#[0,1]*sin_ang# + grid#[2,1]*cos_ang
		grid[2,2] = grid#[0,2]*sin_ang# + grid#[2,2]*cos_ang

		grid[0,0]=m00#
		grid[0,1]=m01#
		grid[0,2]=m02#

	End Method
	
	Method RotateRoll(ang#)
	
		Local cos_ang#=Cos(ang#)
		Local sin_ang#=Sin(ang#)

		Local m00# = grid#[0,0]*cos_ang# + grid#[1,0]*sin_ang#
		Local m01# = grid#[0,1]*cos_ang# + grid#[1,1]*sin_ang#
		Local m02# = grid#[0,2]*cos_ang# + grid#[1,2]*sin_ang#

		grid[1,0] = grid#[0,0]*-sin_ang# + grid#[1,0]*cos_ang#
		grid[1,1] = grid#[0,1]*-sin_ang# + grid#[1,1]*cos_ang#
		grid[1,2] = grid#[0,2]*-sin_ang# + grid#[1,2]*cos_ang#

		grid[0,0]=m00#
		grid[0,1]=m01#
		grid[0,2]=m02#

	End Method
		
End Type



Type TRect
	Field _Left	:Int
	Field _Top	: Int
	Field _Right : Int
	Field _Bottom: Int
	
	Function Create:TRect(ALeft:Int,ATop:Int,ARight:Int,ABottom:Int)
		Local this:TRect=New TRect
		this._Left=ALeft
		this._Top=ATop
		this._Right=ARight		
		this._Bottom=ABottom
		Return this
	End Function
	Method Width:Int()
		Return _Right-_Left
	End Method
	Method Height:Int()
		Return _Bottom-_Top
	End Method
End Type

Function WndProc:Int( hwnd:Int,message:Int,wp:Int,lp:Int ) "win32"
	bbSystemEmitOSEvent hwnd,message,wp,lp,Null
	Select message
	Case WM_CLOSE
		End 
	Case WM_SYSKEYDOWN
		If wp<>KEY_F4 Return 0
	' ensure the valid Flag is current due to mode/focus changes	
	Case WM_SETFOCUS		
		'_dx9driver.ValidateGraphics
	' ensure the valid Flag is current due to mode/focus changes		
	Case WM_KILLFOCUS
		'_dx9driver.ValidateGraphics
	End Select
	Return DefWindowProcA( hwnd,message,wp,lp )
End Function

Function CreateGameWindow:Int(width:Int, height:Int )
	Local wc:WNDCLASS=New WNDCLASS
	wc.hInstance = GetModuleHandleA(0) 
	wc.lpfnWndProc = WndProc
	wc.hCursor=LoadCursorA( Null,Byte Ptr IDC_ARROW )
	wc.lpszClassName=_DX9GRAPHICSEXWINDOWCLASS
	RegisterClassA( wc )

	Local hinst:Int = GetModuleHandleA(0) 
	Local title:Byte Ptr=AppTitle.ToCString()
	
	Local hwnd:Int
	width:Int = 800
	height:Int = 600
	Local style:Int=WS_VISIBLE|WS_CAPTION|WS_SYSMENU |WS_SIZEBOX 
	Local rect :TRect = TRect.Create(32,32,width+32,height+32)
	AdjustWindowRect Int Ptr Byte Ptr rect,style,0
	width=rect.Width()
	height=rect.Height()

	hwnd=CreateWindowExA( 0,_DX9GRAPHICSEXWINDOWCLASS,title,style,rect._Left,rect._Top,width,height,0,0,hinst,Null )
	Return hwnd
End Function