Xrays in GUIs

From The DarkMod Wiki
Jump to navigationJump to search

Xrays in GUIs

Xray materials can be part of GUI overlays. This page will describe how the "xray glasses" mentioned in the main Xrays article were created.


Creating the GUI

The image

GUI overlays should be 1024x1024 square images with an alpha channel, saved as either:

  • .tga without RLE compression or
  • .dds with DXT5 compression and generating mipmaps.

The GUI will be designed to apply the xray effect only to transparent parts of the overlay image. If you have artistic details like dirt smudges, it may be useful to also create a clean version of the image for purposes of cleanly restricting the xray effect, like below:

Glasses overlay.jpg


The material

The next step is to make a material that uses these images. This is what "xray_glasses_overlay_mixed_warped" from the core assets looks like:

xray_glasses_overlay_mixed_warped
{
	description	"Xray GUI overlay for glasses that shows both the normal and xray models transparently. No xray vision through opaque obstacles. Has blurred effect."

	noshadows
	nonsolid

	{
		blend GL_SRC_ALPHA, GL_ZERO
		map makealpha(guis/assets/hud/glasses_overlay)
		maskcolor
		alpha 0.7
	}

	{
		blend GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA
		xrayRenderMap inclusive        
		program		heatHazeWithMask.vfp
		vertexParm	0	time * 0.008 , time * 0.005		// texture scrolling
		vertexParm	1	0.02							// magnitude of the distortion
		fragmentMap	0	_xray
		fragmentMap	1	textures/sfx/vp1				// the normal map for distortion
		fragmentMap	2	guis/assets/hud/glasses_overlay	// the distortion blend map
	}
}

This material has the following features:

  • The first block creates an alpha mask from the white parts of the glasses overlay image. This allows to restrict the xray vision effect to only the central parts of the overlay image, while the black parts of the overlay image will still show normal vision.
  • The line "alpha 0.7" determines how opaque the xray vision should be. If a value less than 1, xray models would appear transparent. At values greater than 1, they would appear unnaturally bright.
  • The first 2 lines of the second block apply the xray effect to the areas defined by the abovementioned alpha mask.
  • All later lines in the second block are optional, applying a heat haze warp to the xray image. The speed of the warp effect can be modified with the "vertexParm0" line, while the strength of the distortion effect can be adjusted with the "vertexParm1" line.


The GUI

Lastly, create a gui/playertools folder in your FM, add a text file with the intended name of your GUI and change its extension to .gui (in this case: xray_glasses.gui). Then add the following contents to it:

windowDef Desktop
{
   	rect      0, 0, 640, 480
	nocursor 1
	background "gui_backdrop_semiopaque"
	
	windowDef SquareFit
	{
		forceScreenAspect
		hcenter
    		rect      0, 0, 480, 480
		background "xray_glasses_overlay_mixed_warped"
	}
}

This GUI has the following features:

  • it uses a background material called "gui_backdrop_semiopaque" from the core assets, which is simply a pure black image at half transparency. This fills out any space on the screen that's not covered by the overlay image itself. Alternatives would be to delete this line for no background or to use "gui_backdrop_opaque".
  • next comes a square window which will contain the overlay material, "xray_glasses_overlay_mixed_warped", which should consist of a square 1024x1024 image with an alpha channel. The keywords "forceScreenAspect" and "hcenter" will stretch the image to match the player's resolution settings.
  • the 2nd "rect" line allows to adjust the overlay image. The first 2 numbers control its horizontal/vertical position on the screen, while the 2nd numbers control its horizontal/vertical scale.

The GUI is now ready to use. The most suitable way would be to create and destroy it from within the scriptobject of a "glasses" inventory item.


The inventory item

To make an "xray glasses" inventory item, an entity definition and a scriptobject are needed. The aim is to be able to press the "use" key (default: enter) while it's selected in the inventory to create or destroy the GUI overlay.

The def

The def should inherit from the "atdm:playertool" and point to a custom scriptobject to be made later on. Apart from that it needs a suitable model and inventory icon.

entityDef atdm:xray_glasses
{
	"inherit"			"atdm:playertool"

	"editor_usage"			"X-Ray glasses"
	"editor_displayFolder"  	"playertools"

	"model"				"models/darkmod/wearables/headgear/spectacles.ase"
	"scriptobject"			"playertools_xray_glasses"

	"gui"				"guis/playertools/xray_glasses.gui"

	"inv_name"			"X-Ray Glasses"

	"inv_icon"			"guis/assets/hud/inventory_icons/spectacles"
	"inv_droppable"			"1"
	"snd_bounce"			"tdm_impact_knife_large"
	"snd_bounce_wood"		"tdm_impact_knife_large"
}


The scriptobject

See below for the "xray glasses" scriptobject:

#ifndef __XRAY_GLASSES__
#define __XRAY_GLASSES__

float wearing_xray_glasses;

object playertools_xray_glasses : player_tools
{
	void init();
	void inventoryUse(entity userEntity, entity frobbedEntity, float buttonState);

	float overlayHandle;
};

void playertools_xray_glasses::init()
{
}

void playertools_xray_glasses::inventoryUse(entity userEntity, entity frobbedEntity, float buttonState)
{
	if ( !wearing_xray_glasses )
	{
		wearing_xray_glasses = true;
		overlayHandle = $player1.createOverlay(getKey("gui"), ZOOM_GUI_LAYER);
		sys.fadeIn('0 0 0', 1);
	}

	else
	{
		wearing_xray_glasses = false;
		$player1.destroyOverlay(overlayHandle);
		sys.fadeIn('0 0 0', 1);
	}
}

#endif //__XRAY_GLASSES__

It has the following features:

  • First off, it creates a global variable called "wearing_xray_glasses". Since it's global, other scripts will be able to tell whether the player currently has xray glasses on. This may come in useful for you, depending on what you want to do with xrays in your map.
  • The scriptobject itself is fairly barebones: all it needs is a function "inventoryUse" - called whenever the player presses the "use" key with it selected.
  • The "inventoryUse" function checks for whether the "wearing_xray_glasses" variable is true. Depending on the result, it chooses to either create or destroy the xray overlay and updates the variable. You may want to add more to these 2 blocks, such as changing the frobability or solidity of certain entities.
  • Since models can pop a little when they're loaded in by the xray system, the scriptobject has a short 1s fade from black to hide the transition.


See also

Xrays: Main article describing the xray feature.