How to update some elements of a GUI

Community Forums/General Help/How to update some elements of a GUI

RemiD(Posted 2013) [#1]
Hello, :)

I am currently working on a GUI for a project and i wonder how to update some elements of the GUI :

->Message area (a zone where there is instructions or a message, with possibility to scroll up or to scroll down)

->Text field (a zone where there is typed text, with possibility to add a char, to add a space, to move before the previous char or before the next char, to remove the previous char or the next char)

->Chat area (a zone where there are the text lines of all users)

I have already managed to code all these elements, my question is more about how to update these elements, because they can be modified depending on the text or text lines on them.

First, i have tried to build all the elements each frame, and to draw them after the render3d with rect + line + text + drawimage.
It is easy to modify the text but it is a bit slow to render.

Second, i have tried to prebuild all the elements once in several images, and to draw them after the render3d with drawimage.
It is more complicated to modify but it is faster to render.
I can modify each element only when necessary (if the text is scrolled up or down, if a char is added or removed, if a line is added or removed.)

Note : the elements of the GUI which never change are prebuilt (the windows, the buttons, the switches, the info areas)

Is there a better approach to do this ?

Thanks for you suggestions,


*(Posted 2013) [#2]
Why not just have a 'Redraw' flag that when set to true gets the element redrawn then it sets the flag back to false, this way only whats needed to be drawn is redrawn :)


RemiD(Posted 2013) [#3]

Why not just have a 'Redraw' flag that when set to true gets the element redrawn then it sets the flag back to false, this way only whats needed to be drawn is redrawn


Oh i see what you mean but i don't think it will work if there are 3d meshes rendered before, i think this will erase the elements of the GUI.

Or maybe i will have to use a quad mesh with the elements of the GUI textured on it.
I have to try that, thanks.

If you have others suggestions, they are welcome.


Derron(Posted 2013) [#4]
Just decouple the logic from the drawing (wohhoo helpful hint) ... this idea is also used for gui things.


Your world graphically changes: set the world-type field to "dirty" or "redraw" (this means eg. mouse used for rotation, animation ...) - only useable if you are coding something "static" like model editors or animationless games - else you will have to use "staticSinceMilliseconds"-timers which you can use for checking (back in the times of 2d we used DirtyRects-methods).


Someone types something -> Keypress-Event, all listeners check if they are targeted.
GuiChat is targeted: field "dirty" or "redraw" is set to true, content is changed according the keypresses.

After all listeners processed that event, do the next one until all events are finished.

After you have drawn your 3d scene you will draw the gui (I think the gui stays on top of all other elements). The gui itself can have z-indexes for gui-element-ordering (different windows).

Now Gui-Object-caching can start: decide on the different states (world dirty, gui dirty, gui already cached) whether you grab the pixmap from the backbuffer or not. As soon as then changes happen (world dirty or guiobject dirty) you will have to reset the cache: so as soon as there are some animations per second you will end up doing more work than without caching.

Each drawn element sets it's "dirty"/"redraw" field to false.

flip.



If your gui objects are rectangles without alpha transparency or shadows you could cache them in nearly all situations (grabpixmap or directly "build" the pixmap). If you know that only your gui-object-decoration is using transparency/alphas ... and there is a rectangle in it containing the texts, you could still consider caching the inner rectangle. Especially if the calculation of text-alignment is slowing down everything (align "justify" is such a case :D).


bye
Ron


RemiD(Posted 2013) [#5]

If your gui objects are rectangles without alpha transparency or shadows you could cache them in nearly all situations (grabpixmap or directly "build" the pixmap). If you know that only your gui-object-decoration is using transparency/alphas ... and there is a rectangle in it containing the texts, you could still consider caching the inner rectangle.


Yes i already do that, one image for the "background" and i add the text on top of this.

After this dicussion i now think that it will be faster to draw a GUI on several textured meshes, each mesh having a specific ZOrder.
There will be no need to redraw all elements because it is only a matter of hiding/showing the right meshes and redrawing only the text on some elements.

The only problem i see with this method is that i will have to use textures with a larger resolution than the resolution of the images i currently use, and specific UV coords depending on the element width height so that the element appearance is the same as if it was with an image.

Or maybe one big texture for each layer (for each different ZOrder)

I don't think i will code this now, i will finish my GUI with 2D commands until it is functional. But at least i have some ideas on what to do next.

Thanks again,


Derron(Posted 2013) [#6]
As soon as you have a good "caching" mechanism, you will in no time adjust it so it used multiple textures/objects if the dimension is bigger than a certain limit.

What I meant with "caching" included the text too (not only the compound image of different gui-"tiles"). So your gui object is drawn using: cacheImage + DecorationTiles (flowers and beetles at all corners...you know :D).

In Blitz you have to do that kind of caching as it really slows down if you use a lot of texts with the default truetyperenderer (multiple glyphs/images - one for each character). If you are having hard times with text2image you will better perform if you code your own fonttype which reads ttfs and "packs" all glyphs into one single texture. This saves the need of bitmapfonts and allows easy modfication concerning fontsizes.

As you seem to be able to "hide and show" only certain meshes I assume you are already using a non blitzmax approach (whole screen gets refreshed during flip) and therefor your "dirty rects" should be performing quite fast (only changed parts of the screen get refreshed).


bye
Ron


RemiD(Posted 2013) [#7]

As you seem to be able to "hide and show" only certain meshes


No, for now i use only the commands rect + line + text + drawimage of Blitz3d.

But from this discussion and my current understanding i think that several quad meshes + several textures + hideentity/showentity can produce a similar result and be faster to update/render.

I will try once i have finished it in 2d, thanks for the tips.