Jump to content
  • Advertisement
Sign in to follow this  
JasonBaldwin

Creating UI Library for games - How would you want it to be

This topic is 3797 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm still new to programming games and i thought a good project would be to write a UI library to be used in games. I want it to stick to these contstraints:
  • Easily customizable - thinking of making a visual editor
  • Rendered with either OpenGL or DirectX. (If not then is there some way of rendering without using those API's so that it doesnt matter what API the user is using?)
  • Easily Extendible so you can make extra controls or something to that extent
Also what controls would be useful to you? So far I've come up with:
  • Button
  • List Box
  • Check Box
  • Radio Box
  • Check Group
  • Radio Group
  • Progress Bar
  • Static Text
  • Static Image
  • Slider
If there are any others you want just say. To implement all of this I've decided to use OOP and c++. I'm going to make each widget inherited from a "Widget" class. I'm not that good at making design choices so any ideas on how to structure this library? How do i write it so you can customize things and extend them? Thanks in advance for your help

Share this post


Link to post
Share on other sites
Advertisement
Some form of component-based design (possibly with facets/mixin/properties instead of only having properties in component) could be better in this matter than the general inheritance approach.
Anyways, this is the approach that I have pursued with my own little user-interface subsystem, and it looks quite easily extensible and flexible so far, although I have not implemented any of it yet (still working on higher prioritized subsystems).

Share this post


Link to post
Share on other sites
Quote:
Original post by JasonBaldwin
I'm still new to programming games and i thought a good project would be to write a UI library to be used in games.

I want it to stick to these contstraints:

  • Easily customizable - thinking of making a visual editor

  • Rendered with either OpenGL or DirectX. (If not then is there some way of rendering without using those API's so that it doesnt matter what API the user is using?)

  • Easily Extendible so you can make extra controls or something to that extent



Don't bother with the visual editor. When you think about how a system is going to generalise to different resolutions and aspect ratios, and you quickly lose most of the benefits that a visual editor gives you. Instead, think about how to make your components flow like a web page does. You can still provide a visual editor if you feel the need, but generally I don't see the point.

Also, don't render in OpenGL or DirectX. Many people will actually not use either of those directly, and will instead have their own rendering system. Ideally, you should be able to hook into that via an abstract interface. If you can break your GUI rendering down into either rendering images or rendering text, you can just have the user supply functions or classes for these. You can supply D3DX examples to show it working if you like.

Quote:
Also what controls would be useful to you?


Drop-Down List Box, Fixed List Boxes (with multiple selection ability), List Views (ie. multicolumn like Windows Explorer), perhaps TreeViews too.

It's also important to come up with a decent solution to scrolling things. I may want to fit a large panel into a small area and be able to scroll it up and down. I may also want scrollbars to appear automatically when the panel area is not big enough to show the content. (This implies you probably need some sort of Panel widget too.)

Quote:
To implement all of this I've decided to use OOP and c++. I'm going to make each widget inherited from a "Widget" class. I'm not that good at making design choices so any ideas on how to structure this library? How do i write it so you can customize things and extend them?


If you don't know what you're doing, it's usually best to start by programming a game, rather than a library for a game. It's quite hard to get libraries right until you have a good idea of what you're doing.

Anyway, a Widget base class is fine, but the other questions are rather vague. It depends what sort of customisation or extension you have in mind.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
Also, don't render in OpenGL or DirectX. Many people will actually not use either of those directly, and will instead have their own rendering system. Ideally, you should be able to hook into that via an abstract interface. If you can break your GUI rendering down into either rendering images or rendering text, you can just have the user supply functions or classes for these. You can supply D3DX examples to show it working if you like.


Exactly what do you mean by this? Will the user have to write their own classes or functions for rendering?

Share this post


Link to post
Share on other sites
I thought of doing something like this.

I got pretty tired of hard coding buttons in a project I am working on and deciding they need to be a couple of pixels to the left, compiling a new exe, then deciding they looked better the first way. So I had this idea that a GUI object could load its layout at runtime from XML. A GUI object would also have a Reload() method so you wouldn't even need to restart the application to see changes. You could also have methods like GUI::AddButton() so you dont need to mess around with XML if you don't want to.

I got a bit stuck on how to interface a GUI object with a rendering engine. The idea I has was to pass a renderer object that implements an interface with methods like Blit() and Text() in a call to GUI::Draw()


// An interface that you provide as part of your API
class GUIRenderer
{
virtual void Blit()=0;
virtual void Text()=0;
};

// The GUI object
class GUI
{
// ...
};

// elsewhere, the user's renderer inherits from your interface
class myNormalRenderer : public GUIRenderer
{
// implement Blit and Text!
}

// somewhere else again
GUI gui("layout.xml");

// Then, while drawing a scene
gui.Draw(&myRenderer);




The user of your API then has to have a renderer object, inherit from your provided interface, and implement the necessary methods.

That was the rough idea I had anyway. I went as far as looking up the docs for CEGUI to see how that handled the renderer interface. It has a different interface for different graphics APIs. In the DirectX one, you pass in your IDirect3DDevice9*.

Edit: Woah this thread really moved while I was typing all that.

Share this post


Link to post
Share on other sites
Quote:
Original post by JasonBaldwin
Quote:
Original post by Kylotan
Also, don't render in OpenGL or DirectX. Many people will actually not use either of those directly, and will instead have their own rendering system. Ideally, you should be able to hook into that via an abstract interface. If you can break your GUI rendering down into either rendering images or rendering text, you can just have the user supply functions or classes for these. You can supply D3DX examples to show it working if you like.


Exactly what do you mean by this? Will the user have to write their own classes or functions for rendering?


Really, a UI library is a subsystem written specifically for allowing the user to interact with the game via an on-screen interface. The rendering of the UI isn't really included in this.

The UI is a black box of code that:

- Receieves keyboard, mouse and/or controller input events passed to it via a concise interface. It doesn't care about how these input events are caught.

- Interacts the input events with some component hierarchy. Might have a screen management system etc so the user can switch 'pages' in the UI.

- Have an interface to which an external renderer should be hooked or bridged such that the UI can be drawn.

- A UI is actually quite a small thing, it shouldn't do the things that most peoples do.

It's also important to abstract functionality properly in your component hierarchy. If you ask most people what a UIButton's functionality should be, they will say that it should have 4 images of a button that change state when the user moves their mouse over etc. This is incorrect and is a perfect case where you need to be pedantic. A UIButton is a clickable region, with no appearance. You should derrive different types of button from this one. The more functionality you correctly abstract away, the more extensible your UI becomes.

A couple of other things:

- For a UI to work it doesn't need to work like Win32. It doesn't need all that functionality.

- There have been very few games with a good UI, i probably couldn't think of more than 5 that are good (imo). There is plenty to learn in this area.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
Don't bother with the visual editor. When you think about how a system is going to generalise to different resolutions and aspect ratios, and you quickly lose most of the benefits that a visual editor gives you. Instead, think about how to make your components flow like a web page does. You can still provide a visual editor if you feel the need, but generally I don't see the point.

The point is that UI artists can easily design and modify the interfaces without having to edit raw text files and then load the game just to see their changes. That's nowhere near user-friendly (to an artist no less) and increases iteration time immensely. If you want to support different resolutions and aspect ratios, build it into the tool.

In this particle case, I agree that the OP doesn't need a visual editor to start with (or at all, depending on how far the project does or doesn't come along). He/she should just focus on getting the UI system designed and working first. But unless I'm completely misinterpreting your post, I don't see how anyone could suggest that a visual editor isn't necessary for GUI design in general. Even if you had to use the Windows Forms designer and parse resource files, it's better than nothing.

Share this post


Link to post
Share on other sites
Quote:
Original post by JasonBaldwin
Quote:
Original post by Kylotan
Also, don't render in OpenGL or DirectX. Many people will actually not use either of those directly, and will instead have their own rendering system. Ideally, you should be able to hook into that via an abstract interface. If you can break your GUI rendering down into either rendering images or rendering text, you can just have the user supply functions or classes for these. You can supply D3DX examples to show it working if you like.


Exactly what do you mean by this? Will the user have to write their own classes or functions for rendering?


Probably. The key point is that complex UI objects devolve into a series of sprites (and possibly text, and possibly render targets). If you build the complex objects out of the simple objects then the user just needs to supply an implementation of 'sprite' (and optional kin) in your interface.

Share this post


Link to post
Share on other sites
There is a bit of coupling that needs to go on between the renderer and a flow-layout type tree.

For instance, if your drawing text then it is usually the renderer that is going to be the source of the text extent information which is required for the layout algorithm. as an example stuff like font hinting and kerning are going to depend on your specific renderer - ie freetype or gdi.

I wrote something like this but havent quite been able to find a really good way to abstract this renderer/flow coupling in a completely satisfactory way.

Share this post


Link to post
Share on other sites
I figure all GUI's run recursively or that's how I designed mine.

Some components are window and group boxes. I designed GUI's in C++, but never got farther than all the basic components. Oh yeah and multi column list boxes are a pain. (at least if you design them like how .NET's work)

Make sure you design how the event system will work before coding much.

One base class Component then all of the others are derived from it. Container components aka windows and group boxes contain arrays of Components. If 2 windows exist on the form then when the user clicks on one events are passed recursively through the top level components downward. Components can have focus and can also be in a path of focus. Like clicking on a button on a window gives the window path focus and the button focus as it travels recursively from the top down. This makes sense because you will realize that there are certain situations like a window or other object where a container needs to know if any of its children have focus.

The focused component is referenced from the GUIManager which deals with the top level components. Key input instantly goes to focused components while mouse clicking and rollover happen on a recursive design. Remember that for this to work, when a component is added to a container it must register all it's events to its parents and the parent registers them to its parent and so on.

If your stuff gets very complex then think about using buffers. Each component has a buffer the size of the components width and height that acts as a bitmap. Rendering occurs from bottom to top based on state changes. I use this in my flash GUI to get performance that would be otherwise impossible to get with redrawing every frame. The idea is that if a window hasn't changed you just render it's buffer. If something has changed you render that objects buffer to it's parent buffer. Albeit complex GUI's with animations can thwart this optimization.

oh yeah and the GUIManager controls all top level components and handles locked focus and such. Common with dialog boxes. The user chooses something and it gives them a yes or no choice and won't let them go back to the window without hitting an option or an X. Window swapping is the easy part of the GUIManager responsibilities, but make sure to code things to work with that idea. Also realize that input always goes to the GUIManager first. If the input "falls through" the GUI it's handled by the game. So you might have things on mouse click or mouse move that look like:
if(!GUI.HandleMouse(mouseState)){
//game needs to handle it
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!