Creating a UI

Hi, wasn’t sure if this belonged to this section or the “Game Mechanics” section, as I think it can cover both.

Anyways, I was wondering, how does one go about the UI, more specifically, drawing it. When its drawn and how.
I’ve got an idea on how I might go about it, but I would like to here your opinion.

I would use an external library, but I’m “recreating the wheel” for learning experience.

So what I’m thinking on how it’s, each element is a texture on a quad, if there’s the UI element, the quad is just rotating, or moving or what ever.

Here’s an image, roughly highlighting the quads of what I think is all the separate elements of the UI in one of my favorite games. Fallout 3
Elements highlighted in yellow boxes, btw not a screenshot from my copy of Fallout 3, quick pull off of the internet.
Might need to view full size to see the lines.
For full http://i.imgur.com/QXbuKQG.png

As for how, I imagine that I just render it like I normally would, binding the textures, updating position uniform if need be and binding the VAO and so on.
But do I do this after I render the game and do what ever post-processing? Or at any stage in between or before?
Also, do I create a separate shader program and use it at this point, or set up some sort of sub-routine in my main shader?

A little extra note, I do know about the different types of UI in games. Diegetic, Non-diegetic, Spatial and Meta according to http://www.gamasutra.com/view/feature/4286/game_ui_discoveries_what_players_.php?print=1, personally I don’t know the names by heart.

Thanks.

Your making this way too complicated :slight_smile:

Just don’t multiply the UI things by the same matrix as everything else. In fact the screen’s X coord goes from [-1,1] and the Y coord goes from [-1,1]

Just render all the buttons and UI stuff without any matrices in this area and it’ll always be on screen exactly in the same spot unless you specify otherwise

[quote]Just don’t multiply the UI things by the same matrix as everything else. In fact the screen’s X coord goes from [-1,1] and the Y coord goes from [-1,1]
[/quote]
I figured this, I don’t think I really specifically said anything about this though.
Plus I see no harm in having a matrix to make things like rotation easier, and then passing the coordinates to the GPU via vectors, taking the necessary data from the matrix.
Things would get more complicated though, for 3D aspects of the UI.

I was just unsure about the theory behind it in a sense.

Although after writing it down, it does seem more clear.

How have some of you guys gone about implementing a UI and such?

Pretty much what the Lion King said, draw your 3D stuff first then change the projection matrix so that you can use easy coordinates for 2D stuff.

The following will allow pixel coordinate accuracy for drawing with 0,0 being in the bottom-left corner. If you want the more standard 0,0 in the top-left you can adjust the projection matrix to do so.


  override def toggleOn2D() {
    if (!is2D) {
      val viewport: IntBuffer = BufferUtils.createIntBuffer(16)

      glGetInteger(GL_VIEWPORT, viewport)

      glMatrixMode(GL_PROJECTION)
      glPushMatrix()
      glLoadIdentity()

      glOrtho(viewport.get(0), viewport.get(0)+viewport.get(2), viewport.get(1), viewport.get(1)+viewport.get(3), -1, 1)
      glMatrixMode(GL_MODELVIEW)
      glPushMatrix()
      glLoadIdentity()
      glTranslated(0.375, 0.375, 0.0)  // slight transition for exact pixel positioning

      glPushAttrib(GL_DEPTH_BUFFER_BIT)
      glDisable(GL_DEPTH_TEST)

      is2D = true
    }
  }

  override def toggleOff2D() {
    if (is2D) {
      glPopAttrib()
      glMatrixMode(GL_PROJECTION)
      glPopMatrix()
      glMatrixMode(GL_MODELVIEW)
      glPopMatrix()

      is2D = false
    }
  }

Ok, ok, how would I go about drawing text?
Do I have sprite sheet with all the letters on it, and upon rendering, have a square containing a single letter, having lots of squares to make a sentence?

That is how I do it :slight_smile:
There might be a better way. Especially if the text never changes, then you might just as well draw it on the UI texture :slight_smile:

I’ve managed to set up a basic UI but I have a problem, it’s with my Quad class.

In this class I basically create a quad that’s somewhat hard coded, I take data passed and simply create a quad.

Should I post the problem here or in a new thread?
The problem is a small one though, basically the position of the vertices and the way I’ve set them up. I think.

Also, anyone know any good resources on how to make a pretty UI?

Why use a projection matrix at all when you can just use an orthographic matrix? Unless you’re going for a built into the helmet GUI thing.

I’m not using any matrices in my implementation.

I convert the location in pixels, for example, 50 pixels, to a position from -1 to 1.

The UI renders almost the way I want it, it’s just flipped on the X axis.
Would that also be the U axis?

Or would you say it’s flipped on the Y axis? I dunno, it’s flipped in the up and down direction.

However if I flip the UVs in the quad class, the 3D stuff will get flipped, because I use a quad during the post process stage.

I would add an option to choose whether to flip, but I figured it might be better to have it so this doesn’t happen.
One less thing I would have to worry about.

Update: I figured the best way to go would be to flip the image upon import, but as far as I can tell, PNGDecoder doesn’t have a flip method. (It has decodeFlipped, which I assume just means that I pass a buffer and it does the flip for me) Anyone know how I would go about it?

Got some kind of basic UI working :smiley:

Left is a panel, just an image, the right is a button, managed to get it so if the mouse is on it, it changes state to in focus.

I still need to make a way so that if it’s pressed it does something. As right now the state just changes.
As well as render strings that are made of letters from a sprite sheet or something, instead of having it in an image before hand.

I also still need to sort out flipping the image on loading.

Edit: Need to do a complete redesign, my current implementation is messy. But I have the idea down.

Redesigned a few things.

[s]I must ask, what would the best way to go about linking a button or something to an object, when they seem completely separate?

For example, I click a button, and object A rotates faster, and object B shrinks and grows.[/s]

Never mind, please ignore this.