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