Advanced Modding - Drawing a GUI with vanilla methods


I want to show you how to use methods provided by vanilla Minecraft to draw GUIs on the screen.


3/10 - Relatively Easy


Forge Version

This Tutorial was created with Forge for Minecraft 1.8. If anything doesn't work with other versions, please contact me!

A few words at the beginning

In this tutorial I'll show you how to use the methods provided by vanilla Minecraft to draw content on a GUI. This will work for GUIs that extend either GuiScreen or GuiContainer (Note that GuiContainer extends GuiScreen itself).

I'll show you some methods and objects that are useful, however I won't explain every single method in detail. Every GUI is different, so there is no way that works everytime. GUI programming is based on trial and error (that's my own experience), so you basically need to experiment with the methods given.

A good way to learn how to use new methods is looking into vanilla code. Very likely, there is a vanilla GUI that does what you want to achieve.

Methods to override

If you are using a subclass of GuiContainer (Gui with inventory) as your GUI class, you always have to override drawGuiBackgroundLayer. This method is used to draw things behind the items in the inventory, for instance the background texture. There is also another method that can be overridden namely drawGuiForegroundLayer. This method is used to draw things in front of the items, for instance inventory titles.


If you are using a subclass of GuiScreen (Gui without inventory) as your GUI class, you need to override drawScreen.


Those three methods are all bit different, so I created a table to compare them:

drawGuiBackgroundLayer drawGuiForegroundLayer

Initially called to render the gui screen. GuiContainer overrides this method to call drawGuiBackgroundLayer and drawGuiForegroundLayer
Arguments: partial tick time, mouse coordinates
Arguments: mouse coordinates
Arguments: mouse coordinates, partial tick time
Position 0|0 is the top left screen corner
Position 0|0 is the top left GUI corner
Position 0|0 is the top left screen corner
Abstract in GuiContainer
Method is empty in GuiContainer
Must call superclass method

The most important thing to remember is the position of the coordinate origin 0|0, because in drawGuiForegroundLayer it is different from the other methods.

Useful variables and objects in GUIs

There are several variables that are quite useful when drawing GUIs.

  • zLevel
    Declared in Gui.class
    Defines the current "height" the draw calls are executed at. A higher value overrides objects drawn at a lower z level.
  • width / height
    Declared in GuiScreen.class
    Contain the width and height of the screen. Should not be edited.
  • xSize / ySize
    Declared in GuiContainer.class (not available for GuiScreen subclasses)
    Contain the x and y size of the GUI texture space. Should be set in the constructor.
  • guiLeft / guiTop
    Declared in GuiContainer.class (not available for GuiScreen subclasses)
    Contain the x and y position of the top-left corner of the GUI texture space. Calculated automatically if the size is set correctly in the constructor.
  • mc
    Declared in GuiScreen.class
    Contains the instance of Minecraft. Replacement for calling Minecraft.getMinecraft().
  • itemRender
    Declared in GuiScreen.class
    Contains the instance of the Minecraft Item Renderer. Replacement for calling mc.getRenderItem().
  • optionsBackground, statIcons and icons
    Declared in Gui.class
    Resource locations for the textures "textures/gui/options_background.png", "textures/gui/container/stat_icons.png" and "textures/gui/icons.png".

Methods for rendering

The following methods can be used to render things onto the GUI screen. They can only be called from inside a GUI class (subclass of GuiScreen).

Method location);

This method loads the image at the given resource location and binds it to the renderer.

A resource location is an object that contains the location of a resource in the file system. There a two constructors for a resource location:

new ResourceLocation(String location)

Example: new ResourceLocation("tutorial:textures/gui/a_texture.png")


new ResourceLocation(String domain, String path)

Example: new ResourceLocation("tutorial", "textures/gui/a_texture.png")


The resources do not neccessarily need to be .png files, but for textures this is the only valid file type. Note that "tutorial" is the modid. The file shown here is placed in assets/tutorial/textures/gui/a_texture.png.


GlStateManager.color(float r, float g, float b, float a);

Not a real GUI method, but also very useful: This method sets the rendering color. If you want to render a texture, you should always call this method before to set the color to white (This needs to be done only once if the color is not changed by other methods).

Example: (Setting color to white)

GLStateManager.color(1.0f, 1.0f, 1.0f, 1.0f)

this.drawHorizontalLine(int startX, int endX, int y, int color)

Draws a horizontal 1-pixel line. I personally never used this method, but maybe someone needs it.

The color values here need to be encoded as a single integer. Therfore, you can use this online tool: External Link

This changes the color!

this.drawVerticalLine(int x, int startY, int endY, int color)

This one is self-explanatory if you've read the one above.
This changes the color!

this.drawRect(int left, int top, int right, int bottom, int color)

This method draws a filled rectangle with the given coordinates and the given color value. This changes the color!


this.drawGradientRect(int left, int top, int right, int bottom, int startColor, int endColor)

This method draws a filled rectangle with a vertical gradient. The start color is the top one, the end color the bottom one.

This changes the color!


this.drawTexturedModalRect(int x, int y, int textureX, int textureY, int width, int height)

This method draws a textured rectangle at the position x/y with the size width/height. The texture is assumed to be 256*256. textureX and textureY are the coordinates of the top-left corner of the texture on the currently bound image in pixels. The texture may be larger (512*512, 1024*1024, ...), then the pixel counts are multiplied by the factor.



My texture is 512*512. I want to draw a rectangle at 10|10 which is 20*20 pixels large. The texture for the rectangle must be 40*40 on the texture sheet, because it's two times larger than 256*256. The texture's coordinates on the 512*512 texture sheet are 100|0 (scaled down to 256*256 this would be 50|0!).

The method is:

this.drawTexturedModalRect(10, 10, 50, 0, 20, 20);

Always remember that the coordinates refer to a 256*256 texture!

this.drawModalRectWithCustomSizedTexture(int x, int y, float u, float v, int width, int height, float textureWidth, float textureHeight)

The same as above, howerver you can set the texture size here.


The texture is 256*521 and I want to render an image on it which is located at 10|256 and 20*20 pixels large.

this.drawModalRectWithCustomSizedTexture(10, 10, 10, 256, 20, 20, 256, 512);

this.fontRenderer.drawString(String string, float x, float y, int color, boolean shadow)

Draws a String at the given position (don't ask why the coordinates are floats. I don't know). The color is the base color, it can be overridden with formatters (§a or similar) in the text.

This changes the color!

this.fontRenderer.getStringWidth(String string)

Returns the width of the given String. Can be used to center Strings.

this.fontRenderer.trimStringToWidth(String string, int width)

Returns a new String that is trimmed to the given width in pixels.

this.fontRenderer.drawSplitString(String str, int x, int y, int wrapWidth, int textColor)

Draws a String with automatic line wrap when the wrapWidth is exceeded.


With those methods it is possible to create fairly fancy GUIs. However, how  you create them and how it will look like is up to you. There's no perfect way and everyone has their own style. Just try something out and hopefully, it'll look cool.

Recommended tutorials to continue with

Take a look at the tutorial overview and decide what you want to do next.

Comments and Questions:

If you want to report modding problems, please make sure to include the code in a pastebin link or something else! Don't just write "It doesn't work", otherwise your post will be deleted. For more complicated problems, please use the troubleshooter form.