Type TBrush

	Field no_texs
	Field no_shader_texs
	Field Name$
	Field red#=1.0,green#=1.0,blue#=1.0,alpha#=1.0
	Field shine#
	Field blend,fx
	Field tex_frame
	Field tex:TTexture[8]
	Field shadertex:TTexture[8]
	
	Field arb_program:tProgramObject
	Field use_Shader:Byte = False
	
	Method InitShader()
		If THardwareInfo.ShaderSupport Then
			arb_program = tprogramobject.Create(Name)
		Else
			Print "Sorry no Shader2.0 support"
		EndIf
	End Method
	
	Method AddShaderObject(_vert:String = Null , _frag:String = Null)
		If arb_program = Null Then Return
		Local Vert:TShaderObject
		Local Frag:TShaderObject
		
		If _Vert <> Null Then 
			Vert = CreateVertShader(_vert)
			arb_program.attachVertShader(Vert)
		EndIf
		
		If _frag <> Null Then 
			frag = CreateFragShader(_frag)
			arb_program.attachFragShader(frag)
		EndIf
	End Method
	
	Method ListShaders()
		If arb_program = Null Then Return
		arb_program.ListAttachedShaders()
	End Method
	
	Method ShaderActivate()
		If THardwareInfo.ShaderSupport Then
			use_Shader = True
		Else
			use_Shader = False
		EndIf
	End Method
	
	Method ShaderDeActivate()
		use_Shader = False
	End Method
	
	Method ProgramAttriBegin()
		If arb_program <> Null Then
			arb_program.Activate()
		End If
	End Method
	
	Method ProgramAttriEnd()
		If arb_program <> Null Then
			arb_program.DeActivate()
		End If
	End Method
	
	Method SetUI1(Name:String,para:Int)
		If arb_program <> Null Then
			arb_program.SetUI1(Name,para)
		EndIf
	End Method
	
	Method SetUI2(Name:String,para:Int,para1:Int)
		If arb_program <> Null Then
			arb_program.SetUI2(Name,para,para1)
		EndIf
	End Method
	
	Method SetUI3(Name:String,para:Int,para1:Int,para2:Int)
		If arb_program <> Null Then
			arb_program.SetUI3(Name,para,para1,para2)
		EndIf
	End Method
	
	Method SetUI4(Name:String,para:Int,para1:Int,para2:Int,para3:Int)
		If arb_program <> Null Then
			arb_program.SetUI4(Name,para,para1,para2,para3)
		EndIf
	End Method
	
	Method SetUF1(Name:String,para:Float)
		If arb_program <> Null Then
			arb_program.SetUF1(Name,para)
		EndIf
	End Method
	
	Method SetUF2(Name:String,para:Float,para1:Float)
		If arb_program <> Null Then
			arb_program.SetUF2(Name,para,para1)
		EndIf
	End Method
	
	Method SetUF3(Name:String,para:Float,para1:Float,para2:Float)
		If arb_program <> Null Then
			arb_program.SetUF3(Name,para,para1,para2)
		EndIf
	End Method
	
	Method SetUF4(Name:String,para:Float,para1:Float,para2:Float,para3:Float)
		If arb_program <> Null Then
			arb_program.SetUF4(Name,para,para1,para2,para3)
		EndIf
	End Method


	Method SetAF1(Name:String,para:Float)
		If arb_program <> Null Then
			arb_program.SetAF1(Name,para)
		EndIf
	End Method
	
	Method SetAF2(Name:String,para:Float,para1:Float)
		If arb_program <> Null Then
			arb_program.SetAF2(Name,para,para1)
		EndIf
	End Method
	
	Method SetAF3(Name:String,para:Float,para1:Float,para2:Float)
		If arb_program <> Null Then
			arb_program.SetAF3(Name,para,para1,para2)
		EndIf
	End Method
	
	Method SetAF4(Name:String,para:Float,para1:Float,para2:Float,para3:Float)
		If arb_program <> Null Then
			arb_program.SetAF4(Name,para,para1,para2,para3)
		EndIf
	End Method


	Method SetAS1(Name:String,para:Short)
		If arb_program <> Null Then
			arb_program.SetAS1(Name,para)
		EndIf
	End Method
	
	Method SetAS2(Name:String,para:Short,para1:Short)
		If arb_program <> Null Then
			arb_program.SetAS2(Name,para,para1)
		EndIf
	End Method
	
	Method SetAS3(Name:String,para:Short,para1:Short,para2:Short)
		If arb_program <> Null Then
			arb_program.SetAS3(Name,para,para1,para2)
		EndIf
	End Method
	
	Method SetAS4(Name:String,para:Short,para1:Short,para2:Short,para3:Short)
		If arb_program <> Null Then
			arb_program.SetAS4(Name,para,para1,para2,para3)
		EndIf
	End Method

	
	Method SetAD1(Name:String,para:Double)
		If arb_program <> Null Then
			arb_program.SetAD1(Name,para)
		EndIf
	End Method
	
	Method SetAD2(Name:String,para:Double,para1:Double)
		If arb_program <> Null Then
			arb_program.SetAD2(Name,para,para1)
		EndIf
	End Method
	
	Method SetAD3(Name:String,para:Double,para1:Double,para2:Double)
		If arb_program <> Null Then
			arb_program.SetAD3(Name,para,para1,para2)
		EndIf
	End Method
	
	Method SetAD4(Name:String,para:Double,para1:Double,para2:Double,para3:Short)
		If arb_program <> Null Then
			arb_program.SetAD4(Name,para,para1,para2,para3)
		EndIf
	End Method
	
	Method SetM2(Name:String,Matrix:Float[,],Trans:Int)
		If arb_program <> Null Then
			arb_program.SetM2(Name,Matrix,Trans)
		EndIf
	End Method
	
	Method SetM3(Name:String,Matrix:Float[,],Trans:Int)
		If arb_program <> Null Then
			arb_program.SetM3(Name,Matrix,Trans)
		EndIf
	End Method
	
	Method SetM4(Name:String,Matrix:Float[,],Trans:Int)
		If arb_program <> Null Then
			arb_program.SetM4(Name,Matrix,Trans)
		EndIf
	End Method


	Method BrushShaderTexture(texture:TTexture,index=0)
		shadertex[index]=texture
		If index+1>no_shader_texs Then no_shader_texs=index+1
	End Method
	
	Method Copy:TBrush()
		
		Local brush:TBrush=New TBrush
	
		brush.no_texs = no_texs
		brush.no_shader_texs = no_shader_texs
		brush.Name$=Name$
		brush.red#=red#
		brush.green#=green#
		brush.blue#=blue#
		brush.alpha#=alpha#
		brush.shine#=shine#
		brush.blend=blend
		brush.fx=fx
		brush.tex_frame=tex_frame
		brush.tex[0]=tex[0]
		brush.tex[1]=tex[1]
		brush.tex[2]=tex[2]
		brush.tex[3]=tex[3]
		brush.tex[4]=tex[4]
		brush.tex[5]=tex[5]
		brush.tex[6]=tex[6]
		brush.tex[7]=tex[7]
		
		brush.shadertex[0]=shadertex[0]
		brush.shadertex[1]=shadertex[1]
		brush.shadertex[2]=shadertex[2]
		brush.shadertex[3]=shadertex[3]
		brush.shadertex[4]=shadertex[4]
		brush.shadertex[5]=shadertex[5]
		brush.shadertex[6]=shadertex[6]
		brush.shadertex[7] = shadertex[7]
		
		brush.arb_program = arb_program
		brush.use_Shader = use_shader


					
		Return brush

	End Method
	
	Method FreeBrush()
	
	End Method
		
	Function CreateBrush:TBrush(r#=255.0,g#=255.0,b#=255.0)
	
		Local brush:TBrush=New TBrush
		brush.red#=r#/255.0
		brush.green#=g#/255.0
		brush.blue#=b#/255.0
		
		Return brush
		
	End Function
	
	Function LoadBrush:TBrush(file$,flags=1,u_scale#=1.0,v_scale#=1.0)
	
		Local brush:TBrush=New TBrush
		brush.tex[0]=TTexture.LoadTexture:TTexture(file$,flags)
		brush.no_texs=1
		'brush.tex[0].u_scale#=u_scale#
		'brush.tex[0].v_scale#=v_scale#
				
		Return brush
		
	End Function
	
	Method BrushColor(r#,g#,b#)
	
		red=r#/255.0
		green=g#/255.0
		blue=b#/255.0
	
	End Method
	
	Method BrushAlpha(a#)
	
		alpha#=a#
	
	End Method
	
	Method BrushShininess(s#)
	
		shine#=s#
	
	End Method
	
	Method BrushTexture(texture:TTexture,frame=0,index=0)
	
		tex[index]=texture
		If index+1>no_texs Then no_texs=index+1
		
		If frame<0 Then frame=0
		If frame>texture.no_frames-1 Then frame=texture.no_frames-1 
		tex_frame=frame
	
	End Method
	
	Method BrushBlend(blend_no)
	
		blend=blend_no
	
	End Method
	
	Method BrushFX(fx_no)
	
		fx=fx_no
	
	End Method
	
	Function GetEntityBrush:TBrush(ent:TEntity)
	
		Return ent.brush.Copy()
		
	End Function
	
	Function GetSurfaceBrush:TBrush(surf:TSurface)
	
		Return surf.brush.Copy()
	
	End Function
	
	' MiniB3D functions
	
	' Internal - not recommended for general use
	
	Function CompareBrushes(brush1:TBrush,brush2:TBrush)
	
		' returns true if specified brush1 has same properties as brush2

		If brush1=Null And brush2<>Null Then Return False
		If brush1<>Null And brush2=Null Then Return False
		If brush1<>Null And brush2<>Null
			If brush1.no_texs <> brush2.no_texs Then Return False
			If brush1.no_shader_texs<>brush2.no_shader_texs Then Return False

			If brush1.red#<>brush2.red# Then Return False
			If brush1.green#<>brush2.green# Then Return False
			If brush1.blue#<>brush2.blue# Then Return False
			If brush1.alpha#<>brush2.alpha# Then Return False
			If brush1.shine#<>brush2.shine# Then Return False
			If brush1.blend<>brush2.blend Then Return False
			If brush1.fx<>brush2.fx Then Return False
			For Local i=0 To 7
				If brush1.tex[i]=Null And brush2.tex[i]<>Null Then Return False
				If brush1.tex[i]<>Null And brush2.tex[i]=Null Then Return False
				If brush1.tex[i]<>Null And brush2.tex[i]<>Null
					If brush1.tex[i].gltex<>brush2.tex[i].gltex Then Return False
					If brush1.tex[i].blend<>brush2.tex[i].blend Then Return False
					If brush1.tex[i].coords<>brush2.tex[i].coords Then Return False
				EndIf
				
				If brush1.shadertex[i]=Null And brush2.shadertex[i]<>Null Then Return False
				If brush1.shadertex[i]<>Null And brush2.shadertex[i]=Null Then Return False
				If brush1.shadertex[i]<>Null And brush2.shadertex[i]<>Null
					If brush1.shadertex[i].gltex<>brush2.shadertex[i].gltex Then Return False
					If brush1.shadertex[i].blend<>brush2.shadertex[i].blend Then Return False
					If brush1.shadertex[i].coords<>brush2.shadertex[i].coords Then Return False
				EndIf

			Next
		EndIf
		
		Return True
	
	End Function
	
End Type
