flkr - Extreme

Miscellaneous Forums/Blitz Showcase/flkr - Extreme

I'm intruiged by new tech simulating old tech. One thing I've been playing with recently is attempting to simulate phosphor burn - ie. A pixel burns brighter the longer it's on the screen and fades slowly when removed. You get this effect on the old Vector Screens like the ones used in the original Asteroids game. So some time back I released the glowing lines mod that I see many people using today to create a nice glow effect to thier vector games. I wanted to add something more to that, something that would offer very subtle or very extreme effects. So I borrowed some old feedback/motion blur code of mine from the Morphlings games - here is the result.


http://indiepath.com/tim/extreme.rar

And the code.
Strict

Import indiepath.texturedpoly
Import indiepath.projmatrix

Global vObjectList:TList = New TList

Type vObject

	Field x#
	Field y#
	Field color1
	Field color2
	Field size#
	Field angle#
	Field rot#
	Field sides
	Field vx#
	Field vy#
	
	Method New ()
            	If vObjectList = Null Then vObjectList = New TList
            	vObjectList.AddLast Self
    	End Method	
	
	Function Create(x#,y#,size#,angle#,sides:Int)
		Local v:vObject = New vObject
		v.x = x
		v.y = y
		v.size = size
		v.angle = angle
		v.sides = sides
		v.color1 = Rand($FF222222,$FFFFFFFF)
		v.color2 = Rand($FF222222,$FFFFFFFF)

		v.vx = Rnd(-1,1)
		v.vy = Rnd(-1,1)
		v.rot = Rnd(-4,4)
	End Function
	
	Method Draw(image:tImage,frame:Int)
		DrawGeom(image,frame,self.x,self.y,self.sides,self.size,self.angle,self.color1,self.color2)
	End Method
	
	Method Update()
		x:+ vx
		y:+ vy
		angle:+ rot
		If angle > 360 Then angle:-360
		If angle < 0 Then angle:+360
		If x < 0 Then x:+480
		If x >480 Then x:-480
		If y < 0 Then y:+360
		If y > 360 Then y:-360
	End Method
	
	Function DrawAll(image:Timage,frame:Int)
	
		TPoly._Begin()
	
		For Local v:vObject = EachIn vObjectList
			v.Update()
			v.Draw(image,frame)
		Next
		
		TPoly._End()
	End Function
	
End Type


' //////////////****************************************************///////////////////////
' //////////////****************************************************///////////////////////
' //////////////****************************************************///////////////////////


Function DrawGeom(image:tImage,frame:Int,x#,y#,sides#,length#,angle#,c1:Int,c2:Int)

	Local aStep# = 360.0 / sides
	Length# = (length/2)/Sin(aStep#/2)  		
	
	'Local temp# = ((Sin(MilliSecs()/5) + 1) * 10) + 10
				
	For Local a:Float = 0 To sides-1
		Local x1# = x# - (Sin(angle + (aStep * a))*length)
		Local y1# = y# - (Cos(angle + (aStep * a))*length)
		Local x2# = x# - (Sin(angle + (aStep * (a+1)))*length)
		Local y2# = y# - (Cos(angle + (aStep * (a+1)))*length)
		TPoly.Line(image,frame,x1,y1,c1,x2,y2,c2,20,True,True)	
	Next
	
End Function

' //////////////****************************************************///////////////////////
' //////////////****************************************************///////////////////////
' //////////////****************************************************///////////////////////


AppTitle = "Subtle Glow - NOT!"

Graphics 640,480,0

projectionmatrix.Initialise(480,360)
tPoly.Initialise()

SeedRnd(MilliSecs())
SetAlpha(1)


Local temp:TImage = LoadAnimImage("glowing_dots.png",64,64,0,4,FILTEREDIMAGE|MIPMAPPEDIMAGE)

For Local i:Int = 0 To 50
	vObject.Create(Rand(0,480),Rand(0,360),Rand(10,20),Rand(0,360),Rand(3,10))
Next

While Not KeyHit(KEY_ESCAPE)

	SetAlpha(1)
	SetBlend(LIGHTBLEND)
	vObject.DrawAll(temp,2)

	' This is the bit that provides the nice phosphor effect.
	DrawImage(temp,-100,-100) ' * Force a state change
	SetColor 0,0,0
	SetBlend(ALPHABLEND)
	SetAlpha(0.1)
	DrawRect 0,0,480,360

	Flip 

Wend

End






Now I go and do some proper work.

Everyone seems to be using the word extreme on the end of their game names - I'll have to change SRX to be called something else...

Extreme refers to the glow not the game. It's not a game anyway, maybe I should make it into a game and since I borrowed bits from GEOM I should call it "GEOM WARS EXTREME" :P

Let's buck the trend.

Coming Soon: Naked War Mild

hehe.

"360" is another trend btw.

Pentium Mellow Edition.

Indiepath: This looks cool. I don't really get how you achieve that overall glow effect though, guess it must be hidden in the modules? I see there is a glowingdots.png, do you use this to draw you lines one dot at a time?

Damn JP, beat me to it!

Mildly Naked War

oh, what sorta FPS can that code pull?

@Jake, each line is created from 6 triangles using 8 vertices. I use the vertex UV to tell the renderer how to texture the line. The ends of the line are textured using the left side and right sides of the dot texture. The length of the line is textured using the very centre line of the dot texture, this is then stretched the length of the line. You can also specify the color and alpha at either line end.

How fast is it? well it's just textured polys so you should be able to use in excess 100,000 and still maintain 60FPS.

The overall fade/blur is controlled by 4 lines :
	' This is the bit that provides the nice phosphor effect.
	SetBlend(ALPHABLEND)
	SetAlpha(0.09)
	SetColor 0,0,0
	DrawRect 0,0,480,360

You see I'm not using CLS, I'm using an Black Alpha Rectangle to slowly clear the contents. Play with the Alpha setting and see what happens SetAlpha(0.02) is crazy.

I played with something similar a while back, but without the fancy glowing lines...

Strict

Type TPoint2D
	Field x#, y#
End Type

Type TVectObj
	Field originX#, originY#
	Field scaleX# = 1, scaleY# = 1
	Field rotation#, alpha# = 1
	Field r, g, b
	
	Field points:TPoint2D[]
	
	Method AddPoint(x#, y#)
		Local thisPoint:TPoint2D = New TPoint2D
		thisPoint.x# = x#
		thisPoint.y# = y#
		
		points = points[..points.length + 1]
		points[points.length - 1] = thisPoint
	End Method
	
	Method SetColour(r, g, b)
		Self.r = r
		Self.g = g
		Self.b = b
	End Method
	
	Method SetScale(x#, y#)
		scaleX# = x#
		scaleY# = y#
	End Method
	
	Method Draw()
		SetTransform rotation#, scaleX#, scaleY#
		SetColor r, g, b
		
		For Local thisPoint = 0 Until points.length
			Local nextPoint = (thisPoint + 1) Mod points.length
			Local handleX# = originX# - (originX# + points[thisPoint].x#)
			Local handleY# = originY# - (originY# + points[thisPoint].y#)
			
			SetHandle handleX#, handleY#
			DrawLine originX# ,originY#,..
							(originX# + Points[nextPoint].x#) + handleX#,..
							(originY# + Points[nextPoint].y#) + handleY#
		Next
	End Method
End Type

Type TPlayer
	Field ship:TVectObj
	Field vx#, vy#
	
	Function Create:TPlayer(ship:TVectObj, x#, y#)
		Local thisPlayer:TPlayer = New TPlayer
		
		thisPlayer.ship = ship
		thisPlayer.ship.originX# = x#
		thisPlayer.ship.originY# = y#
		
		Return thisPlayer
	End Function
	
	Method Update()	
		Local thrustX#, thrustY#
		
		If KeyDown(KEY_LEFT)
			ship.rotation# :- 4
		EndIf
		
		If KeyDown(KEY_RIGHT)
			ship.rotation# :+ 4
		EndIf
		
		If KeyDown(KEY_UP)
			vx# :+ Sin(ship.rotation#) * 0.1
		 	vy# :- Cos(ship.rotation#) * 0.1
		Else
			vx# :* 0.99
			vy# :* 0.99
		EndIf
		
		ship.originX# :+ vx#
		ship.originY# :+ vy#
		
		If ship.originX# < 0
			ship.originX# = GraphicsWidth()
		Else
			If ship.originX# > GraphicsWidth() Then ship.originX# = 0
		EndIf
		
		If ship.originY# < 0
			ship.originY# = GraphicsHeight()
		Else
			If ship.originY# > GraphicsHeight() Then ship.originY# = 0
		EndIf	
	End Method
	
	Method Draw()
		ship.Draw()
	End Method	
End Type		
		
	
SetGraphicsDriver GLMax2DDriver()
Graphics 800, 600, 32'0
HideMouse

Local ship:TVectObj = New TVectObj
ship.AddPoint(0, -10)
ship.AddPoint(10, 10)
ship.AddPoint(0, 7.5)
ship.AddPoint(-10, 10)
ship.SetColour(200, 255, 255)

Local player:TPlayer = TPlayer.Create(ship, 400, 300)

glEnable(GL_LINE_SMOOTH)
SetLineWidth 2'0.25

Repeat
	Clear(0.2)
	
	'ship.SetScale(1 + (Cos(MilliSecs() * 1.5) * 0.1), 1 + (Sin(MilliSecs() * 1.5) * 0.1))
	
	player.Update()
	player.Draw()
	
	Flip
Until KeyHit(KEY_ESCAPE)

End

Function Clear(alpha#=0.6) 
	SetColor 0, 0, 0
	SetHandle 0, 0
	SetTransform 0, 1, 1
	SetBlend ALPHABLEND
	SetAlpha alpha#
	DrawRect 0, 0, 800, 600
	SetAlpha 1
End Function


Hah, that's really cool, and simple. nice one!

What does 'flkr' mean?

Where to get ?

Import indiepath.texturedpoly
Import indiepath.projmatrix

http://modules.indiepath.com

flkr = Flicker = flkr.net = something new :)

And are these mods and code free to use?

Tim. Thanks for the answer, I get it now, cool. And that sounds FAST btw :-D

Sorry but how do i install the mods?

Yes the stuff is free to use in freeware and commercial projects. All I ask is for a mention in your credits and let people know where you got the code from. The code may not be wrapped or supplied for sale as a part of or as a feature of a framework blah...blah...and you can't sell this stuff as your own..blah blah.. If Jake includes anything in his "Framework" then you can be assured that he has permission to do so.

Install the mods to you BlitzMax/mods folder. Your structure should look something like BlitzMax/mods/indiepath.mod/...

** Oh and I wanna play Thrust Extreme with this stuff in it please :) NOW!

Something new?! I should've guessed! :)

ARGH!

I have /mod/indiepath.mod/texturedpoly.mod

this dir contains...

the docs and examples dirs and texturedpoly.mod but still it cannot find it!

Says cannot find interface for mode 'indiepath.texturedpoly'

Could some one please send me both mods zipped in in the correct folder structure so I can compile this excellent stuff...

Like this :
C:\Program Files\BlitzMax\mod\indiepath.mod\texturedpoly.mod


Also you need "ProjMatrix.mod" for the example!

P.S. And you need to REBUILD MODULES too.

I have that path setup...

Could someone send me theirs?

How do I rebuild modules MY OPTION IS GREYED OUT!

aarrghhh!

You need to have mingw setup correctly on your system for a rebuild:
http://www.blitzbasic.com/Community/posts.php?topic=53442

Gimmi a min, sending you mine... 8)

Sent!

Oh and it works on Mac and Linux.

Grisu,

thanks - builds but when I run I get unhandled exception trying to access field or method of null object

TPoly.Line(image,frame,x1,y1,c1,x2,y2,c2,20,True,True)

:-(

Have you got the image in the directory?

Ooops - no - shoot me!

*Kaboooooooooooooooooom* *click, click *Kabooooooooooom*

Just in case the first bullet missed... ;)

@Tim:
For the Credits, what would you prefer?

Poly Module by:
1. Tim Fisher
2. Indiepath
3. www.indiepath.com

Indiepath please, send everyone to indiepath.com

Ok, will do.

Don't know if this is overkill, but I like my tiny Extreme Credits. :)


Grisu,

is that a game?

Indiepath - how d'ya get the exe so small - using upx?

no, my credits window, it's an extremely boring app! :)

The .exe is UPX'd but it would be smaller if I only used the frameworks that were needed.

Btw:
Have you tested the module under opengl win32?
It seems to crash my whole app after a while! 8)

Any ideas?

Actually OpenGL does not act as it should... Let me investigate.

Thanks!

OpenGL had a state change problem it was easily solved by using this code.
	' This is the bit that provides the nice phosphor effect.
	DrawImage(temp,-100,-100) ' * Force a state change
	SetColor 0,0,0
	SetBlend(ALPHABLEND)
	SetAlpha(0.1)
	DrawRect 0,0,480,360

Not sure why you are getting a crash though, it's not happening here.

The problem might be the fact that im using it inside a maxgui canvas, though I dont understand that it runs fine as long as I don't use the gldriver... :(

YUK did you say canvas? urrrgggh.

Yes, CANAVS, as my app is full written with the bmx gui. *hell of work and I found nice gui bugs on the way*

*gets himself a plushy chainsaw*

As soon as my INFO window gets inactive, it crashes.

(pic deleted)

P.S.:
Well, I have given up. No sense in spending more time on this as I'm not writing a game with it. Was worth a try.