I once made a HUD using planes that use the principles you need. I'll post the code below:
// Pixel-perfect positioned HUD-panels made from 3D planes,
// by Zerotown in AGK v1.819.
// Original DBPro-code by Cloggy: http://tinyurl.com/oov5bxd
//
// notes: a. Will benefit if ZDepth of objects can be disabled, so the HUD
// actually appears in front of other 3D objects. Currently this
// is not possible, but planned for AGK V2.
//
// b. Uses the actual device resolution (or resolution set in
// the setup.agc-file when using Windows) to position panels,
// regardless of the set virtual resolution.
// ==========================================================================
// ==========================================================================
// define variables
// --------------------------------------------------------------------------
global CamFOV# as float
global HUDBaseX# as float
global HUDBaseY# as float
global ScreenX# as float
global ScreenY# as float
global ZDist# as float
global MaxHUDPanels as integer
type HUDobject
Obj as integer
PosX# as float
PosY# as float
Width as integer
Height as integer
Texture as integer
endtype
// ==========================================================================
// set the screen
// --------------------------------------------------------------------------
SetOrientationAllowed(0, 0, 1, 1)
SetVirtualResolution(1024, 786)
SetResolutionMode(0)
SetPrintSize(20)
// ==========================================================================
// set variables
// --------------------------------------------------------------------------
CamFOV# = 45
ScreenX# = GetDeviceWidth()
ScreenY# = GetDeviceHeight()
HUDBaseX# = 0 - ScreenX# / 2 ` variables needed to convert the coördinates of the HUD-objects to x and y coördinates on the screen
HUDBaseY# = ScreenY# / 2
ZDist# = ((ScreenY# / 2) / TAN(CamFOV# / 2)) * -1 ` distance from cam to make plane scale to exact pixel size (e.g. 10x10 plane takes up 10x 10 pixels on screen etc.)
MaxHUDPanels = 3
dim HUD[MaxHUDPanels] as HUDObject
// ==========================================================================
// load images and create HUD-elements
// --------------------------------------------------------------------------
` LoadImage([nr], "[\path\filename]")
` LoadImage([nr], "[\path\filename]")
CreateHUD(1, 150, 200, 0, 0, 0) ` create three planes that will be used as hud-panels (texture is currently set to 0, so none is loaded)
CreateHUD(2, 100, 100, 200, 200, 0) ` usage: [object nr, width, height, x-pos, y-pos, texture id].
CreateHUD(3, 150, 200, 600, 400, 0)
// ==========================================================================
// main program loop
// --------------------------------------------------------------------------
do
// display some information
print ("FPS : " + str(screenfps()))
print ("Camera PosX: " + str(GetCameraX(1)))
print ("Camera PosY: " + str(GetCameraY(1)))
print ("Camera PosZ: " + str(GetCameraZ(1)))
print ("Camera AngX: " + str(GetCameraAngleX(1)))
print ("Camera AngY: " + str(GetCameraAngleY(1)))
print ("Camera AngZ: " + str(GetCameraAngleZ(1)))
print("")
print("Zdist# : " + str(ZDist#))
for Id = 1 to MaxHUDPanels
print("Panel " + str(Id) + ": PosX: " + str(Hud[Id].PosX#) + ", PosY: " + str(Hud[Id].PosY#))
next Id
// check user input
HandleCamera()
// update planes
UpdateHUD() ` Update the hud postion relative to the screen position
Sync()
loop
// ==========================================================================
// create HUD panel
// --------------------------------------------------------------------------
function CreateHUD(Id, Width, Height, PosX#, PosY#, Tex)
HUD[Id].Width = Width
HUD[Id].Height = Height
HUD[Id].PosX# = PosX#
HUD[Id].PosY# = PosY#
HUD[Id].Texture = Tex
HUD[Id].Obj = CreateObjectPlane(HUD[Id].Width, HUD[Id].Height)
SetObjectDepthReadMode(Hud[Id].Obj, 8) ` make sure the object always passes the depth test and thus is visuble
SetObjectColor(HUD[Id].Obj, Random(0, 255), Random(0, 255), Random(0, 255), 255) ` this colors the plane and is purely for testing-purposes
if Tex > 0
if GetImageExists(Tex) = 1 then SetObjectImage(Hud[Id].Obj, Tex, 0) ` these lines will texture the plain if an image is loaded
endif
endfunction
// ==========================================================================
// place HUD on screen in actual x and y screen positions
// --------------------------------------------------------------------------
function UpdateHUD()
for Id = 1 to MaxHUDPanels
if GetObjectExists(Hud[Id].Obj) = 1 then HudPosition(Hud[Id].Obj, Hud[Id].PosX#, HUD[Id].PosY#, HUD[Id].Width, HUD[Id].Height)
next Id
endfunction
// ==========================================================================
// position HUD panel
// --------------------------------------------------------------------------
Function HudPosition(Obj, PosX#, PosY#, Width, Height) ` (obj = plane nr., x & y = screen pos., height & width = obj. height + width)
CurCamX# = GetCameraX(1)
CurCamY# = GetCameraY(1)
CurCamZ# = GetCameraZ(1)
CamAngX# = GetCameraAngleX(1)
CamAngY# = GetCameraAngleY(1)
CamAngZ# = GetCameraAngleZ(1)
SetObjectPosition(Obj, CurCamX#, CurCamY#, CurCamZ#) ` Place object at camera position
SetObjectLookat(Obj, CurCamX#, CurCamY#, CurCamZ#, 0) ` Set set object to face the camera
SetObjectRotation(Obj, -CamAngX#, WrapValue(CamAngY# + 180), CamAngZ#) ` Rotate plane so it's flat side faces the camera
MoveObjectLocalZ(Obj, ZDist#)
MoveObjectLocalX(Obj, -(HUDBaseX# + PosX# + (Width /2)))
MoveObjectLocalY(Obj, HUDBaseY# - PosY# - (Height /2))
endfunction
`======================================================================================
` Handle input from user
`--------------------------------------------------------------------------------------
function HandleCamera() ` this bit is purely here to show that the panels stay at their relative positions when the camera moves `
key = GetRawLastKey()
if GetRawKeyState(key) = 1
select key
// left cursor, turn camera left
case 37:
RotateCameraGlobalY(1,-1)
endcase
// right arrow, turn camera right
case 39:
RotateCameraGlobalY(1,1)
endcase
// up arrow, tilt camera up
case 38:
if GetCameraAngleX(1) > -30
RotateCameraLocalX(1,-1)
endif
endcase
// down arrow, tilt camera down
case 40:
if GetCameraAngleX(1) < 30
RotateCameraLocalX(1,1)
endif
endcase
// W, move camera forward
case 87:
MoveCameraLocalZ(1,0.2)
endcase
// S, move camera back
case 83:
MoveCameraLocalZ(1,-0.2)
endcase
endselect
endif
endfunction
`======================================================================================
` Calculate the wrap-around value of an angle
`--------------------------------------------------------------------------------------
function WrapValue(Angle#)
If Angle# < 0.0 then Angle# = 360.0 + Angle#
If Angle# > 360.0 then Angle# = Angle# - 360.0
endfunction Angle#