Building a GUI system ( Maybe from scratch)

Started by
6 comments, last by Burnt_Fyr 10 years, 1 month ago

Dear people, I'm involved on a project where I have to create an user Interface (GUI system) that must to run across multiple platforms.

I did some research and found that there is plenty of libraries out there, like GiGi, GLUI, CEGUI, and a lot of others, including QT.

Most of the Libraries that I found are built upon OpenGL and SDL but I'm not confident of using any of them yet. Maybe because they are little confusing, but for sure because in one of the target plataforms , there is nothing more that openGL-ES. The libraries I found are simply not ready for the platform.

So, I started thinking on implementing the Gui system from scratch, even because the requirements are not so big. I need some buttons and other basic controls, editable text fields, and maybe a window to show 3D objects. I would be convinced of implementig the Gui upon OpenGL, maybe SDL to increase portability. But I'm still in doubt between two approaches I imagined.

Ipproach 1: Creating GUI elements as textured 3D rectangles.

I could have a sprite sheet to contain the graphics for most of the basic GUI elements, and a reusable mesh , so It would not have too many draw calls. I'm affraid of using this approach because the editable text fields. I think the texture for those elements must be procedural and unique for each text field, And I will have a lot of them, So it will increase the number of draw calls per frame as I need to redraw all the scene in openGL ( Of course there is the option of not clear the buffer and redraw only the object that changed. but I´m not sure if it is a good Idea in OpenGL )

Ipproach 2: Using OpenGL only as a flipping multiplatform surface.

I could build the entire GUI as single texture. The GUI would be rasterized on a big buffer, and than used as a texture for a 3D rectangle that covers all openGL viewport. Using this approach, despite the Window would be flipped at a great frame rate, the texture that actually contains the Gui can be redrawn only when something changes. In fact , the only part that must be redrawn is the element that changed, and its children. That approach was proven at the old days of Graphic interfacing, using Win32 GDI. But in those days we did not rasterize in HD.

So, I would like to ask you people, if anyone have built a GUI from scratch like the ways above , or something completly different. I? just trying to choose the best patch here . .

Advertisement

Hello,

It depends on your target platforms, and what kind of content you have to display. First approach is fine on PC with modern hardware.

If you have large texts to display, it may be a good idea to not redraw everthing every frame.

But have you considered mixing the 2 approches ? Using a method 1 to draw in a render texture ?

----

www.winthatwar.com

Download our latest demo here.

www.insaneunity.com

@InsaneUnity

@DTR666

An incresingly popular option - one I haven't tried myself but will be sometime this year on a commercial project - is to use something like CEF (Chromium Embedded Framework) or Awesomium. You really don't need to overthink performance too much outside of in-game HUDs, and even then you can usually tolerate a few frame's lag. Chrome does all its rendering in a separate process and then you feed the result of that into the scene as an overlay when it's ready. Gives you the full flexibility of HTML/CSS/JS/canvas for making your GUIs (which is a very strong option given all the work that's gone into making open source frameworks for easy to use and beautiful web interfaces) as well as letting you integrate Web content (think Unity's asset store or the like).

IF you do build things on your own, don't worry so much about text. Draw the text input fields as if they were empty so they draw efficiently like every other GUI element. Keep their clip regions for text around. Then do another pass drawing the text output for all text fields on that layer combined, calculating the glyph placement with the clip regions. If you have only a single font and no overlapping GUI elements/layers, you'll need only a single extra draw call. Even if you do have a few fonts and layers, we're talking only a handful of extra draw calls. Even if it were a lot, the render performance doesn't matter that much outside of the real-time game screen. Optimize where it matters and don't waste time/effort where it doesn't.

Sean Middleditch – Game Systems Engineer – Join my team!

I'm using something similar to what you described in Approach 1. No problems with performance (although my projects aren't gui heavy), for gui heavy stuff I tend to prefer using Gtk and Qt (when i use C++) or WPF (WinForms in older days) once I work with C#.

As for implementation, in my current version I already have most of GUI elements that are generally used (starting with buttons, checkboxes, through comboboxes, sliders, ending with switchable containers) -> I've also created a simple language to describe my GUI elements, the harder part is actually allowing to specify actions inside the file (F.e. by function name - which works quite well for me).

I'd also like to note that making a renderer for GUI is just a minor thing (the whole GUI logic is larger part - especially when you want to describe GUI using some kind of data files).

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Thanks for the answers people
DTR666 , Mixing two approaches. Nice sugestion, I have considered something a bit different: Using approach 2 for the most complex elements, like text, those would be rasterized on a proper texture. The others could use approach 1.
Seam, Thanks. I will do some research about Chromium Embbeded Framework.
Vilem, Thanks for the advice, You are right. I think I will not create or use a language for describing the GUI. I think I will do it programmatically, with C++ interfaces and objects. But It will for sure have the degree of complexity you sugest.

Okay, well if you will need any advice during the development - either shoot me a PM or write here on forums. I'm always lurking around (hunting heads ph34r.png ... uhm ... posts).

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Hey Artur,

As SeanMiddleditch says, we use CEF in our game engine (and previously Awesomium), It's not so difficult to integrate.

Do not hesitate to PM me if you take this way !

----

www.winthatwar.com

Download our latest demo here.

www.insaneunity.com

@InsaneUnity

@DTR666

If rolling your own, I would also suggest the combo of 1 and 2. I worked out a basic Gui, working with colored triangles(I hadn't implemented textures at the time), and implementing everything essential the same way as wn32 has.

The GUI was rendered immediately when it needed a responsive update(button depressed, popup windows, to a full screen quad, and also regularly as a task for things like data being updated from the simulation(ike the FPS metric). During the normal render loop this was blitted to a fullscreen quad drawn with a single call.

Creating a plethora of different GUI objects was quite a bit of work, daunting even, considering how novice I was/am. A great learning exercise for sure, but something I would not likely repeat. The idea of CSS/HTML support really appeals to me so I think CEF would be the way to go.

This topic is closed to new replies.

Advertisement