PDA

View Full Version : Hud drawing

DarkLore
04-26-2001, 01:56 AM
Hello everybody.

I'm making an x-wing type game, and I need help drawing the hud, so that it remains stable and in front of the camara.

I thought that maybe with the camara pos and camaralookat pos, I can create a normal vector the plane where the hud should be, but I can't manage to create that plane, so any help with the maths involved would be really appreciated.

Tomas.

bsenftner
04-26-2001, 06:52 AM
In my engine, I have an implementation of the LookAt() function from MESA, and in that logic I retain the camera's basis vectors for use later.

Here's my logic:

// --------------------------------------------------------------------------
// This routine will generate a lookAt matrix provided that the eye position,
// a viewing target have been set. An internal "up" vector may also be set,
// but defaults to the {0,1,0} vector. The result is stored in m_viewMat:
// --------------------------------------------------------------------------
inline void LookAt( void )
{
// create a rotation matrix by calculating a camera direction vector,
// and then using that to generate the remaining vectors for a rotation mat:

// m_basisZ vector is the direction vector from target to the eye:
m_basisZ = m_eye - m_target;
m_basisZ.Normalize();

// make sure the source data for the up vector is not modified:
m_basisY = m_up;

// m_basisX = m_basisY % m_basisZ; // cross product... same as my old CrossProductFVector( &y, &z, &x ); x is the result
// m_basisY = m_basisZ % m_basisX; // cross x & z to insure that we're perpendictular
//
m_basisX = m_basisY.Cross( m_basisZ );
m_basisY = m_basisZ.Cross( m_basisX );

// normalize these guys:
m_basisX.Normalize();
m_basisY.Normalize();

// directly set the values to construct a rotation matrix:
// glow::Mat4f rotMat;
CMat4f rotMat;

rotMat.SetVal( 0,0, m_basisX.GetX() ); rotMat.SetVal( 0,1, m_basisX.GetY() );
rotMat.SetVal( 1,0, m_basisY.GetX() ); rotMat.SetVal( 1,1, m_basisY.GetY() );
rotMat.SetVal( 2,0, m_basisZ.GetX() ); rotMat.SetVal( 2,1, m_basisZ.GetY() );
rotMat.SetVal( 3,0, 0.0f ); rotMat.SetVal( 3,1, 0.0f );

rotMat.SetVal( 0,2, m_basisX.GetZ() ); rotMat.SetVal( 0,3, 0.0f );
rotMat.SetVal( 1,2, m_basisY.GetZ() ); rotMat.SetVal( 1,3, 0.0f );
rotMat.SetVal( 2,2, m_basisZ.GetZ() ); rotMat.SetVal( 2,3, 0.0f );
rotMat.SetVal( 3,2, 0.0f ); rotMat.SetVal( 3,3, 1.0f );

// construct a translation matrix:
// glow::Mat4f tranMat;
CMat4f tranMat;
tranMat.SetTranslation( -m_eye.GetX(), -m_eye.GetY(), -m_eye.GetZ() );

// finally generate our lookAt matrix:
// m_viewMat = rotMat * tranMat;
m_viewMat = rotMat.CMat4fMult( tranMat );
}

// -------------------- get the last calculated x,y,z basis vectors -----------------
inline void GetBasisVectors( CVec3f *leftRight, CVec3f *upDown, CVec3f *inOut )
{
*leftRight = m_basisX;
*upDown = m_basisY;
*inOut = m_basisZ;
}

Note that 'leftRight' points to the right, 'upDown' points up and 'inOut' points into the camera (out of the screen.)

These are normalized vectors, so you can simply get these basis vectors, and then you'll know your various directions relative to the current camera view.

This logic right here will calculate the 4 corners of your screen at that near clipping plane in world coordinates:

// calculate the x,y max,min bounds for the near clipping plane:
double ymax = gApp->GetCameraZNear() * tan( gApp->GetCameraFOV() * CMath: http://www.opengl.org/discussion_boards/ubb/tongue.gifi / 360.0 );
double ymin = -ymax;
double xmin = ymin * gApp->GetCameraAspect();
double xmax = ymax * gApp->GetCameraAspect();

// get direction vectors for the current view:
CVec3f leftRight, upDown, inOut;
gApp->GetCameraBasis( &leftRight, &upDown, &inOut );
// 'inOut' points in, towards the camera but we want it to point outwards:
inOut.Negate();

// figure out the coord that is the world space screen center:
CVec3f cameraPosition = gApp->GetCameraPosition();
CVec3f worldSpaceScreenCenter( cameraPosition );
worldSpaceScreenCenter += (inOut * gApp->GetCameraZNear());

// calculate the near clip plane frustum corner coordinates:
CVec3f topLeft( worldSpaceScreenCenter ),
topRight( worldSpaceScreenCenter ),
botLeft( worldSpaceScreenCenter ),
botRight( worldSpaceScreenCenter );

// project the 'top' points up:
topLeft += (upDown * ymax);
topRight += (upDown * ymax);

// project the 'bottom' points down:
botLeft += (upDown * ymin);
botRight += (upDown * ymin);

// project the 'left' points left:
topLeft += (leftRight * xmin);
botLeft += (leftRight * xmin);

// project the 'right' points right:
topRight += (leftRight * xmax);
botRight += (leftRight * xmax);

There may be easier ways to calculate this, but it seemed so simple, I like this method.

Once you have the 4 corners at the near clip plane, just nudge them back a tad (so they don't get clipped) and draw your hud. (Nudge back further if you have a 3D hud http://www.opengl.org/discussion_boards/ubb/wink.gif )

-Blake

bsenftner
04-26-2001, 06:56 AM
Very strange, this discussion board software put a smiley face inside one of my above equasions (previous post.)

It may do it again here:

CMath: http://www.opengl.org/discussion_boards/ubb/tongue.gifi / 360.0

that should read CMath colon colon pi / 360.0

:P:P:P:PP:P:P:P:P:P:P:P:P:PP:P:P:P:P

-Blake

Leo
04-26-2001, 08:41 AM
Instead of translating the HUD into 3D space, why not switch GL into an orthographic projection draw the HUD, and then switch it back afterwards.

cass
04-26-2001, 12:44 PM
I second this previous post. Just change your modelview and projection matrices.

Thorz
04-27-2001, 08:18 AM
I agree as well, change to Ortho then back again.
Here are the commands I'm using in the Sim I'm working on...
It's programmed in Delphi, but the OpenGL commands aren't any different.

glMatrixMode(GL_PROJECTION); // Set up Perspective Clipping Volume
gluPerspective(zoom, aspect, Cnear, CFar);
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
gluLookAt(AX,Alti,AZ, AX-CX,Alti+CY,AZ-CZ, 0,1,0); // Point the camera

Draw 3D Environment

glMatrixMode(GL_PROJECTION);
gluOrtho2D(0, Form3.ClientWidth-1, 0, Form3.ClientHeight-1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity; // Lower Left Corner of Screen = (0,0)

Disable OpenGL Lighting so the HUD colors come out looking right...

Draw HUD