Writing pixels to screen FAST?

BlitzMax Forums/BlitzMax Programming/Writing pixels to screen FAST?

hi again!

is there a way to write pixels to the screen without using a pixmap. pixmaps are slow for that matter. also plot is too slow for this either.

this should not be done via openGL. at best, it should be software rendered

thanks :)
(i promise, i will not post so many topics soon anymore)

draw pixels on pixmap, unlock pixmap (= TImage), draw TImage?

k, will do that
thx!

Have a look at this method. Although it uses pixmaps the method used to set the pixels is really fast

(The demo only seems to work in non-debug mode for me though)


Rem
	Binary Therapys Fire Demo
	Mods (Jim Brown):
	Stripped dependancies
EndRem

Strict

Framework BRL.GLMax2D
'Framework BRL.D3D7Max2D

Import BRL.Bank
Import BRL.Random
Import BRL.BMPLoader

SetGraphicsDriver GLMax2DDriver()
'SetGraphicsDriver D3D7Max2DDriver()


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)
Global creds=0

SeedRnd MilliSecs()

AppTitle = "BlitzMax Firedemo"

Global quittime=0
Global qta=1

Global gradient[256] , col[5]

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

SetupGradient()

Graphics 640,480 , 32

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 False
	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
	
	DrawPixmap firepix , 80 , 0

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

	Local frametime=MilliSecs()-startime

	If frametime<30 And qta>0
		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 , 30,0
	EndIf

	If KeyHit(KEY_ESCAPE) And quittime=64
		particle_list.Clear()
		Particle.pcount = 0
		quittime=63;qta=-qta
	EndIf

	If quittime<64
		quittime=quittime+qta
	EndIf

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

Until quittime=0 And qta < 0

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




There is also a faster version of drawing a pixmap to the screen too (OpenGL):
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


How is that drawpixmap faster?

Are you saying that switching off blending and texturing makes it faster?

And what is the glBitmap doing to help matters?

DC - you may want to also try a vertex buffer of points.

thanks for the example, i'll stick to the first one :)