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 |