A few little effects test programs.

Miscellaneous Forums/Blitz Showcase/A few little effects test programs.

EDIT: The locations for this stuff has changed to
http://www.scottshaver2000.com/site/template/template.php?page=examples

I've been playing with a number of different effects and thought I'd share, these are using BlitzMax 2D commands.

http://www.scottshaver2000.com/blitz/demo6/demo6.exe



http://www.scottshaver2000.com/blitz/demo6/plasma.exe



http://www.scottshaver2000.com/blitz/demo6/lines.exe



http://www.scottshaver2000.com/blitz/demo6/lines2.exe







MUCH cooler that the image below shows

http://www.scottshaver2000.com/blitz/demo6/lines3.exe







Looking good, reminds me of the Amiga days of demo's.

How did you do the sinewave text one? Split it into thin slices and draw each at a different x coord?

Here is the code for the rainbow color sin wave text. Basically I take the font image and create a set of data for each character that consists of the horizontal lines making up each character. In B+ you could just use the raw pixels but doing that in BMax is way too slow.

'=================================================================
' By: Scott Shaver
'=================================================================
Strict 

Framework BRL.GlMax2D
Import BRL.System
Import BRL.Basic
Import BRL.Retro
Import BRL.Max2D
Import BRL.pngloader

Graphics 640,480',32',60

'=================================================================
Incbin "mom_child.png"
Global mom:TImage = LoadImage("incbin::mom_child.png")
Global momImage:LineImage = LineImage.Create(mom)',0,255,255,255)

momImage.SetColorFunction(SetMomDrawColor) ' use this function to set the color when drawing

Incbin "hansolo_crisp.png"
Global font:TImage = LoadAnimImage("incbin::hansolo_crisp.png",32,32,0,128,FILTEREDIMAGE|MASKEDIMAGE|DYNAMICIMAGE)

Global lif:LineImageFont = LineImageFont.Create(font)
lif.SetColorFunction(SetFontDrawColor) ' use this function to set the color when drawing
lif.SetCoordFunction(SetFontCoordOffset) ' use this function to modify the draw coords

Global ang:Double=0
Global ang2:Double=0
Global tilt:Float=0
Global tiltOff:Float=.01

'=================================================================
While Not KeyHit(KEY_ESCAPE)
	Cls
	
	SetScale(1,1)
	lif.DrawFont(tilt,False)	
	
	SetScale(1,1)
	momImage.Draw(320+Cos(ang2)*220,240+Sin(ang2)*140,tilt,False)
	ang:+4
	ang2:+1
	'tilt:+tiltOff
	'If tiltOff>0 And tilt>1 Then tiltOff=-.01
	'If tiltOff<0 And tilt<-1 Then tiltOff=.01
	Flip
Wend
End

'=================================================================
Function SetMomDrawColor(x:Int,y:Int)
	SetColor(Abs(255*Cos(x+ang2)),Abs(255*Sin(y+ang2)),Abs(255*Cos(y+ang2)))
End Function

'=================================================================
Function SetFontDrawColor(x:Int,y:Int)
	SetColor(Abs(255*Cos(y+ang)),Abs(255*Sin(y+ang)),Abs(255*Cos(y+ang)))
End Function

'=================================================================
Function SetFontCoordOffset(x:Double Var,y:Double Var)
	x :+ Sin(y/.5+ang)*14
End Function

'=================================================================
' this type holds the coordinates for a line segment
'=================================================================
Type Line
	Field x1:Double,y1:Double,x2:Double,y2:Double
	Field SetDrawColor(x:Int,y:Int) = Null
	Field SetCoordOffset(x:Double Var,y:Double Var) = Null
	
	Method SetColorFunction(SetDrawColor(x:Int,y:Int))
		self.SetDrawColor = SetDrawColor
	End Method
	
	Method SetCoordFunction(SetCoordOffset(x:Double Var,y:Double Var))
		self.SetCoordOffset = SetCoordOffset
	End Method
	
	Function Create:Line(x1:Double,y1:Double,x2:Double,y2:Double)
		Local rval:Line = New Line
		rval.x1=x1
		rval.y1=y1
		rval.x2=x2
		rval.y2=y2
		Return rval
	End Function
	
	Method Draw(x:Double,y:Double,tilt:Float)
		If SetDrawColor<>Null Then
			SetDrawColor(x1+x,y1+y)
		EndIf
		Local dx:Double = x1+x+(tilt*y1)
		Local dy:Double = y1+y
		If SetCoordOffset<>Null Then SetCoordOffset(dx,dy)
		ScaleDrawRect(dx,dy,x2-x1,1)
	End Method
	
	Function ScaleDrawRect(x:Double,y:Double,w:Double,h:Double)
		Local sx:Float,sy:Float
		GetScale(sx,sy)
		If sx*x>GraphicsWidth() Or sy*y>GraphicsHeight() Then Return
		DrawRect(sx*x,sy*y,w,h)
	End Function
	
	Method DrawByPixel(x:Double,y:Double,tilt:Double)
		Local deltax:Double= Abs(x2 - x1)        ' The difference between the x's
		Local deltay:Double= Abs(y2 - y1)        ' The difference between the y's
		Local lx:Double= x1                       ' Start x off at the first pixel
		Local ly:Double= y1                       ' Start y off at the first pixel
		Local xinc1:Double= 0
		Local yinc1:Double= 0
		Local xinc2:Double= 0
		Local yinc2:Double= 0
		Local numadd:Double= 0
		Local numpixels:Double= 0
		Local den:Double= 0
		Local num:Double= 0
		
		If x2 >= x1 Then                 ' The x-values are increasing
		  xinc1 = 1
		  xinc2 = 1
		Else                          	' The x-values are decreasing
		  xinc1 = -1
		  xinc2 = -1
		EndIf
		
		If y2 >= y1 Then                 ' The y-values are increasing
		  yinc1 = 1
		  yinc2 = 1
		Else                          	' The y-values are decreasing
		  yinc1 = -1
		  yinc2 = -1
		EndIf
		
		If deltax >= deltay Then        ' There is at least one x-value For every y-value
		  xinc1 = 0                  ' Don't change the x when numerator >= denominator
		  yinc2 = 0                  ' Don't change the y for every iteration
		  den = deltax
		  num = deltax / 2
		  numadd = deltay
		  numpixels = deltax         ' There are more x-values than y-values
		Else                          ' There is at least one y-value For every x-value
		  xinc2 = 0                  ' Don't change the x for every iteration
		  yinc1 = 0                  ' Don't change the y when numerator >= denominator
		  den = deltay
		  num = deltay / 2
		  numadd = deltax
		  numpixels = deltay         ' There are more y-values than x-values
		EndIf
		
		For Local curpixel:Int = 0 To numpixels
			If SetDrawColor<>Null Then
				SetDrawColor(x1+x,y1+y)
			EndIf
			Local dx:Double = lx+x-(y1*tilt)
			Local dy:Double = ly+y
			If SetCoordOffset<>Null Then SetCoordOffset(dx,dy)
			ScaleDrawRect(dx,dy,1,1) ' draw the current pixel
			num :+ numadd              ' Increase the numerator by the top of the fraction
			If num >= den Then             ' Check If numerator >= denominator
				num :- den               ' Calculate the New numerator value
				lx :+ xinc1               ' Change the x as appropriate
				ly :+ yinc1               ' Change the y as appropriate
			EndIf
			lx :+ xinc2                 ' Change the x as appropriate
			ly :+ yinc2                 ' Change the y as appropriate
		Next

	End Method
	
End Type

'=================================================================
' an image made of line segments
'=================================================================
Type LineImage
	Field lines:Line[] = New Line[0]
	Field width:Int = 0
	Field height:Int = 0
	Field lineCount:Int = 0		
	
	Method SetColorFunction(SetDrawColor(x:Int,y:Int))
		For Local l:Int = 0 Until lineCount
			lines[l].SetColorFunction(SetDrawColor)
		Next
	End Method
	
	Method SetCoordFunction(SetCoordOffset(x:Double Var,y:Double Var))
		For Local l:Int = 0 Until lineCount
			lines[l].SetCoordFunction(SetCoordOffset)
		Next
	End Method
	
	Method Draw(x:Double,y:Double,tilt:Double,pixel:Byte=True)
		If pixel=True Then
			For Local l:Int = 0 Until lineCount
				lines[l].DrawByPixel(x,y,tilt)
			Next
		Else
			For Local l:Int = 0 Until lineCount
				lines[l].Draw(x,y,tilt)
			Next
		EndIf
	End Method
	
	Function Create:LineImage(image:TImage,frame:Int=0,r:Int=0,g:Int=0,b:Int=0)
		Local rval:LineImage = New LineImage
		
		Local pm:TPixmap = LockImage( image,frame)
		
		rval.width = PixmapWidth(pm)
		rval.height = PixmapHeight(pm)

		Local started:Byte=False
		Local sx:Int=-1
		Local ex:Int=-1
		For Local y:Int = 0 Until rval.height
			started=False
			sx=-1
			ex=-1
			
			For Local x:Int = 0 Until rval.width
				Local pix:Int = pm.ReadPixel(x,y)
										
				If started=False And (pix & $FF000000)<>0 And (pix & $00FFFFFF) | (r Shl 16|g Shl 8|b) <> 0 Then ' found SOL
					started=True
					sx = x
				Else If started=True And ((pix & $FF000000)=0 Or (pix & $00FFFFFF) | (r Shl 16|g Shl 8|b) = 0) Then ' found EOL
					ex = x-1
				EndIf
				If started=True And ex<>-1 Then
					Local l:Line = Line.Create(sx-(rval.width/2),y-(rval.height/2),ex-(rval.width/2),y-(rval.height/2))
					rval.lines = rval.lines[..(rval.lineCount+1)]
					rval.lines[rval.lineCount]=l
					rval.lineCount:+1
					started=False
					sx=-1
					ex=-1
				EndIf
			Next
			If started=True And ex=-1 Then
				ex=rval.width-1
				Local l:Line = Line.Create(sx-(rval.width/2),y-(rval.height/2),ex-(rval.width/2),y-(rval.height/2))
				rval.lines = rval.lines[..(rval.lineCount+1)]
				rval.lines[rval.lineCount]=l
				rval.lineCount:+1
			EndIf
		Next
		
		UnlockImage(image,frame)
		
		Return rval
	End Function
End Type

'=================================================================
' a font made of LineImage objects
'=================================================================
Type LineImageFont
	Field chars:LineImage[] = New LineImage[256]
	
	Method SetColorFunction(SetDrawColor(x:Int,y:Int))
		For Local c:Int = 0 To 127
			chars[c].SetColorFunction(SetDrawColor)
		Next
	End Method
	
	Method SetCoordFunction(SetCoordOffset(x:Double Var,y:Double Var))
		For Local l:Int = 0 To 127
			chars[l].SetCoordFunction(SetCoordOffset)
		Next
	End Method
	
	Function Create:LineImageFont(image:TImage,r:Int=0,g:Int=0,b:Int=0)
		Local rval:LineImageFont = New LineImageFont
		For Local c:Int = 0 To 127
			rval.chars[c] = LineImage.Create(image,c,r,g,b) 
		Next
		Return rval
	End Function
	
	Method DrawFont(tilt:Float=0,pixel:Byte=True)
		For Local y:Int=0 To 15
			For Local x:Int = 0 To 15
				If chars[(y*16)+x]<>Null Then 
					chars[(y*16)+x].Draw((x+1)*chars[0].width,(y+1)*chars[0].height,tilt,pixel)
				EndIf
			Next
		Next
	End Method
End Type


Only max2d commands ? How did you do the line3.exe one ? :)

Here is the code for the "wicked" scroller

'=================================================================
' By: Scott Shaver
'=================================================================
Strict 

Framework BRL.GlMax2D
Import BRL.System
Import BRL.Basic
Import BRL.Retro
Import BRL.Max2D
Import BRL.pngloader

Graphics 640,480,32',60

'=================================================================
Incbin "mom_child.png"
Global mom:TImage = LoadImage("incbin::mom_child.png")
Global momImage:LineImage = LineImage.Create(mom)',0,255,255,255)

momImage.SetColorFunction(SetMomDrawColor) ' use this function to set the color when drawing

Incbin "hansolo_crisp.png"
Global font:TImage = LoadAnimImage("incbin::hansolo_crisp.png",32,32,0,128,FILTEREDIMAGE|MASKEDIMAGE|DYNAMICIMAGE)

Global lif:LineImageFont = LineImageFont.Create(font,0,0,0,90,-1)
lif.SetColorFunction(SetFontDrawColor) ' use this function to set the color when drawing
'lif.SetCoordFunction(SetFontCoordOffset) ' use this function to modify the draw coords

Incbin "hbar.png"
Global hbar:TImage = LoadImage("incbin::hbar.png")
MidHandleImage(hbar)

Global ang:Double=0
Global ang2:Double=0
Global tilt:Float=0'.5
Global tiltOff:Float=.01
Global scrollerx:Float=GraphicsWidth()

SetClsColor(100,100,200)
'lif.rotate(0,75,0)
'=================================================================
While Not KeyHit(KEY_ESCAPE)
	Cls
	
	SetScale(1,1)
	'lif.DrawFont(tilt,False,0,0)	
	lif.rotate(4,0,0)
	
	SetScale(1,1)
	'momImage.Draw(320+Cos(ang2)*220,240+Sin(ang2)*140,tilt,False)
	'momImage.rotate(0,0,1)
	ang:+4
	ang2:+1
	'tilt:+tiltOff
	'If tiltOff>0 And tilt>1 Then tiltOff=-.01
	'If tiltOff<0 And tilt<-1 Then tiltOff=.01
	
	Local msg:String = "             WICKED SCROLLER! BROUGHT TO YOU BY ZPARTICLE! I HAVE ONLY EVER SEEN THIS IN ONE DEMO AND I THOUGHT IT WAS TOTALLY COOL!            "
	lif.DrawString(scrollerx,GraphicsHeight()/2,msg,0,0,0)
	If scrollerx<=-Len(msg)*32 Then scrollerx=GraphicsWidth()
	scrollerx:-1
	Flip
Wend
End

'=================================================================
Function SetMomDrawColor(x:Int,y:Int,z:Int)
	SetColor(Abs(255*Cos(x+ang2)),Abs(255*Sin(y+ang2)),Abs(255*Cos(y+ang2)))
End Function

'=================================================================
Function SetFontDrawColor(x:Int,y:Int,z:Int)
	'SetColor(Abs(255*Cos(y+ang)),Abs(255*Sin(y+ang)),Abs(255*Cos(y+ang)))
	SetColor(175+(5*z),175+(5*z),50+(5*z))
End Function

'=================================================================
Function SetFontCoordOffset(x:Double Var,y:Double Var)
	x :+ Sin(y/.25+ang)*4
End Function

'=================================================================
' this type holds the coordinates for a line segment
'=================================================================
Type Line
	Field x1:Double,y1:Double,x2:Double,y2:Double,z1:Double=15,z2:Double=15
	Field SetDrawColor(x:Int,y:Int,z:Int) = Null
	Field SetCoordOffset(x:Double Var,y:Double Var) = Null
	
	Method compare:Int(o:Object)
          Local s:Line = Line(o)
          If Not s Then Return 1
          Return z1 - s.z1
    End Method

	Method SetColorFunction(SetDrawColor(x:Int,y:Int,z:Int))
		self.SetDrawColor = SetDrawColor
	End Method
	
	Method SetCoordFunction(SetCoordOffset(x:Double Var,y:Double Var))
		self.SetCoordOffset = SetCoordOffset
	End Method
	
	Function Create:Line(x1:Double,y1:Double,x2:Double,y2:Double)
		Local rval:Line = New Line
		rval.x1=x1
		rval.y1=y1
		rval.x2=x2
		rval.y2=y2
		Return rval
	End Function
	
	'--------------------------------------------------------
	' rotate a point around the origin, we rotate in the following order x,y,z
	' xa,ya,za - The angle To rotate the point from its current position, in degrees
	Method rotate(xa:Double,ya:Double,za:Double)
		Local xx:Double = Cos(ya) * Cos(za)
		Local xy:Double = (Sin(xa) * Sin(ya) *Cos(za)) - (Cos(xa) * Sin(za))
		Local xz:Double = (Cos(xa) * Sin(ya) *Cos(za)) + (Sin(xa) * Sin(za))
	
		Local yx:Double = Cos(ya) * Sin(za)
		Local yy:Double = (Cos(xa) * Cos(za)) + (Sin(xa) * Sin(ya) * Sin(za))
		Local yz:Double = (-Sin(xa) * Cos(za)) + (Cos(xa) * Sin(ya) * Sin(za))
	
		Local zx:Double = -Sin(ya)
		Local zy:Double = Sin(xa) * Cos(ya)
		Local zz:Double = Cos(xa) * Cos(ya)
		
		Local nx:Double = (x1*xx)+(y1*xy)+(z1*xz)
		Local ny:Double = (x1*yx)+(y1*yy)+(z1*yz)
		Local nz:Double = (x1*zx)+(y1*zy)+(z1*zz)
		
		x1=nx
		y1=ny
		z1=nz
		
		nx = (x2*xx)+(y2*xy)+(z2*xz)
		ny = (x2*yx)+(y2*yy)+(z2*yz)
		nz = (x2*zx)+(y2*zy)+(z2*zz)
		
		x2=nx
		y2=ny
		z2=nz
	End Method
	
	'--------------------------------------------------------
	' rotate a point around the origin, we rotate in the following order x,y,z
	' xa,ya,za - The angle To rotate the point from its current position, in degrees
	Method TempRotate(xa:Double,ya:Double,za:Double,x1:Double Var,y1:Double Var,z1:Double Var,x2:Double Var,y2:Double Var,z2:Double Var)
		Local xx:Double = Cos(ya) * Cos(za)
		Local xy:Double = (Sin(xa) * Sin(ya) *Cos(za)) - (Cos(xa) * Sin(za))
		Local xz:Double = (Cos(xa) * Sin(ya) *Cos(za)) + (Sin(xa) * Sin(za))
	
		Local yx:Double = Cos(ya) * Sin(za)
		Local yy:Double = (Cos(xa) * Cos(za)) + (Sin(xa) * Sin(ya) * Sin(za))
		Local yz:Double = (-Sin(xa) * Cos(za)) + (Cos(xa) * Sin(ya) * Sin(za))
	
		Local zx:Double = -Sin(ya)
		Local zy:Double = Sin(xa) * Cos(ya)
		Local zz:Double = Cos(xa) * Cos(ya)
		
		Local nx:Double = (x1*xx)+(y1*xy)+(z1*xz)
		Local ny:Double = (x1*yx)+(y1*yy)+(z1*yz)
		Local nz:Double = (x1*zx)+(y1*zy)+(z1*zz)
		
		x1=nx
		y1=ny
		z1=nz
		
		nx = (x2*xx)+(y2*xy)+(z2*xz)
		ny = (x2*yx)+(y2*yy)+(z2*yz)
		nz = (x2*zx)+(y2*zy)+(z2*zz)
		
		x2=nx
		y2=ny
		z2=nz
	End Method
	
	Method Draw(x:Double,y:Double,tilt:Float, angle:Double=0)
		Global lasty:Double=-1
		Local x1:Double = self.x1
		Local y1:Double = self.y1
		Local z1:Double = self.z1
		Local x2:Double = self.x2
		Local y2:Double = self.y2
		Local z2:Double = self.z2
		
		If angle<>0 Then TempRotate(angle,0,0,x1,y1,z1,x2,y2,z2)

		If SetDrawColor<>Null Then
			SetDrawColor(x1+x,y1+y,z1)
		EndIf
		Local dx:Double = x1+x+(tilt*y1)
		Local dy:Double = y1+y
		If Abs(lasty-dy)>1 Then 'fill gaps between lines when wrapped around origin
			If SetCoordOffset<>Null Then SetCoordOffset(dx,dy)
			ScaleDrawRect(dx,dy-1,x2-x1,1)
		EndIf
			If SetCoordOffset<>Null Then SetCoordOffset(dx,dy)
			ScaleDrawRect(dx,dy,x2-x1,1)
	End Method
	
	Function ScaleDrawRect(x:Double,y:Double,w:Double,h:Double)
		Local sx:Float,sy:Float
		GetScale(sx,sy)
		If sx*x>GraphicsWidth() Or sy*y>GraphicsHeight() Then Return
		DrawRect(sx*x,sy*y,w,h)
	End Function
	
	Method DrawByPixel(x:Double,y:Double,tilt:Double)
		Local deltax:Double= Abs(x2 - x1)        ' The difference between the x's
		Local deltay:Double= Abs(y2 - y1)        ' The difference between the y's
		Local lx:Double= x1                       ' Start x off at the first pixel
		Local ly:Double= y1                       ' Start y off at the first pixel
		Local xinc1:Double= 0
		Local yinc1:Double= 0
		Local xinc2:Double= 0
		Local yinc2:Double= 0
		Local numadd:Double= 0
		Local numpixels:Double= 0
		Local den:Double= 0
		Local num:Double= 0
		
		If x2 >= x1 Then                 ' The x-values are increasing
		  xinc1 = 1
		  xinc2 = 1
		Else                          	' The x-values are decreasing
		  xinc1 = -1
		  xinc2 = -1
		EndIf
		
		If y2 >= y1 Then                 ' The y-values are increasing
		  yinc1 = 1
		  yinc2 = 1
		Else                          	' The y-values are decreasing
		  yinc1 = -1
		  yinc2 = -1
		EndIf
		
		If deltax >= deltay Then        ' There is at least one x-value For every y-value
		  xinc1 = 0                  ' Don't change the x when numerator >= denominator
		  yinc2 = 0                  ' Don't change the y for every iteration
		  den = deltax
		  num = deltax / 2
		  numadd = deltay
		  numpixels = deltax         ' There are more x-values than y-values
		Else                          ' There is at least one y-value For every x-value
		  xinc2 = 0                  ' Don't change the x for every iteration
		  yinc1 = 0                  ' Don't change the y when numerator >= denominator
		  den = deltay
		  num = deltay / 2
		  numadd = deltax
		  numpixels = deltay         ' There are more y-values than x-values
		EndIf
		
		For Local curpixel:Int = 0 To numpixels
			If SetDrawColor<>Null Then
				SetDrawColor(x1+x,y1+y,z1)
			EndIf
			Local dx:Double = lx+x-(y1*tilt)
			Local dy:Double = ly+y
			If SetCoordOffset<>Null Then SetCoordOffset(dx,dy)
			ScaleDrawRect(dx,dy,1,1) ' draw the current pixel
			num :+ numadd              ' Increase the numerator by the top of the fraction
			If num >= den Then             ' Check If numerator >= denominator
				num :- den               ' Calculate the New numerator value
				lx :+ xinc1               ' Change the x as appropriate
				ly :+ yinc1               ' Change the y as appropriate
			EndIf
			lx :+ xinc2                 ' Change the x as appropriate
			ly :+ yinc2                 ' Change the y as appropriate
		Next

	End Method
	
End Type

'=================================================================
' an image made of line segments
'=================================================================
Type LineImage
	Field lines:Line[] = New Line[0]
	Field width:Int = 0
	Field height:Int = 0
	Field lineCount:Int = 0		
	Field bar:Byte=False
	
	Method SetColorFunction(SetDrawColor(x:Int,y:Int,z1:Int))
		For Local l:Int = 0 Until lineCount
			lines[l].SetColorFunction(SetDrawColor)
		Next
	End Method
	
	Method SetCoordFunction(SetCoordOffset(x:Double Var,y:Double Var))
		For Local l:Int = 0 Until lineCount
			lines[l].SetCoordFunction(SetCoordOffset)
		Next
	End Method
	
	Method Draw(x:Double,y:Double,tilt:Double,pixel:Byte=True,angle:Double=0,inc:Double=0)
		lines.sort()
		If pixel=True Then
			For Local l:Int = 0 Until lineCount
				lines[l].DrawByPixel(x,y,tilt)
			Next
		Else
			Local drawBar:Byte=True
			For Local l:Int = 0 Until lineCount
				If bar=True And lines[l].z1>0 And drawBar=True Then
					Local sx:Float,sy:Float
					GetScale(sx,sy)
					drawBar=False
					SetColor(50,50,255)
					DrawImageRect(hbar,sx*x,sy*y,sx*width,sy*ImageHeight(hbar))
				EndIf
				lines[l].Draw(x,y,tilt,angle+(inc*l))
			Next
			If bar=True And drawBar=True Then
				Local sx:Float,sy:Float
				GetScale(sx,sy)
				drawBar=False
				SetColor(50,50,255)
				DrawImageRect(hbar,sx*x,sy*y,sx*width,sy*ImageHeight(hbar))
			EndIf			
		EndIf
	End Method
	
	'--------------------------------------------------------
	' rotate a point around the origin, we rotate in the following order x,y,z
	' xa,ya,za - The angle To rotate the point from its current position, in degrees
	Method rotate(xa:Double,ya:Double,za:Double)
		For Local l:Int = 0 Until lineCount
			lines[l].rotate(xa,ya,za)
		Next
	End Method
	
	Function Create:LineImage(image:TImage,frame:Int=0,r:Int=0,g:Int=0,b:Int=0,angle:Double=0,inc:Double=0)
		Local rval:LineImage = New LineImage
		
		Local pm:TPixmap = LockImage( image,frame)
		
		rval.width = PixmapWidth(pm)
		rval.height = PixmapHeight(pm)

		Local started:Byte=False
		Local sx:Int=-1
		Local ex:Int=-1
		For Local y:Int = 0 Until rval.height
			started=False
			sx=-1
			ex=-1
			
			For Local x:Int = 0 Until rval.width
				Local pix:Int = pm.ReadPixel(x,y)
										
				If started=False And (pix & $FF000000)<>0 And (pix & $00FFFFFF) | (r Shl 16|g Shl 8|b) <> 0 Then ' found SOL
					started=True
					sx = x
				Else If started=True And ((pix & $FF000000)=0 Or (pix & $00FFFFFF) | (r Shl 16|g Shl 8|b) = 0) Then ' found EOL
					ex = x-1
				EndIf
				If started=True And ex<>-1 Then
					Local l:Line = Line.Create(sx-(rval.width/2),y-(rval.height/2),ex-(rval.width/2),y-(rval.height/2))
					If angle<>0 Or inc<>0 Then l.rotate(angle+(inc*y),0,0)
					rval.lines = rval.lines[..(rval.lineCount+1)]
					rval.lines[rval.lineCount]=l
					rval.lineCount:+1
					started=False
					sx=-1
					ex=-1
				EndIf
			Next
			If started=True And ex=-1 Then
				ex=rval.width-1
				Local l:Line = Line.Create(sx-(rval.width/2),y-(rval.height/2),ex-(rval.width/2),y-(rval.height/2))
				If angle<>0 Or inc<>0 Then l.rotate(angle+(inc*y),0,0)
				rval.lines = rval.lines[..(rval.lineCount+1)]
				rval.lines[rval.lineCount]=l
				rval.lineCount:+1
			EndIf
		Next
		
		UnlockImage(image,frame)
		
		Return rval
	End Function
End Type

'=================================================================
' a font made of LineImage objects
'=================================================================
Type LineImageFont
	Field chars:LineImage[] = New LineImage[256]
	
	Method SetColorFunction(SetDrawColor(x:Int,y:Int,z:Int))
		For Local c:Int = 0 To 127
			chars[c].SetColorFunction(SetDrawColor)
		Next
	End Method
	
	Method SetCoordFunction(SetCoordOffset(x:Double Var,y:Double Var))
		For Local l:Int = 0 To 127
			chars[l].SetCoordFunction(SetCoordOffset)
		Next
	End Method
	
	'--------------------------------------------------------
	' rotate a point around the origin, we rotate in the following order x,y,z
	' xa,ya,za - The angle To rotate the point from its current position, in degrees
	Method rotate(xa:Double,ya:Double,za:Double)
		For Local l:Int = 0 To 127
			chars[l].rotate(xa,ya,za)
		Next
	End Method
	
	Function Create:LineImageFont(image:TImage,r:Int=0,g:Int=0,b:Int=0,angle:Double,inc:Double)
		Local rval:LineImageFont = New LineImageFont
		For Local c:Int = 0 To 127
			rval.chars[c] = LineImage.Create(image,c,r,g,b,angle,inc) 
			rval.chars[c].bar=True
		Next
		Return rval
	End Function
	
	Method DrawFont(tilt:Float=0,pixel:Byte=True,angle:Double=0,inc:Double=0)
		For Local y:Int=0 To 15
			For Local x:Int = 0 To 15
				If chars[(y*16)+x]<>Null Then 
					chars[(y*16)+x].Draw((x+1)*chars[0].width,(y+1)*(chars[0].height+20),tilt,pixel,angle,inc)
				EndIf
			Next
		Next
	End Method
	
	Method DrawString(x:Int,y:Int,msg:String,tilt:Float=0,angle:Double=0,inc:Double=0)
		Local spacing = chars[0].width
		Local msglen:Int = Len(msg)
		Local curx:Int = x
		' draw each character
		For Local i:Int = 1 To msglen
			' get the letter
			Local letter:String = Mid$(msg,i,1)
			' get the ascii code
			Local ccode:Int = Asc(letter$)
			chars[ccode].Draw(curx,y,.2,False,angle,inc)
			' move To the Next character position
			curx = curx + spacing
			'angle:+5 ' this gives a spiral effect
		Next
	End Method
	
End Type


Many thanks for this code Scott :)

Thanks. I'll bookmark this.

thanks dude

Not bad... Quick suggestion for the top demo: It would probably look a *lot* smoother if you would do an alphablend to fade the new characters into existence rather than just drawing them out of nowhere...

It makes it look a lot more choppy than it needs to be.

@everyone: you welcome, hope it comes in useful

@xlsior: yeah I tried that but couldn't get to look the way I wanted it. maybe I'll go back and try again. :)

Since people seem to like having the code to look at I've added a new section to my site, Examples/Snippets where I have and will continue to post this kind of stuff.

http://www.scottshaver2000.com

did you create these with a 32bit graphics depth?
they all crashed for me = thats probably why

that's weird, yes one of them is, ithink it's the plasma one. the rest are in windowed mode with no depth setting. The code is available so you should be able to compile them and make them work.

here is another one a real time water ripple effect. Code can be found on my site in the examples section. Click or click and drag on the image.

http://www.scottshaver2000.com/blitz/demo6/water.exe



neat, but seems a little fuzzy and somewhat choppy.

Hmmm, choppy as in the frame rate isn't smooth? What kind of box are you running and video card?

im not sure what this computer has, it belongs to the school and they barred access to the specs. But its generally pretty fast...

When I wave my mouse accros the screen, there are large chunks of space that dont ripple, and theres a quite large delay between updating the pixels, it might just be because it is running in window mode? i really dont know how max runs at all.