TalkBubble (working!) > How to optimize?
BlitzMax Forums/BlitzMax Programming/TalkBubble (working!) > How to optimize?
| ||
| Greetings, I lost myself finding a way to optimize this "TextBubble" function. It is written for a game im working on where people can chat and have a bubble popup. As the title says, its a fully functional script, except its kinda slow if you have to render about 100 of these. I have NO idea what todo. For the source + bubblemapfont download: http://www.fantasaar.com/bubble.zip fyi, here is a direct copy of the code: SetGraphicsDriver GLMax2DDriver()
Graphics 640,480,,,GRAPHICS_BACKBUFFER
Global BubbleMap$="!~q#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~~"
Global BubbleCharW=7,BubbleCharH=10
Global BubbleLimitW=48
Global BubbleFont=LoadAnimImage("bubble.png",BubbleCharW,BubbleCharH,0,256)
While Not KeyDown(KEY_ESCAPE)
DrawBubble("Hey! My name is LeeMing :D. ThislineisbrokenupThislineisbrokenupThislineisbrokenupThislineisbrokenupThislineisbroken\n\nupThislineisbrokenup Some random text goes here: Welcome to the official Fantasaar gameserver!",320,240)
Flip
Wend
End
Function DrawBubble(text$,x,y)
'Local destPixmap:TPixmap = CreatePixmap(((BubbleLimitW+1)*BubbleCharW),240,PF_RGBA8888)
'destPixmap.Paste(BubbleFont.Lock(224,0,0), 32, 32)
Local line$
Local l=0
Local newline
'Render top
For p=1 To BubbleLimitW+2
If p=1
DrawImage(BubbleFont,((p-1)*BubbleCharW),(l*BubbleCharH),224)
Else If p=BubbleLimitW+2
DrawImage(BubbleFont,((p-1)*BubbleCharW),(l*BubbleCharH),226)
Else
DrawImage(BubbleFont,((p-1)*BubbleCharW),(l*BubbleCharH),225)
End If
Next
l:+1
While Len(text)>0
newline=False
p=0
'Line start
DrawImage(BubbleFont,(p*BubbleCharW),(l*BubbleCharH),227)
For p=1 To BubbleLimitW
'on: newline?
If Mid(text,p,2)="\n"
line=Left(line,p)
text=Right(text,Len(text)-(Len(line)+2))
p=0
newline=True
Exit
Else
'on: text
If p < Len(text)+1
line=line+Mid(text,p,1)
'Finished?
Else
Exit
End If
End If
Next
'Always except when new line
If newline=False
p=line.FindLast(" ")
If p>-1
line=Left(line,p)
p=0
End If
text=Right(text,Len(text)-(Len(line)+1+p))
End If
'Render textline
For p=1 To Len(line)
DrawImage(BubbleFont,(p*BubbleCharW),(l*BubbleCharH),228)
DrawImage(BubbleFont,(p*BubbleCharW),(l*BubbleCharH),Instr(BubbleMap,Mid(line,p,1)))
Next
'Finish tender textline (spacing)
For i=p To BubbleLimitW
DrawImage(BubbleFont,(i*BubbleCharW),(l*BubbleCharH),228)
Next
'Line stop
DrawImage(BubbleFont,(i*BubbleCharW),(l*BubbleCharH),229)
l:+1
line=""
Wend
'Render bottom
For p=1 To BubbleLimitW+2
If p=1
DrawImage(BubbleFont,((p-1)*BubbleCharW),(l*BubbleCharH),230)
Else If p=BubbleLimitW+2
DrawImage(BubbleFont,((p-1)*BubbleCharW),(l*BubbleCharH),232)
Else
DrawImage(BubbleFont,((p-1)*BubbleCharW),(l*BubbleCharH),231)
End If
Next
'Talk arrow
DrawImage(BubbleFont,((BubbleLimitW+1)*BubbleCharW)/2,((l+1)*BubbleCharH)-4,236)
End Function
|
| ||
| With that attempt it will never become faster ... you render several images for each letter ... that means that you easily render several (ten)tousand objects each frame ... thats a clear no go ... Implement a "lower level" system or check out the DrawImageArea / DrawImageRect functions that allow you to use 1 texture with all chars in instead of XY different ones and draw subareas of that. |
| ||
| a "lower level" system? afaik I can only draw images using the draw command. Are you talking about pre-assembling the image before displaying? How would that work? do i use PixMaps for that? |
| ||
| it would be a lot faster creating a single image with your bubble and text and drawing that every loop. |
| ||
| No I am talking about preassembling an image with all letters on it and use that to do a imagefont and "draw image area" commands that only draw a subarea. This will not work with Stock Max2D commands, no mather what you do. The amount of texture rebinds is too high, you kill the graphics card by flooding it that way |
| ||
| Ye, going to OOP. Was thinking about that. Altough i must say i did not plan to have it create images every loop. I did this to notice a noticable increase in preformance, that is, when testing and trying to optimize it. I guess i will have to play arround a bit more with pixmaps... it seem that is the way to go. Ive had some support here with a previous question, also pixmap related. http://www.blitzbasic.com/Community/posts.php?topic=75531 Isn't there a better referance this subject with BlitzMax? |
| ||
| There is a Render2Texture module by indiepath that a user upgraded to 1.26 ... it can be found on the boards. Pixmaps aren't fast enough for anything as you must always recreate an image from them if you intend to use blending etc. |
| ||
| i was afraid of that... hmm, il look up that function. |
| ||
| But as mentioned: a bitmap font with a single surface approach (ie 1 texture for all characters) should already speed it up seriously ... |
| ||
| Oh, i ust have not understood that correctly. How exactly do i create a bitmap font? (thanks for the help, its appreciated!) I know how these things work in Blitz3D, but im new to BlitzMax. |
| ||
| Well in BM they work exactly the same. Just that the DrawImageRect function from B3D does not exist anymore. But users have created their own version of it. They are known as DrawImageArea or DrawImageRect2 and can be found in the code archives. |
| ||
| Neat. Thanks for the tip. |
| ||
I got the function.... but i dont see how
Function tg_drawimagerect(image:TImage,x:Int,y:Int,xs:Int,ys:Int,width:Int,height:Int)
DrawImage LoadImage(PixmapWindow(LockImage(image),xs,xy,width,height)),x,y
End Function
is faster than drawing images the way i did?! |
| ||
| Just an idea but could you not build up a set of commonly used words and build and store them as images to reduce the number of rectangles drawn? Or you could even build up a mapping of letter combinations e.g. 2 to 3 letters and then when you write a string containing commonly used combinations it would pick a pre-built one? With judicious use of Maps could this be faster, over longer conversations heavy duty usage? You could even go a step further and tokenize the common words combinations and only send those between clients? As well as potentially being usefull for predictive text? Wow I like this idea, now how the hell do I write a chat room? |
| ||
| @LeeMing Not DrawImage LoadImage(PixmapWindow(LockImage(image),xs,xy,width,height)),x,y is not right variant. Right functions' names is "DrawImageArea" and "ccDrawImageArea". And they could be just in forum, not only in code archives. |
| ||
| I think i found one: http://www.blitzbasic.com/Community/posts.php?topic=73041#816343 (posting it for reference purpose) -Edit- Check this, its a great solution to my problem here: http://www.blitzbasic.com/Community/posts.php?topic=74153#828522 |