Gneu.org is a community of developers in many fields coming together in order to collaborate on projects including but not limited to development of applications, artwork, documentation, typeface or design, while devoting a lot of their energy to the needs of those that are new to the various areas. Gneu Members put their energy into tutorials, walkthroughs, discussion as well as many other means of decreasing the slope of the learning curve for those who are trying to enter into a profession or are just interested in expanding their skill set.

Post tutorial Report RSS Basic HUD Modification

This tutorial shows you how to change the HUD by adding a graphic. Adding a graphic to the HUD isn't that difficult. However, it is recommended that you know your way around the Material Creation process.

Posted by on - Basic Client Side Coding

Importing the HUD material

In general, adding graphics to the HUD follows the same procedure as adding any material to Source-based games, so create your graphic at your own discretion. The difference is that we are going to give vtex some extra parameters in the .txt file accompanying the .tga.

We will use the following setup as an example.

"UnlitGeneric"
{
    "nomip" "1"
    "nocompress" "1"
    "nolod" "1"
}

In this case, we are telling vtex...

$nomip
Do not make mip-levels for this texture. Simply because you will not be viewing the HUD from varying distances.
$nocompress
Do not use compression on this texture. This prevents artifacting in our graphic.
$nolod
Do not use lower quality versions of this texture in lower DirectX versions. This is obvious as the difference in performance is marginal.

Once you have the appropriate variables set up, we are now going to run vtex. It is recommended for clarity that you generate your graphics in the /materials/HUD/ directory (if it does not exist, create it).

For the .VMT, we are going to use the following setup.

"UnlitGeneric"
{
      "$basetexture" "HUD/nameofyourgraphic"
      "$translucent"   "1"
      "$translucency" "1"
      "$ignorez" "1"
}

With the .vmt and hence the material completed, all that's left is to change the HUD and add a class. Let's start with the class.

Adding a HUD element class

Open up your copy of MSVS. Do a search for class CHud. You should be able to cycle through a number of files. I recommend you keep all these stock and if you edit, back them up so you can keep them for reference.

All we are trying to do is put a graphic on the screen. In Half-Life 2 there is a function we have to call in order to get this to happen, called paint. We are going to need a variable to act as a place holder for our sprite so that we can call it in the game via the paint function. It would also be nice to be able to turn this on and off, so we are going to learn how to use cvars to control HUD elements in this way.

Here is our example class definition.

#include "hudelement.h"
#include 

using namespace vgui;

class CHudImport : public CHudElement, public Panel
{
   DECLARE_CLASS_SIMPLE( CHudImport, Panel );

   public:
   CHudImport( const char *pElementName );
   void togglePrint();
   virtual void OnThink();

   protected:
   virtual void Paint();
   int m_nImport;
};

Drop the above code into hud_import.h. Remember, the simpler you keep things now, the easier it will be to understand your code later if you have to alter it.

Now, create a new .cpp file called hud_import.cpp. Here are the required includes and pre-function statements (top of your .cpp file):

#include "hud.h"
#include "cbase.h"
#include "hud_import.h"
#include "iclientmode.h"
#include "hud_macros.h"
#include "vgui_controls/controls.h"
#include "vgui/ISurface.h"

#include "tier0/memdbgon.h"

using namespace vgui;

DECLARE_HUDELEMENT( CHudImport );

In order to kick this off we have to load the texture pointer variable. The best place for that is the constructor of the class.

What we are going to do:

  • Get the viewport and parent it
  • make it invisible, but with alpha 100%
  • create a new texture id for our texture/sprite
  • connect the id to the texture
  • have it show only if you have the suit and if you aren't dead

Here is how it's done.

CHudImport::CHudImport( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudImport" )
{
    Panel *pParent = g_pClientMode->GetViewport();
    SetParent( pParent );   
   
    SetVisible( false );
    SetAlpha( 255 );

    //AW Create Texture for Looking around
    m_nImport = surface()->CreateNewTextureID();
    surface()->DrawSetTextureFile( m_nImport, "HUD/import" , true, true);

    SetHiddenBits( HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
}

Our graphic starts out invisible, so we have to paint it now. Let's go on to the paint function. This one, although simpler, has a very important part associated with sizing and spacing to deal with.

void CHudImport::Paint()
{
    SetPaintBorderEnabled(false);
    surface()->DrawSetTexture( m_nImport );
    surface()->DrawTexturedRect( 2, 2, 128, 128 );
}

First, we set the paint border to false. Next we draw our texture onto our surface. The next line is the important part. You actually define where you put your panel and how large it is in your HudLayout.res file. This last statement is attached to the image itself. You set its values like this...

surface()->DrawTexturedRect( xspacing , yspacing, xsize, ysize );

You would put your own values in there according to the size of your picture.

There are two steps to go, our cvar toggle as well as editing the HudLayout.res.

Defining the ConVar

First, let's define the cvar. Go back up to the top of the cpp file and paste this:

static ConVar show_beta("show_beta", "0", 0, "toggles beta icon in upper right corner");

show_beta is the variable name that we're using as an example. We're actually creating the series of pictures on the second post.

This variable will allow us to type show_beta 1 into the console.

But what will that do for us, we need a function to test it.

void CHudImport::togglePrint()
{
    if (!show_beta.GetBool())
        this->SetVisible(false);
    else
        this->SetVisible(true);
}

Not too complex, just a traditional boolean status. And since its something that can change at any time, we should put it into our think function so it is tested always.

void CHudImport::OnThink()
{
    togglePrint();

    BaseClass::OnThink();
}

And that's it. Build, so we can move onto the .res.

Editing HudLayout.res

Open up /scripts/HudLayout.res under your mod's main directory and paste the following in it.

HudImport
{
    "fieldName" "HudImport"
    "xpos" "r86"
    "ypos" "6"
    "wide" "80"
    "tall" "34"
    "visible" "0"
    "enabled" "1"
      
    "PaintBackgroundType"   "2"
}

There are a number of settings to choose from. For more information on VGUI schemes, you can read VGUI Documentation#Schemes.

Booting the game now, you should be looking at your HUD, with a graphic in the upper right corner of the screen drawn with rounded corners.

Post comment Comments
raphael103
raphael103 - - 31 comments

where do i put all those codes?

Reply Good karma Bad karma+1 vote
bob_gneu Author
bob_gneu - - 62 comments

Im sorry? what do you mean? The tutorial is pretty clear in explaining how to set it up.

Reply Good karma+3 votes
jmdigital
jmdigital - - 129 comments

Exactly what i needed thanks man :)

Reply Good karma Bad karma+1 vote
lebofly
lebofly - - 197 comments

it dosnt say what cpp files he is talking about you just say for the cpp enter this code or something not which cpp and where it can be found

Reply Good karma Bad karma+1 vote
bob_gneu Author
bob_gneu - - 62 comments

The class name at the beginning of the code blocks is what tells you where it goes. Your commentary is not really very difficult. If you need assistance with CPP you can easily get a tutorial for that.

Reply Good karma+1 vote
bob_gneu Author
bob_gneu - - 62 comments

Thank you for the input, but i am actually the original author of the article.

Reply Good karma0 votes
Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: