GUIs: Materials

From Mod Wiki
Revision as of 10:33, 16 October 2007 by 192.168.0.142 (talk)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Overview

Material system and caching of materials.

Remember having to create 9 windows to draw a window with a border? Now with the _frame keyword you only need one window to draw a window with a border. There are many similar additions to help reduce the number of windows required for certain common types of window drawing. See the Materials page for more information.

The GUI will cache any materials defined in the materials block. Caching the materials avoids stuttering during gameplay and is needed when making binary decls.

materials {
	[alias] [material name]
}

Alias is the name you would use in the guis:

windowDef desktop {
	properties {
		color	backColor	=	1, 1, 1, 0.8;
		string material = [alias];
	}		
}

The material name may be prefixed with a code that tells the gamecode what type of material it is:

  • "literal: [material name]" - same as [material name], no theme lookup.
  • "_frame [material name]" - 9 part material.
  • "_st [material name]" - Specified a rectangle on the material.
  • "_3v [material name]" - 3 vertical parts.
  • "_3h [material name]" - 3 horizontal parts.
  • "_5h [material name]" - 5 horizontal parts.
  • "::[material name]" - Lookup material directly instead of looking up for a theme.

Additional Parameters

If no :: prefix is used then some additional comma separated values may be added after the material name:

  • flipX - Flip texture horizontally.
  • flipY - Flip texture vertically.
  • rect - Specify a certain region, must be used with _st.

Examples

materials {
	"icon_context" "guis/assets/mainmenu/sheet_fill, rect( 324, 165, 24, 24 )"
}
...
// Use _st, lookup material from list of materials above.
handle	iconContext = gui.cacheMaterial( "iconContext",	"_st icon_context" );

Specifying A Rectangle

Icons are almost always grouped together onto larger texture sheets to improve performance and keep things organized. It's possible to create a new material where it draws a specific area of a texture by using the rect keyword when caching materials in GUIs. Here's an example where the players rank icons are being cached, all icons use a specific rectangle on the same material (guis/assets/icons/gdf_ranks01):

// Ranks
materials {
	"guis/assets/icons/rank01"	"guis/assets/icons/gdf_ranks01, rect( 0, 	0, 64, 64 )"
	"guis/assets/icons/rank02"	"guis/assets/icons/gdf_ranks01, rect( 64, 	0, 64, 64 )"
	"guis/assets/icons/rank03"	"guis/assets/icons/gdf_ranks01, rect( 128, 	0, 64, 64 )"
}

Frame

Frames are used for drawing dialogs, buttons, tab buttons, weapon selection buttons in the limbo menu, etc. A frame consists of 9 parts:

  • top left
  • top
  • top right
  • right
  • bottom right
  • bottom
  • bottom left
  • left
  • center

Example from guis/game/hud/materials.include

To draw a frame you would first cache the materials in the GUI, the suffixes _l/_r/_t/_b/_tl/_tr/_bl/_br/_c must be specified or else it won't find all the 9 parts needed for the frame:

// dialog fill
materials {
	"dialog_l"  "guis/assets/mainmenu/sheet_fill, rect( 255, 187, 6, 1 )"
	"dialog_r"  "guis/assets/mainmenu/sheet_fill, rect( 255, 187, 6, 1 ) flipX"
	"dialog_t"  "guis/assets/mainmenu/sheet_fill, rect( 259, 182, 1, 6 )"
	"dialog_b"  "guis/assets/mainmenu/sheet_fill, rect( 259, 182, 1, 6 ) flipY"
	"dialog_tl" "guis/assets/mainmenu/sheet_fill, rect( 255, 182, 6, 6 )"
	"dialog_tr" "guis/assets/mainmenu/sheet_fill, rect( 255, 182, 6, 6 ) flipX"
	"dialog_bl" "guis/assets/mainmenu/sheet_fill, rect( 255, 182, 6, 6 ) flipY"
	"dialog_br" "guis/assets/mainmenu/sheet_fill, rect( 255, 182, 6, 6 ) flipX flipY"
	"dialog_c"  "guis/assets/white"
}

Now create a material handle for "dialog":

properties {
	handle dlgFillMaterial = cacheMaterial( "_dlgFill", "_frame dialog" );		
}

The handle may now be used together with drawCachedMaterial to draw all 9 parts in one go!

3 Parts

Similarly to frames there is vertical or horizontal 3 part materials where there is a top part drawn with a fixed size, a bottom part drawn with a fixed size and a middle part which is stretched depending on the draw rectangle it is being drawn for.

Example from guis/game/hud/materials.include

Scroll bars use a vertical 3 part material. First the materials are cached:

materials {
	"scroll_t" "guis/assets/mainmenu/sheet_add, rect( 149, 213, 11, 11 )"
	"scroll_c" "guis/assets/mainmenu/sheet_add, rect( 149, 224, 11, 11 )"
	"scroll_b" "guis/assets/mainmenu/sheet_add, rect( 149, 213, 11, 11 ) flipY"
}

Now specify a material name for a window:

string material = "_3v scroll";

The gamecode automatically draws the material when the window is drawing so it is not necessary to call drawCachedMaterial to draw it.

5 Parts

The 5 part material is mainly used for top and bottom items in the radial context. There is left edge with a constant width, left part that stretches between the edge part and the center part, a center part that has a constant width, a right part that stretches between the center part and the right edge part.

Example from guis/game/quickchat.include

First the materials are cached:

materials {
	// bottom center radial
	"bottom_center_r_fill_tl"	"guis/quickchat/qchat_fill, rect( 171, 84, 22, 42 )"
	"bottom_center_r_fill_l"	"guis/quickchat/qchat_fill, rect( 192, 84, 1, 42 )"
	"bottom_center_r_fill_c"	"guis/quickchat/qchat_fill, rect( 192, 84, 41, 42 )"
	"bottom_center_r_fill_r"	"guis/quickchat/qchat_fill, rect( 192, 84, 1, 42 )"
	"bottom_center_r_fill_tr"	"guis/quickchat/qchat_fill, rect( 171, 84, 22, 42 ), flipX"
}

A material handle is then saved that can later be used for drawing the 5 part material:

fill = gui.cacheMaterial( "fill", "_5h bottom_center_r_fill" );