Need lockedbuffer version of this...

Blitz3D Forums/Blitz3D Programming/Need lockedbuffer version of this...

This is some code from the code archives or toolbox or somewhere, "Seth's BMP Fontlib v3d.11". It's worked fine, except I've just found on my P3 600 it takes 45 ms to draw a 2 digit number! It uses CopyRect, which I've tried to replace with locked buffers and CopyPixelFast()

My unworking attempt at this conversion is :
Function BMPText(bmpfnt,x#,y#,txt$,h_align=0,v_align=0,width=0)
	; x,y		- coordinates
	; txt$		- Text to display on the screen
	; h_align	- should text be horizontally centred?
	; v_align	- should text be vertically centred?
	; width		- if greater than 0, text is wrapped to that width
	
	; This function returns the total height of the BMPtext which
	; is useful if you want to set other values like window heights
	; to the height of the text as it wraps.
	
	; If you wish to retrieve the height without drawing text, then see
	; the BMPTextHeight command
	
	Local xx#,yy#
	
	fnt.bmpfont = Object.bmpfont(bmpfnt)
	LockBuffer ImageBuffer(fnt\img)		;********************************************************************
	
	flines=fnt\height[Asc("X")]
	maxasc=122+4*fnt\extrachar+(255-126)*fnt\extendedchar
	If width>0
		txt=txt+" "
		i=0 ww=0
		While Instr(txt," ",i+1)>0
			For j=i+1 To Instr(txt," ",i+1)
				a=Asc(Mid(txt,j,1))
				If a=>Asc(" ") And a<=maxasc
					ww=ww+fnt\width[a]
				ElseIf a=13
					j=j+1
					flines=flines+fnt\height[Asc("X")]
					ww=0 w=0
					Exit
				End If
				If ww+fnt\width[a]=>width And w>0 Then
					txt = Left(txt,i-1) + Chr(13) + Right(txt,Len(txt)-i)
					ww=0 w=0 flines=flines+fnt\height[Asc("X")]
					j=i+1
				End If
			Next
			i=j-1
			w=ww
		Wend
		i=0 txt=Left(txt,Len(txt)-1)+Chr(13)
		If v_align Then y = y - flines/2
		xx = x  yy = y
		While Instr(txt,Chr(13),i+1)>0
			If h_align
				For j=i+1 To Instr(txt,Chr(13),i+1)-1
					a=Asc(Mid(txt,j,1))
					If a=>Asc(" ") And a<=maxasc Then xx=xx-fnt\width[a]*.5
				Next
			End If
			For j=i+1 To Instr(txt,Chr(13),i+1)-1
				a=Asc(Mid(txt,j,1))
				If a=>Asc(" ") And a<=maxasc
;					DrawImageRect fnt\img,xx,yy,fnt\x[a],fnt\y[a],fnt\width[a],fnt\height[a]
					For x1=0 To fnt\width[a]
						For y1=0 To fnt\height[a]
							z=ReadPixelFast 
							CopyPixelFast fnt\x[a]+x1, fnt\y[a]+y1, ImageBuffer(fnt\img), xx+x1,yy+y1
						Next
					Next
					xx=xx+fnt\width[a]
				End If
			Next
			i=j
			yy=yy+fnt\height[Asc("X")] xx=x
		Wend
	Else
		If h_align
			For i=1 To Len(txt)
				a=Asc(Mid(txt,i,1))
				If a=>Asc(" ") And a<=maxasc
					x=x-fnt\width[a]/2
				End If
			Next
		End If
		If v_align y=y-flines/2

		xx=x yy=y
		
;image = variable holding the image handle 
;x = x location on the screen to draw the image 
;y = y location on the screen to draw the image 
;rect_x = starting x location within the image to draw 
;rect_y = starting y location within the image to draw 
;rect_width = the height of the area to draw 
;rect_height = the width of the area to draw 
;frame = optional frame number of image to draw 

;src_x - x-coordinate of source pixel to copy from 
;src_y - y-coordinate of source pixel to copy from 
;src_buffer - name of buffer to copy from, e.g. ImageBuffer() 
;dest_x - x-coordinate of destination pixel to copy to 
;dest_y - y-coordinate of destination pixel to copy to 
;dest_buffer (optional) - name of buffer to copy to, e.g. BackBuffer() 

		For i=1 To Len(txt)
			a=Asc(Mid(txt,i,1))
			If a=13
				xx=x
				yy=yy+fnt\height[Asc("X")]
			ElseIf a=>Asc(" ") And a<=maxasc
;				DrawImageRect fnt\img,xx,yy,fnt\x[a],fnt\y[a],fnt\width[a],fnt\height[a]
				For x1=0 To fnt\width[a]
					For y1=0 To fnt\height[a]
						CopyPixelFast fnt\x[a]+x1, fnt\y[a]+y1, ImageBuffer(fnt\img), xx+x1,yy+y1
					Next
				Next
				xx=xx+fnt\width[a]
			End If
		Next
	End If
	
	UnlockBuffer ImageBuffer(fnt\img)		;********************************************************************
	Return flines
End Function


I call this function from another function...
Function TG_Change_Text(indx%,replacement_text$, forced%=0)
	; FUNCTION : updates texts(indx) with new text
	; Force forces the graphics draw without the speed optimization of checking for duplication of graphics
	If texts(indx)\txt$<>replacement_text$ Or forced		; If changing the text
		texts(indx)\txt$=replacement_text$
		SetBuffer TextureBuffer(texts(indx)\texture)	; write to texture
		Cls
		LockBuffer TextureBuffer(texts(indx)\texture)
		If texts(indx)\txt$<>""
			BMPText font_gothic, (texts(indx)\siz_x/2), (texts(indx)\siz_y/2), texts(indx)\txt$,1,1
		Else
			BMPText font_gothic, (texts(indx)\siz_x/2), (texts(indx)\siz_y/2), texts(indx)\default_txt$,1,1
		EndIf
		UnlockBuffer TextureBuffer(texts(indx)\texture)
		SetBuffer BackBuffer()
		EntityTexture(texts(indx)\sprite,texts(indx)\texture)
	EndIf
End Function


When run I get a MAV on 'RenderWorld tween'

Could someone smarter than I fix this to run faster? Thanks.

I think Copyrect is pretty fast, not sure if it's worth to convert it to copypixelfast.

Drawing or poking to an imagebuffer is slow in general, since the data has to pass the bottleneck between ram and Vram. A better solution would be to do all operations on the backbuffer and copyrect the finished stuff to the image buffers.

(I know it sounds unlogical, since the backbuffer is also in Vram AFAIK. Noless, copyrect in image buffers seems to be much slower than in the backbuffer )

You speak the truth! I tried a couple alternatives and drawing to the texture just takes 45 ms. Whereas texting to the backbuffer is much, much faster. I need to shift my text drawing to work on the backbuffer then.

This is very important info. Thanks for pointing it out to me.

However, I found CopyRect much slower than CopyPixelFast when I did switch to writing to the backbuffer, and copying from backbuffer to texture. CopyRect didn't appear to speed up much at all this way.

Locking the buffer has no effect on CopyRect. But copyrect is much faster for moving biggish areas. Have you tried setting the +256 flag on the texture your using?

When I said using this method, I meant writing to backbuffer and copying to texture. Doing that, and using CopyRect, things didn't speed up much. Whereas writing to backbuffer, locking buffers and using CopyPixelFast I got a considerable speed improvement. I haven't tried setting the VRAM flag. I might give that a go, but at the moment I'm considering the program finished and am working on the website now, so tweaks are very low on the agenda.