Heads Up Display Stencils

This is a request for a simple HUD which takes advantage of the use of stencils. I äm currently struggling with the subject at them moment and a snippet of how it’s done would be beneficial.

Thanks, Asparagus.

Well stencils have a lot of applications. What are you looking to do

As the arrow fills up, the use of stencils would stop it from drawing outside of the area.

Could you not just draw a polygon?

This is not what I plan to do. I think you misunderstood. I can draw a poly fine for the outline triangular shape, but for testing with stencils I want to draw a box with a growing length to fill the arrow, however it comes out of the arrow shape.

You can use stencils…Or do a better job with base functions like polys and rects

what on earth are you talking about
that is a terrible idea

OP i’m writing you some skeleton code, hold on

  1. Draw your bar with filler texture underneath
  2. Draw a cutout arrow .png on top

KISS, If you don’t need a fully re-sizable solution then that’s gonna work fine.

I think what ollie is saying is that you can draw a png texture of the hollow shape of the arrow, and another one underneath it of the filled shape, but using a render scissor rectangle to hide/show the fill from one side to the next.

If ollie didn’t mean that, well, that’s the easiest way.

Regardless, I’m still writing you the stencil code just so you can see. The correct solution is a png with scissor rectangles, though.

[editline]10th February 2015[/editline]

[lua]–you have a rectangle and a triangle to limit the drawing to
–the stencil will draw one single rectangle that only shows up within the two desired shape
–because i’m using a polygon for the triangle, i may as well do it for the rectangle too

local rectangle = {}
–rectangle looks like:
– D C
– A B
rectangle.x, rectangle.y = 0, ScrH()-100 --bottom left corner of rectangle (A)
rectangle.w, rectangle.h = 400, 100–dimensions of rectangle
rectangle.poly = {
{x=rectangle.x, y=rectangle.y}, --A
{x=rectangle.x+rectangle.w, y=rectangle.y}, --B
{x=rectangle.x+rectangle.w, y=rectangle.y-rectangle.h}, --C
{x=rectangle.x, y=rectangle.y-rectangle.h} --D
}
local triangle = {}
–triangle looks like:
– C
– B
– A
triangle.x, triangle.y = rectangle.x+rectangle.w, rectangle.y+50 --bottom left corner of triangle (A)
triangle.w, triangle.h = 100, rectangle.h+100 --will now draw 50 units below and above the rectangle
triangle.poly = {
{x = triangle.x, y = triangle.y}, --A
{x = triangle.x+triangle.w, y = triangle.y-triangle.h/2}, --B
{x = triangle.x, y = triangle.y-triangle.h} --C
}

hook.Add(“HUDPaint”,“stencilpoly”,function()
render.ClearStencil()
render.SetStencilEnable(true)
render.SetStencilWriteMask(255)
render.SetStencilTestMask(255)
render.SetStencilFailOperation(STENCILOPERATION_KEEP)
render.SetStencilZFailOperation(STENCILOPERATION_KEEP)
render.SetStencilPassOperation(STENCILOPERATION_REPLACE)
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_ALWAYS)
render.SetStencilReferenceValue(10)
surface.SetDrawColor(255,0,0,50)
surface.DrawPoly(rectangle.poly)
surface.DrawPoly(triangle.poly) --the arrow is now written part-visibly to the stencil buffer as value 10
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_EQUAL)
render.SetStencilPassOperation(STENCILOPERATION_KEEP)
surface.SetDrawColor(255,0,0,255)
surface.DrawRect(rectangle.x,triangle.y-triangle.h,LocalPlayer():Health()/100*(rectangle.w+triangle.w),triangle.h)
render.SetStencilEnable(false)
end)[/lua]

It gets a bit messy with the screen coordinates towards the end, but it works. An arrow appears on your lower left, built of polygons, and it uses a stencil to fill the shape. Learn more about how the stencils work here.

however, what you SHOULD do for your simple HUD’s purpose, is simply draw a hollow .png texture of your arrow to the screen, and draw a filled version below it that uses scissor rectangles to limit where the filled image is drawn