strage behavior on different GPUs with direct3d9

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

So, here's the sample with latest changes. Instead of using my Direct3d type for initialization, you ca also use your driver with only comment out:

If _flags & GRAPHICS_DEPTHBUFFER
			'_PresentParams.EnableAutoDepthStencil = True ' true if we want z-buffer
			'_PresentParams.AutoDepthStencilFormat=D3DFMT_D16			
		End If	
		If _flags & GRAPHICS_STENCILBUFFER
			'_PresentParams.EnableAutoDepthStencil=True ' true if we want z-buffer
			'_PresentParams.AutoDepthStencilFormat=D3DFMT_D24S8			
		End If


Warning, it's ~1200 lines of code because of TMatrix and TSurface from miniB3d.
TSurface is completely adjusted to TRenderable, which is normaly an interface implementation...
Strict

Global d3dx9Lib=LoadLibraryA( "d3dx9d_33" )
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()
Global D3DXVec3TransformCoord:Float ptr(pOutVector:Float ptr,  pV:Float ptr, pM:Float ptr ) "win32" = GetProcAddress( d3dx9Lib,"D3DXVec3TransformCoord" )

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


local hwnd = CreateGameWindow(800,600)
Local d3d9Graphics:Direct3d = New Direct3d
d3d9Graphics._Init(hwnd,800,600,true)
d3d9Graphics.SetClsColor(255,255,255)

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

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) 

Local sphere:TDXMesh = New TDXMesh.CreateSphere() 
sphere.PositionEntity(1.5, 0, 0) 

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

local e:TDXEntity = new TDXEntity 
e.PositionEntity(0, 0, -10)

cam.SetMatrix(e.mat)
cam.SetViewport(10,10,780,580) 
cam.SetClippingPlanes(1,2000)



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() 
		lpD3DDevice.EndScene()

	EndIf

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

until KeyHit(Key_Escape)
End




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

Type TDXCamera

	Global D3DDevice:IDirect3DDevice9
	
	Global vUp		:Float[] = [0.0,1.0,0.0]
	Global vLook	:Float[] = [0.0,0.0,1.0]

	Field vLookAt		:Float[3]
	Field vWorldUp		:Float[3]
	Field vWorldLook	:Float[3]
	Field mView			:Float[16]				
	Field mProj			:Float[16]				
	Field viewport		:D3DVIEWPORT9 = New D3DVIEWPORT9					  
	Field Zoom			:Float	= 1.0			  
	Field ClearColor	:Int = $FF000000
	Field ClsMode		:Int = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER 

	field mat:TMatrix

	method SetMatrix(m:tMatrix)
		mat = m
	end method 

	method Clear()
		D3DDevice.Clear(0,Null, ClsMode, ClearColor,1.0,0)
	end method 

	method UpdateViewPort()
		D3DDevice.SetViewport( Byte ptr(viewport) ) 
	end method 

	method Update()
		UpdateViewPort()
		Clear()
		UpdateView() 
	end method 

	Method UpdateView() 
	
		' Only rotation values are needed
		Local mCam:TMatrix = mat.Copy()
		mCam.grid[3,0] = 0.0
		mCam.grid[3,1] = 0.0
		mCam.grid[3,2] = 0.0
		
		' Transform vectors based on camera's rotation matrix
	   	D3DXVec3TransformCoord( vWorldUp, vUp, mCam.grid )
	    D3DXVec3TransformCoord( vWorldLook, vLook, mCam.grid )
		 
	    'Update the lookAt position based on the eye position 
		Local vPos:Float[] = [mat.grid[3,0],mat.grid[3,1],mat.grid[3,2]]
		vLookAt[0] = vWorldLook[0] + vPos[0]
		vLookAt[1] = vWorldLook[1] + vPos[1]
		vLookAt[2] = vWorldLook[2] + vPos[2]

		 ' Update the view matrix
    	D3DXMatrixLookAtLH(mView, vPos, vLookAt, vUp) 
    	D3DDevice.SetTransform(D3DTS_VIEW, mView) 

		' Init Projection Matrix
	    D3DXMatrixPerspectiveFovLH(mProj, Pi / 4, 800.0 / 600.0, 1.0, 300.0) 
	    D3DDevice.SetTransform(D3DTS_PROJECTION, mProj) 
		
	End Method

	Method SetViewport(x:Int, y:Int, width:Int, height:Int) 
		viewport.X = x
		viewport.Y = y
		viewport.WIDTH = WIDTH
		viewport.HEIGHT = HEIGHT											
	End Method 
	
	Method SetClippingPlanes(n:Float,f:Float)
		viewport.MinZ = n
		viewport.MaxZ = f									
	End Method 
	
	Method SetZoom(zoom:Float)
		Zoom = zoom				 									
	End Method 
	
	Method SetClsMode(p:Int, d:Int)
		ClsMode = 0
		If p Then
			ClsMode = ClsMode | D3DCLEAR_TARGET
		End If
		If d Then
			ClsMode = ClsMode | D3DCLEAR_ZBUFFER
		End If				 									
	End Method 
	
	Method SetClsColor(r:Float, g:Float , b:Float, a:Float = 1.0)
		ClearColor = $ff000000|(Int(r) Shl 16)|(Int(G) Shl 8)|Int(b)			
	End Method 

	 Method GetViewport:Int[]() 
		Return [viewport.X, viewport.Y, viewport.WIDTH, viewport.HEIGHT]
	End Method
	
End Type

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

Type TDXRenderable

	Const VERTEXSIZE:Int = 44
	Const INDEXSIZE:Int = 2
	
	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
			
			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) 
		
		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
			If D3DDevice.CreateVertexBuffer(vert_array_size, 0, D3D_VERTEX_FORMAT, D3DPOOL_DEFAULT, VertexBufferObj, Null) <> D3D_OK Then
				Assert "Failed to create VB"
			EndIf
			If D3DDevice.CreateIndexBuffer(tri_array_size, 0, D3D_INDEX_FORMAT, D3DPOOL_DEFAULT, IndexBufferObj, Null) <> D3D_OK Then
				Assert "Failed to create IB"
			EndIf
		EndIf
	End Method

	Method Update() 
		D3DDevice.SetTransform(D3DTS_WORLD, mat.grid) 
		D3DDevice.SetFVF(D3D_VERTEX_FORMAT) 
		D3DDevice.SetStreamSource(0, VertexBufferObj, 0, VERTEXSIZE) 
		D3DDevice.SetIndices(IndexBufferObj) 
		D3DDevice.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, no_verts, 0, no_tris) 
	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, D3DLOCK_NOSYSLOCK) = D3D_OK Then
				MemCopy(VertexBufferStart, verts, no_verts * VERTEXSIZE) 
				VertexBufferObj.Unlock() 
			EndIf
			 
			If IndexBufferObj.Lock(0, no_tris * 3 * INDEXSIZE, IndexBufferStart, D3DLOCK_NOSYSLOCK) = D3D_OK Then
				MemCopy(IndexBufferStart, Byte Ptr(tris), no_tris * 3 * INDEXSIZE) 
				IndexBufferObj.Unlock() 
			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;

		PParams.EnableAutoDepthStencil = True 
		PParams.AutoDepthStencilFormat=D3DFMT_D16	
		
		
		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
			End If
		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();
    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


Edit:
hmm, if I create the window with CreateWindowExA insted of using a maxgui window, the programm also chrashes at device.present, when using D3DCREATE_SOFTWARE_VERTEXPROCESSING...same as using your d3d9GraphicsDriver :)

Edit:
ok, _PresentParams.EnableAutoDepthStencil = True works also fine...I yust must clear the zBuffer( Field ClsMode :Int = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER ) :)