Advertisement

OpenGL HUD

Started by April 19, 2006 01:35 PM
7 comments, last by GameDev.net 18 years, 6 months ago
I'm extremely new to OpenGL, but not game design (i used to use SDL). Is there any way to draw directly to the screen to do a HUD without having to use glTranslate or glRotate or anything else. Either opengl doesn't do this or I'm just looking through the wrong functions. Any insight would be awsome Ozwald~
Search for the millions of threads about 2d using OpenGL. The same method can be used to draw a hud over your 3d scene.
Advertisement
it's simple, use glOrtho and the turn off depthwriting and depthtesting with
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
and you have a good hud drawing mode.

also you can use these functions to help switching back and forth between the different modes.

void ViewOrtho(int x, int y)							// Set Up An Ortho View{	glMatrixMode(GL_PROJECTION);					// Select Projection	glPushMatrix();							// Push The Matrix	glLoadIdentity();						// Reset The Matrix	glOrtho( 0, x , y , 0, -1, 1 );				// Select Ortho Mode	glMatrixMode(GL_MODELVIEW);					// Select Modelview Matrix	glPushMatrix();							// Push The Matrix	glLoadIdentity();						// Reset The Matrix}void ViewPerspective(void)							// Set Up A Perspective View{	glMatrixMode( GL_PROJECTION );					// Select Projection	glPopMatrix();							// Pop The Matrix	glMatrixMode( GL_MODELVIEW );					// Select Modelview	glPopMatrix();							// Pop The Matrix}


you might still have to use glTranslate (you won't get away from that in openGL) but it's definitly a lot easier to draw the hud in this mode.
thanks, lc_overlord. That did the trick very nicely.

Ozwald~
does anyone know how to output variables to the HUD like the score
Thanks
AC
just print what you want to the screen...here's a routine from nehe's tutorial for printing...works just like printf in c

GLvoid glPrint(GLuint glfontlist, GLfloat x, GLfloat y, const char *fmt, ...){	if( glIsList( glfontlist ) == GL_FALSE ) {		// Error Report?		return;	}		glRasterPos2f( x, y );		char text[256];	va_list ap;		if(fmt==NULL) return;		va_start(ap, fmt);		vsprintf(text, fmt, ap);	va_end(ap);		glPushAttrib(GL_LIST_BIT);	glListBase(glfontlist - 32);	glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);	glPopAttrib();}


it uses lists for the font...if you look through nehe's tutorials, and find some of the font/printing text tutorials, you find how to load such.

hope that helps.

Oz~

PS:

int score = 50;glPrint( yourfont, 1.0f, 500.0f, "Your score is: %d", score );
Advertisement
I'm having a problem.

I'm drawing a polygon in perspective view then switching over to ortho view to render text. I can display text but only by using openGL coordinates in an ortho view by using RasterPos2i(x,y)

I want to display my text using Windows coordinates like in the Lesson 32 program on nehe.gavedev.net.

The code to set up perspective is here
______________________________________

void SetupViewPorts(int width, int height)
{
// now setup the viewports
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); // set projection matrix
glLoadIdentity(); // reset projection matrix

// calculate aspect ratio of window
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height,1.0f,1000.0f);

glMatrixMode(GL_MODELVIEW); // set modelview matrix
glLoadIdentity(); // reset modelview matrix
}
-------------------------------------------------------------------------
and my rendering code which renders in the viewport created in previous function
a polygon, then switches over to ortho and renders the text
-------------------------------------------------------------------------
// fuction for rendering
void Render()
{

char output[50] = " ";
char output2[50] = " ";
char ch_zoom[50];

// clear screen and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); // reset modelview matrix



// move one unit into the screen
glTranslatef(0.0f, 0.0f, zoom);
glPushMatrix();
glRotatef(angle, 1.0f, 0.0f, 0.0f);
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(-1.0f, -1.0f, 0.0);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(1.0f, -1.0f, 0.0);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(1.0f, 1.0f, 0.0);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(-1.0f, 1.0f, 0.0);
glEnd();
glPopMatrix();




// setup ortho view to draw text
glPushMatrix();

glMatrixMode(GL_PROJECTION);

glOrtho(0, winWidth, 0, winTop, -1, 1);
glMatrixMode(GL_MODELVIEW);
glColor4f(1.0f, 1.0f, 1.0f, 0.75f);

glRasterPos2i(-4, -4);
// build the string
gcvt(zoom, 4, ch_zoom);
strcpy(output, "Zoom is currently: ");
strcpy(output2, ch_zoom);
strcat(output, output2);

PrintString(listbase, output);

glFlush();
SwapBuffers(g_HDC); // bring back buffer to foreground
angle += 0.01f;
if(angle >= 360.0f)
angle = 0.0f;

}
___________________________________________________________________

can someone help me fix this code and clean it up so I can render my text using windows coordinate system like the nehe.gamedev.net Lesson 32 program?
___________________________________________________________________
The coordinates using ortho mode should be the same as the window coordinates (as in if the res is 800x600, x goes 0-800, y goes 0-600)
If you want true windows coords, use ScreenToClient( hWnd, POINT coords );
or ClientToScreen( <same parameters> );

Oz~

PS:

glOrtho(0, winWidth, winTop, 0, -1, 1);

that should fix it :p
here is my complete code. Maybe you can figure it out.

____________________________________________________________________________
#define WIN32_LEAN_AND_MEAN

#include
#include
#include
#include
#include
#include

// global variables
bool keyPressed[256]; // holds true for keys that are pressed
float angle = 0.0f; // current angle of the rotating triangle
HDC g_HDC; // global device context
HWND g_HWND;

bool b_fullScreen = TRUE; // flag value to test for full screen mode

unsigned int listbase;

int winHeight, winWidth, winTop, winBottom; // rect structure to store window values
float zoom = -10.0f;

// Prototype Functions
void SetupFont();
void Render();
void SetupFullScreenMode();
void SetupViewPorts(int width, int height);
unsigned int CreateBitmapFont(char *fontName, int fontSize);
void PrintString(unsigned int base, char *str);
void ClearFont(unsigned int base);
void Initialize();

// End Prototypes
void Initialize()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // clear to black

glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);

listbase = CreateBitmapFont("Comic Sans MS", 20); // create the bitmap font
}


unsigned int CreateBitmapFont(char *fontName, int fontSize)
{
HFONT hFont; // windows font
unsigned int base;

base = glGenLists(96); // create storage for 96 characters

if(stricmp(fontName, "symbol") == 0)
{
hFont = CreateFont(fontSize, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, SYMBOL_CHARSET,
OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
FF_DONTCARE | DEFAULT_PITCH, fontName);
}
else
{
hFont = CreateFont(fontSize, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
FF_DONTCARE | DEFAULT_PITCH, fontName);
}
if(!hFont)
{
MessageBox(NULL, "Failed to Create Font!", "Font Error", MB_OK);
return 0;
}

SelectObject(g_HDC, hFont);
wglUseFontBitmaps(g_HDC, 32, 96, base);

return base;
}

void PrintString(unsigned int base, char *str)
{
glDisable(GL_DEPTH_TEST);
if((base == 0) || (str == NULL))
return;

glPushAttrib(GL_LIST_BIT);
glListBase(base -32);
glCallLists(strlen(str), GL_UNSIGNED_BYTE, str);
glPopAttrib();
glEnable(GL_DEPTH_TEST);
}

void ClearFont(unsigned int base)
{
if(base != 0)
glDeleteLists(base, 96);
}



void SetupViewPorts(int width, int height)
{
// now setup the viewports
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); // set projection matrix
glLoadIdentity(); // reset projection matrix

// calculate aspect ratio of window
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height,1.0f,1000.0f);

glMatrixMode(GL_MODELVIEW); // set modelview matrix
glLoadIdentity(); // reset modelview matrix
}


//function that sets up fullscreen mode
void SetupFullScreenMode()
{
// do nothing
MessageBox(NULL, "Full screen mode not available yet!", "Fullscreen?", MB_OK);
b_fullScreen = FALSE;
}


// fuction for rendering
void Render()
{

char output[50] = " ";
char output2[50] = " ";
char ch_zoom[50];

// clear screen and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); // reset modelview matrix



// move one unit into the screen
glTranslatef(0.0f, 0.0f, zoom);
glPushMatrix();
glRotatef(angle, 1.0f, 0.0f, 0.0f);
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(-1.0f, -1.0f, 0.0);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(1.0f, -1.0f, 0.0);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(1.0f, 1.0f, 0.0);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(-1.0f, 1.0f, 0.0);
glEnd();
glPopMatrix();




// setup ortho view to draw text
glPushMatrix();

glMatrixMode(GL_PROJECTION);

glOrtho(0, winWidth, winTop, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glColor4f(1.0f, 1.0f, 1.0f, 0.75f);

glRasterPos2i(-4,-4);
// build the string
gcvt(zoom, 4, ch_zoom);
strcpy(output, "Zoom is currently: ");
strcpy(output2, ch_zoom);
strcat(output, output2);

PrintString(listbase, output);

glFlush();
SwapBuffers(g_HDC); // bring back buffer to foreground
angle += 0.01f;
if(angle >= 360.0f)
angle = 0.0f;

}

// function to set the pixel format for the device context
void SetupPixelFormat(HDC hDC)
{
int nPixelFormat; // your pixel format

static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // size of the structure
1, // version, always set to 1
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // support double buffering
PFD_TYPE_RGBA, // RGBA color mode
32, // go for 32 bit color mode
0, 0, 0, 0, 0, 0, // ignore color bits, not used
0, // no alpha buffer
0, // ignore shift bit
0, // no accumulation bits
0, 0, 0, 0, // ignore accumulation bits
16, // 16 bit z-buffer size
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main drawing plane
0, // reserved
0, 0, 0 }; // layer masks ignored

//choose best matching pixel format, return index
nPixelFormat = ChoosePixelFormat(hDC, &pfd);

// set pixel format to device context
SetPixelFormat(hDC, nPixelFormat, &pfd);
}

// the windows Procedure event handler
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HGLRC hRC; // rendering context
static HDC hDC; // device context
char string[] = "Hello world!"; // text to be displayed
int width, height; // window width and height
RECT myWinDimensions;



switch(message)
{
case WM_CREATE: // window is being created

listbase = CreateBitmapFont("Comic Sans MS", 48);
if(MessageBox(NULL, "Do you want to run in fullscreen mode?", "Fullscreen?", MB_YESNO) == IDYES)
{
SetupFullScreenMode();
}
else
{
MessageBox(NULL, "Running in windowed mode", "Fullscreen?", MB_OK);
}
hDC = GetDC(hwnd); // get device context for window
g_HDC = hDC;
SetupPixelFormat(hDC); // call your pixel format setup function

// create rendering context and make it current
hRC = wglCreateContext(hDC); // create rendering context
wglMakeCurrent(hDC, hRC); // make rendering context current
return 0;
break;

case WM_DESTROY: // window is closing
wglMakeCurrent(hDC, NULL); // deselect Rendering context
wglDeleteContext(hRC); // delete rendering context
ClearFont(listbase);
PostQuitMessage(0);
return 0;
break;

case WM_SIZE:
height = HIWORD(lParam); // retrieve width and height
width = LOWORD(lParam);

if (height == 0) // dont want a divied by zero
{
height = 1;
}
g_HWND = hwnd;
SetupViewPorts(width, height);



return 0;
break;

case WM_KEYDOWN:
SetCapture(hwnd);
// is a key pressed?
keyPressed[wParam] = true;
return 0;
break;
case WM_KEYUP:
ReleaseCapture();
keyPressed[wParam] = false;
return 0;
break;


default:
break;
}

return (DefWindowProc(hwnd, message, wParam, lParam));
}

// The application entry point
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX windowClass; // window class
HWND hwnd; // window handle
MSG msg; // message
bool done; // flag saying when your app is complete

DWORD my_exstyle, my_style;

// fill out the window class structure
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = "MyClass";
windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);

// register the window class
if (!RegisterClassEx(&windowClass))
return 0;

if (b_fullScreen)
{
my_exstyle = WS_EX_APPWINDOW; // hide top level windows
my_style = WS_POPUP; // no border on your window
ShowCursor(TRUE); // hide the cursor
}
else
{
my_exstyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // same as regular window
my_style = WS_OVERLAPPEDWINDOW;
}
// class registered, so now create your window
hwnd = CreateWindowEx(NULL,
"MyClass",
"Bitmap Fonts Application in OpenGL",
WS_OVERLAPPEDWINDOW |
WS_VISIBLE |
WS_SYSMENU,
100, 100,
400, 400,
NULL,
NULL,
hInstance,
NULL);

// check if window creation failed( hwnd would equal NULL)
if (!hwnd)
return 0;

ShowWindow(hwnd, SW_SHOW); // display the window
UpdateWindow(hwnd); // update the window

Initialize();
// main message loop
while(true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// Process the message
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if (keyPressed[VK_ESCAPE])
PostQuitMessage(0);
if (keyPressed['A'])
{
zoom += 0.01f;
}
if (keyPressed['Z'])
{
zoom -= 0.01f;
}
// Render Here
Render(); // Call rendering Function
}

}



return msg.wParam;
}
_______________________________________________________________________________

This topic is closed to new replies.

Advertisement