Jump to content
  • Advertisement
Sign in to follow this  

[XNA] Using Textured Quad for HUD

This topic is 2942 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to render an image of a gun onto a textured quad, which will be part of my HUD (think Minecraft or Ace of Spades).

However, I just can't get the image to rotate or have a Z value.

Here's some code:

public void Render()
//If we have an active screen, don't draw the rest of the HUD, return.
if (displayScreen != null)

// Test

gunBillboardEffect.Parameters["Projection"].SetValue(Matrix.CreateOrthographic(Globals.GameInstance.GraphicsDevice.Viewport.Width, Globals.GameInstance.GraphicsDevice.Viewport.Height, 0, 4000f));


foreach (EffectPass pass in gunBillboardEffect.CurrentTechnique.Passes)


//Draw the normal HUD.



private void DrawBillboard()
VertexBillboard[] billboardVertices = new VertexBillboard[4];

Vector3 v1 = Vector3.Zero;

billboardVertices[0] = new VertexBillboard(new Vector3(v1.X + 10, v1.Y + 10, 0), new Vector2(1, 1));
billboardVertices[1] = new VertexBillboard(new Vector3(v1.X + 10, v1.Y - 10, 0), new Vector2(0, 1));
billboardVertices[2] = new VertexBillboard(new Vector3(v1.X - 10, v1.Y + 10, 0), new Vector2(1, 0));
billboardVertices[3] = new VertexBillboard(new Vector3(v1.X - 10, v1.Y - 10, 0), new Vector2(0, 0));

short[] billboardIndices = new short[] { 3, 2, 0, 3, 0, 1 };

Globals.GameInstance.GraphicsDevice.DrawUserIndexedPrimitives<VertexBillboard>(PrimitiveType.TriangleList, billboardVertices, 0, 4, billboardIndices, 0, 2);

The code above will draw the image on the screen. However, if I add any rotation to the World matrix, or I specify a Z value for the vertices, the image disappears.
I'm not sure if this is a problem with my code, or if I'm just doing something wrong.


public struct VertexBillboard : IVertexType
Vector3 _position;

Vector2 _textureCoordinate;

public static readonly VertexElement[] VertexElements = new VertexElement[]
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
new VertexElement(sizeof(float) * 3, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)

public static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration(VertexElements);
VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration; } }

public VertexBillboard(Vector3 position, Vector2 texcoords)
_position = position;

_textureCoordinate = texcoords;

public Vector3 Position { get { return _position; } set { _position = value; } }
public Vector2 TextureCoordinate { get { return _textureCoordinate; } set { _textureCoordinate = value; } }
public static int SizeInBytes { get { return sizeof(float) * 5; } }


float4x4 World;
float4x4 View;
float4x4 Projection;

Texture BillboardTexture;

sampler BillboardSampler = sampler_state
texture = <BillboardTexture>;
magfilter = POINT;
minfilter = POINT;
mipfilter = POINT;
AddressU = WRAP;
AddressV = WRAP;

struct VertexShaderInput
float4 Position : POSITION0;

float2 TextureCoords : TEXCOORD0;

struct VertexShaderOutput
float4 Position : POSITION0;

float2 TextureCoords : TEXCOORD0;
float4 Color : COLOR0;

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
VertexShaderOutput output;

float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);

output.TextureCoords = input.TextureCoords;

output.Color.rgb = float3(1, 1, 1);
output.Color.a = 1;

return output;

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
float4 texColor = tex2D(BillboardSampler, input.TextureCoords);

float4 color;

color.rgb = texColor.rgb * input.Color.rgb;
color.a = texColor.a;

if(color.a == 0)

return color;

technique Technique1
pass Pass1
// TODO: set renderstates here.

VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();

I'm fairly new to writing my own shaders, so please, be patient with me. :)

Thanks for any help

Share this post

Link to post
Share on other sites
When drawing hud elements there is no need for any matrix transformations. You just need to create the polygon for the item in screen space, ie between 0 and 1 for both the x and y axes. What you're doing in your example is treating it as an in-world element thus rotating it is probably moving it away from where your camera is pointing just as if it was any other object in the world.

In your case you just have to set up your vertices with x/y positions something like X = screenPos.X / screenWidth; Y = screenPos.Y / screenHeight; where screenPos is the desired position of the vertex.

After that just pass it through to an effect written to handle 2D objects so it doesn't take in any matrices it just takes the input position and passes it directly to the pixel shader. I think you can actually just avoid having a vertex shader at all if you don't need one and anything that would normally get sent to the vertex shader will get sent straight to the pixel shader but I can't remember if I just made that up or not :) If you do need a vertex shader then it can be as simple as:

Data screenVertexShader( Data in )
return in;

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!