Facebook Twitter YouTube Frictional Games | Forum | Privacy Policy | Dev Blog | Dev Wiki | Support | Gametee


Thread Rating:
  • 3 Vote(s) - 3.67 Average
  • 1
  • 2
  • 3
  • 4
  • 5
GUI Tutorial Series
Abion47 Offline
Senior Member

Posts: 369
Threads: 22
Joined: Oct 2015
Reputation: 46
#11
RE: GUI Tutorial Series

Get to The Back Of The Line

Now that we've got those pesky basics out of the way, we can get into some of the really fun stuff. From here on out, we'll be putting together some of the barebones terminals that in their essence could be published in their own right (though I imagine you'd probably want to pretty them up first).

Table of Contents
The Basics
Getting More Advanced
Using SOMA's Built-In GUI Styles
  • StationGui (WIP)
  • UrbanGui (WIP)
  • Playing Audio (WIP)

Going Beyond Terminals
  • Setting Up a User Module (WIP)
  • Basic Heads-Up Display (WIP)
  • Target Info Module (WIP)
  • Player HUD Menu System (WIP)

Tutorial Requirements

For this tutorial, you will need the following:
  • A map with a prepared terminal, plus all the necessities.
  • A script file with a prepared OnGui terminal callback function.

Tutorial Source Files

Initial File
Completed File

The Tutorial Itself

So far, when we create our TextPanel or Button, the background has been a solid color. While this is perfectly fine for prototyping levels and explaining concepts, it's a bit lack-luster for a published game. What we want is to shape and format our widgets so they aren't just functional - they look good.

Let's start from where we left off, and put together a simple Button and TextPanel in our OnGui function. (For the sake of this tutorial, we'll ignore the Button's interactivity.)

cImGuiTextFrameData textFrameData;
textFrameData.mFont.mvSize = cVector2f(45, 45);
textFrameData.mColorBase = cColor(0, 0, 0, 0);

ImGui_DoTextFrameExt(
    "In this tutorial, we shall learn how to create awesome backgrounds, so that your terminal isn't just a solid white on black, or boring rectangles of color. The amount of awesome in your terminal is only limited to how much you can give it.",
    0,
    10,
    0,
    textFrameData,
    cVector3f(80, 290, 0),
    cVector2f(880, 660));

cImGuiButtonData buttonData;
buttonData.mFont.mvSize = cVector2f(60, 60);
buttonData.mColorBase = cColor(0.35, 0.35, 0.35);
buttonData.mFont.SetFile("sansation_large_bold.fnt");

bool bButtonState = ImGui_DoButtonExt(
    "gui_button",
    "I Don't Do Anything",
    buttonData,
    cVector3f(220, 90, 0),
    cVector2f(600, 95));

Nothing terribly exciting yet, and running this map through the DevBat will confirm that.

[Image: n5D0vT8.jpg]

Given some bells and whistles, this terminal would be perfectly functional. However, it's not terribly impressing to look at right now, so let's change that up.

Inside the widget data classes is a field called mGfxBackground. This field takes a value of the type cImGuiGfx, which you may remember from the Image tutorial. When given an image, the widget will automatically place the image in the background of your widget, handling all the positioning and scaling itself.

In our case, let's replace the boring solid color backgrounds with some graphics that really make our widgets pop. Change up the OnGui code to look like the following:

cImGuiTextFrameData textFrameData;
textFrameData.mFont.mvSize = cVector2f(45, 45);
textFrameData.mbUseBackgroundGfx = true;
textFrameData.mGfxBackground = cImGuiGfx("graphics/imgui/station/filetreeicons/file_icon.tga");

ImGui_DoTextFrameExt(
    "In this tutorial, we shall learn how to create awesome backgrounds, so that your terminal isn't just a solid white on black, or boring rectangles of color. The amount of awesome in your terminal is only limited to how much you can give it.",
    120,
    10,
    0,
    textFrameData,
    cVector3f(40, 200, 0),
    cVector2f(950, 510));

cImGuiButtonData buttonData;
buttonData.mFont.mvSize = cVector2f(60, 60);
buttonData.mbUseBackgroundGfx = true;
buttonData.mGfxBackground = cImGuiGfx("graphics/imgui/station/filetreeicons/file_icon.tga");
buttonData.mFont.SetFile("sansation_large_bold.fnt");

bool bButtonState = ImGui_DoButtonExt(
    "gui_button",
    "I Don't Do Anything",
    buttonData,
    cVector3f(220, 90, 0),
    cVector2f(600, 95));

The changes may be a bit discrete, so let's step through them.

First, we delete the lines of code that sets the mColorBase data for both widgets. Then we replace them with code that sets the widget's mGfxBackground to a particular image. We also want to set the mbUseBackgroundGfx field for both widgets to true, so we don't risk the widgets ignoring the background images we just gave to it.

(Another sneaky change that you may not have noticed is that I changed the second parameter in the call to ImGui_DoTextFrameExt from 0 to 120, which you might recall as being the padding parameter. The reason for this is that when we are just using text, we don't really want any padding, but using no padding when our TextFrame has a background image set makes the text hug the sides of the image, which doesn't look very good. Also, the background image we are using here has distinct borders, so we want to make sure our text stays within those borders.)

One more thing we need to do (that you might remember from the Image tutorial) is that we need to pre-load our images when we load the map. If you forget to add this step, you run the risk of your terminal taking up a lot of resources in trying to load the image on the fly, or the image not showing up at all. Don't forget this step!

void OnEnter()
{
    ImGui_PreloadImage("graphics/imgui/station/filetreeicons/file_icon.tga");
    ImGui_PreloadImage("graphics/imgui/station/thirdparty/pda/pda_background.tga");
}

Alright, now that we've got our images set, let's see how it looks in the DevBat.

[Image: NPbNl5d.jpg]

...Okay, it's not the prettiest solution in the world, but it's the concept that matters, right?

As it is right now, setting the background graphics could let us go a long way. The problem, however, is that the image being used will be scaled to whatever size the widget is, and a lot of times that scaling makes it look weird or downright ugly. You can see this in how we used the same picture for both our Button and our TextFrame, but the differences between them make them look bizarre.

With the Button, there's another way. The ImGui does background images, but another thing it supports is the use of background frames, which are a series of images that the ImGui uses to build a specialized background that will look great no matter what size you give it.

We're going to have to update our buttonData to make use of background frames. (Hold onto something. This next batch of code might be a tad difficult to digest.)

cImGuiButtonData buttonData;
buttonData.mFont.mvSize = cVector2f(60, 60);
buttonData.mFont.SetFile("sansation_large_bold.fnt");

buttonData.mbUseFrame = true;

buttonData.mGfxFrame.mGfxBorderLeft = cImGuiGfx("graphics/imgui/station/button/big_border_left.tga");
buttonData.mGfxFrame.mGfxBorderTop = cImGuiGfx("graphics/imgui/station/button/big_border_top.tga");
buttonData.mGfxFrame.mGfxBorderRight = cImGuiGfx("graphics/imgui/station/button/big_border_right.tga");
buttonData.mGfxFrame.mGfxBorderBottom = cImGuiGfx("graphics/imgui/station/button/big_border_bottom.tga");

buttonData.mGfxFrame.mGfxCornerTopLeft = cImGuiGfx("graphics/imgui/station/button/big_corner_topleft.tga");
buttonData.mGfxFrame.mGfxCornerTopRight = cImGuiGfx("graphics/imgui/station/button/big_corner_topright.tga");
buttonData.mGfxFrame.mGfxCornerBottomLeft = cImGuiGfx("graphics/imgui/station/button/big_corner_bottomleft.tga");
buttonData.mGfxFrame.mGfxCornerBottomRight = cImGuiGfx("graphics/imgui/station/button/big_corner_bottomright.tga");

buttonData.mColorText = cColor(0, 0, 0);

As you can see, we've done away with our mGfxBackground altogether, and instead we are using a frame. When we create our frame, what we are really doing is we are specifying eight different images. Four of these images represent the four sides, and the other four will be the corners.

(Also, for this particular setup of frame images, the result makes the background basically white, so we need to turn our text black in order to be able to read it.)

Of course, we are using eight more images, so we need to make sure those images are pre-loaded.

void OnEnter()
{
    ...
    ImGui_PreloadImage("graphics/imgui/station/button/big_border_left.tga");
    ImGui_PreloadImage("graphics/imgui/station/button/big_border_top.tga");
    ImGui_PreloadImage("graphics/imgui/station/button/big_border_right.tga");
    ImGui_PreloadImage("graphics/imgui/station/button/big_border_bottom.tga");
    
    ImGui_PreloadImage("graphics/imgui/station/button/big_corner_topleft.tga");
    ImGui_PreloadImage("graphics/imgui/station/button/big_corner_topright.tga");
    ImGui_PreloadImage("graphics/imgui/station/button/big_corner_bottomleft.tga");
    ImGui_PreloadImage("graphics/imgui/station/button/big_corner_bottomright.tga");
}

Alright, let's send this new code through the DevBat.

[img]http://i.imgur.com/e90Z699.jpg[/img]

That Button looks a lot more crisp now, doesn't it?

(Ironically, the TextFrame widget doesn't support frame graphics. You're stuck with using either a general background image or making the background transparent and handling the frame another way.)

We've got our Button and TextFrame all gussied up, but the rest of the terminal looks pretty bland with its solid black, doesn't it? Let's drop in an Image to make it look interesting. Add the following code after the Button logic:

[code]ImGui_DoImage(cImGuiGfx("graphics/imgui/station/thirdparty/pda/pda_background.tga"), cVector3f(0, 0, -1), cVector2f(1024, 788));

(And of course, the corresponding image pre-loading.)

void OnEnter()
{
    ...
    ImGui_PreloadImage("graphics/imgui/station/thirdparty/pda/pda_background.tga");
}

For the most part, this is the same kind of Image you saw way back before. We just set the origin point at [0, 0] and the size to [1024, 788], so that the Image starts at the very upper-lect corner and covers the entire screen of the terminal.

But one thing you may have been curious about all this time is that confusing cVector3f parameter. We've been using it in every ImGui_DoBlank function call we've ever done, but that third value has always been 0. But here, we set it to -1. What gives, right?

That third value represents the widget's "z-order", which is a value in 3D layout rendering systems that tells the renderer what order it should draw its elements in, from least to greatest. That means that anything with a z-order of 0 will always be drawn behind anything with a z-order of 1, which in turn will be behind anything with a z-order of 2, and so on. If several widgets have the same z-order, then they will generally be drawn in the order which they were created.

Up until now, we've never had overlapping widgets, so the z-order has never mattered much. But in this case, we have an image that we always want drawn behind anything else in the terminal, so we make sure that it's z-order is set to a value less than that of other widgets, which is why it is given a z-order of -1, whereas our other widgets have a z-order of 0;

Alright, now that we've got our Image code in, let's see how things look in the DevBat.

[Image: izEEsWH.jpg]

Our terminal is starting to look pretty snazzy, don't you think? (Albeit in a late '90s website sort of way.)

That more or less wraps up this tutorial. In the next one, we'll take a look into how to give our terminal multiple screens that we can switch between.

Extra Credit

In this tutorial, we removed the field settings for the color base in our widget data... but what happens if you specify a color base and a background image?
(This post was last modified: 09-03-2016, 08:04 PM by Abion47.)
11-10-2015, 05:06 AM
Find


Messages In This Thread
GUI Tutorial Series - by Abion47 - 11-07-2015, 09:27 AM
RE: GUI Tutorial Series - by Abion47 - 11-07-2015, 10:44 AM
RE: GUI Tutorial Series - by Abion47 - 11-07-2015, 11:11 AM
RE: GUI Tutorial Series - by Kanthos - 11-07-2015, 12:38 PM
RE: GUI Tutorial Series - by RaideX - 11-07-2015, 01:28 PM
RE: GUI Tutorial Series - by Abion47 - 11-07-2015, 02:52 PM
RE: GUI Tutorial Series - by Abion47 - 11-08-2015, 03:38 AM
RE: GUI Tutorial Series - by A.M Team - 11-08-2015, 12:46 PM
RE: GUI Tutorial Series - by Abion47 - 11-09-2015, 01:28 AM
RE: GUI Tutorial Series - by Abion47 - 11-09-2015, 02:57 AM
RE: GUI Tutorial Series - by Abion47 - 11-10-2015, 05:06 AM
RE: GUI Tutorial Series - by Vale - 11-10-2015, 08:00 AM
RE: GUI Tutorial Series - by Abion47 - 11-10-2015, 08:03 AM
RE: GUI Tutorial Series - by Abion47 - 11-27-2015, 01:20 AM
RE: GUI Tutorial Series - by Abion47 - 07-12-2016, 07:52 PM
RE: GUI Tutorial Series - by Abion47 - 07-12-2016, 10:04 PM
RE: GUI Tutorial Series - by NewPueblo - 09-03-2016, 12:09 AM
RE: GUI Tutorial Series - by Abion47 - 09-03-2016, 08:02 PM



Users browsing this thread: 1 Guest(s)