Plot vs. Writepixel

BlitzMax Forums/BlitzMax Beginners Area/Plot vs. Writepixel

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Nick,
Have a look at the code samples here (which use OpenGL) ..

The first example demonstrates Plot using two methods:

First, using the standard BLitzMax Plot
Then, using an unwrapped version with glBegin and glEnd being called at the start and end of a batch of pixels to plot (instead of every plot)

The speed difference only shows up if you plot 1000's of stars per frame.

' faster plotting

SuperStrict
Framework BRL.GLMax2D
Import BRL.Random


SetGraphicsDriver GLMax2DDriver()
Const width%=640 , height%=480
Const NUMPLOTS%=500000
Local t%

Graphics width,height,0


t=MilliSecs()
FastPlot NUMPLOTS
Local t1%=MilliSecs()-t

t=MilliSecs()
NormalPlot NUMPLOTS
Local t2%=MilliSecs()-t

' _________________________________________________

Cls
DrawText "Number of plots = "+String(NUMPLOTS),10,10
DrawText "  Fast plot (m/secs)= "+String(t1),10,40
DrawText "Normal plot (m/secs)= "+String(t2),10,60
Flip
WaitKey
End

' _________________________________________________

Function FastPlot(num%)
	glDisable GL_TEXTURE_2D	
	glBegin GL_POINTS
	For Local p%=1 To num
		glVertex2f Rand(width),Rand(height)
	Next
	glEnd
	glEnable GL_TEXTURE_2D
	Flip
End Function


Function NormalPlot(num%)
	For Local p%=1 To num
		Plot Rand(width),Rand(height)
	Next
	Flip
End Function





This code is more complicated (using the WritePixel command)
Its certainly pretty damn fast but you need to run it with Debug Off:
Strict

Framework BRL.GLMax2D
Import BRL.Pixmap
Import BRL.Bank
Import BRL.Random
Import BRL.System


SetGraphicsDriver GLMax2DDriver()
Graphics 640,480 , 0


Global particle_list:TList=New TList
Const glevel1=1
Const glevel2=2
Const glevel3=4

Const maxx=239
Const maxy=239

Const particle_life=1000

Global firepix:TPixmap=CreatePixmap(480 , 480 , PF_RGBA8888)
Global cfb:TBank = CreateBank(57600)
Global hfb:TBank = CreateBank(57600)

SeedRnd MilliSecs()

AppTitle = "BlitzMax Firedemo"

Global gradient[256] , col[5]

col[0]=$000000
col[1]=$400040
col[2]=$000080
col[3]=$C00000
col[4]=$FFFF00

SetupGradient()


Local angl:Double = 0

Type Particle
	Field x#,y#
	Field speed#,direction,angle,life
	Global pcount=0
	'
	Method New()
		x=0
		y=0
		speed#=Rnd (.2 , .6)
		direction=Rand(0,359)
		angle=direction
		life=particle_life
		pcount:+1
		particle_list.AddLast(Self)
	End Method
	'
	Method Update()
		If x < -120 Then x = -120
		If x >  119 Then x =  119
		If y < -120 Then y = -120
		If y >  119 Then y =  119

		Local bofs= Int(x+120) + Int(y+120)*240
		Local myPtr:Byte Ptr = BankBuf (cfb)

		Local valu=myPtr[bofs]
		valu=valu+20

		If valu<80
			life:-1
		EndIf

		If life <=0
			x=0
			y=0
			speed#=Rnd (.2 , .6)
			direction=Rand(0,359)
			angle=direction
			life=particle_life
		Else
			If valu>255 Then valu=255
			myPtr [bofs] = valu

			Local surfangle = ATan2 ( y , x )
			x = x + speed * Cos( direction )
			y = y + speed * Sin( direction )

			If (x*x + y*y)>10000
				angle = surfangle - 180
			Else
				If angle = direction
					angle=Rand(0,359)
				EndIf
			EndIf

			angle=(angle + 360) Mod 360
			direction=(direction + 360) Mod 360

			Local angc:Double
			If angle<direction
				angc=360+angle-direction
			Else
				angc=angle-direction
			EndIf

			If angc>180
				direction=direction-1
			ElseIf angc>0
				direction=direction+1
			EndIf
		EndIf
	EndMethod
	'
End Type



Repeat
	Flip 0
	Cls
	Local startime = MilliSecs()

	For Local p:Particle = EachIn particle_list
		p.update
	Next

	For Local yco=0 To maxy
		For Local xco=0 To maxx
			Local myPtr:Byte Ptr = BankBuf(cfb)

			Local rb:Byte = myPtr [xco + yco*240]
			If rb>0
				Local valu=rb*glevel3

				Local x1 = xco-1
				If x1<0 Then x1=x1+maxx

				Local x3 = xco+1
				If x3>maxx Then x3=x3-maxx

				Local y1 = yco-1
				If y1<0 Then y1=y1+maxy

				Local y3 = yco+1
				If y3>maxy Then y3=y3-maxy

				rb=myPtr [x1 + y1 * 240]
				valu=valu+rb*glevel1

				rb=myPtr [xco + y1 * 240]
				valu=valu+rb*glevel2

				rb=myPtr [x3 + y1 * 240]
				valu=valu+rb*glevel1

				rb=myPtr [x1 + yco * 240]
				valu=valu+rb*glevel2

				rb=myPtr [ x3 + yco * 240 ]
				valu=valu+rb*glevel2


				rb=myPtr [x1 + y3 * 240]
				valu=valu+rb*glevel1

				rb=myPtr [xco + y3 * 240]
				valu=valu+rb*glevel2

				rb=myPtr [x3 + y3 * 240]
				valu=valu+rb*glevel1

				valu=valu Shr 4
				
				PokeByte hfb,xco + yco * 240 , valu

			EndIf
		Next
	Next

	For Local yco=0 To maxy
		For Local xco=0 To maxx
			Local bofs=yco*240+xco
			Local valu=PeekByte(hfb,bofs)
			If valu>0
				If valu>4
					valu=valu-4
				Else
					valu=0
				EndIf
				PokeByte hfb,bofs,valu
				WritePixel firepix , xco*2 , yco*2 , gradient[valu]
				WritePixel firepix , xco*2+1 , yco*2 , gradient[valu]
				WritePixel firepix , xco*2+1 , yco*2+1 , gradient[valu]
				WritePixel firepix , xco*2 , yco*2+1 , gradient[valu]
			EndIf
		Next
	Next

	Local temp:TBank = cfb
	cfb = hfb
	hfb = temp
	
	FastDrawPixmap firepix , 160 , 0

	'One beat each 14.4 frames = 12.5 angles a frame

	angl=angl+12.5
	If angl>180 Then angl=angl-180

	Local frametime=MilliSecs()-startime

	If frametime<30
		For Local i = 0 To 9
			New Particle
		Next
	EndIf

	If Particle.pcount>0
		Local part:String="Featuring "+Particle.pcount+" real-time blurred particles."
		DrawText part , 640-TextWidth(part$),0
	EndIf

	If KeyHit(KEY_ESCAPE)
		particle_list.Clear()
		Particle.pcount = 0
		Exit
	EndIf

	While frametime<33
		frametime=MilliSecs()-startime
	Wend

Forever

End

Function SetupGradient()
	Local ofs,grad,i
	While ofs<255
		For i=0 To 63
			Local perc#=i/63.0
			Local x1=col[grad] Shr 16 & $FF
			Local xco=col[grad] Shr 8 & $FF
			Local x3=col[grad] & $FF
			Local y1=col[grad+1] Shr 16 & $FF
			Local yco=col[grad+1] Shr 8 & $FF
			Local y3=col[grad+1] & $FF
			gradient[i+ofs]=$FF000000 + Int(x1*(1-perc)+y1*perc) Shl 16 + Int(xco*(1-perc)+yco*perc) Shl 8 + Int(x3*(1-perc)+y3*perc)
		Next
		ofs=ofs+i;grad=grad+1
	Wend
EndFunction

Function FastDrawPixmap(p:TPixmap,x,y,scalex#=1.0, scaley#=1.0)
	Local blend%=GetBlend()
	glDisable GL_TEXTURE_2D 'DisableTex
	SetBlend SOLIDBLEND
	Local t:TPixmap=p
	If t.format<>PF_RGBA8888 t=ConvertPixmap(p, PF_RGBA8888 )
	glpixelzoom scalex#,-scaley#
	glRasterPos2i 0,0
	glBitmap 0,0,0,0,x,-y,Null
	glPixelStorei GL_UNPACK_ROW_LENGTH, p.pitch Shr 2
	glDrawPixels p.width, p.height, GL_RGBA, GL_UNSIGNED_BYTE, p.pixels
	glEnable GL_TEXTURE_2D
	SetBlend blend
End Function