The following code is what I use to “print” text to the screen in my OpenGL programs (or I will be, since I’m still working on this).
Anyone have any suggestions on how to improve the OpenGL part of this? I don’t want to preallocate the texture memory for it and then subload the texture, because that would limit my string size (and I don’t want to have a screen sized texture).
Thanks.
HDC hFontDC=NULL;
HBITMAP hFontBitmap=NULL;
HFONT hFont=NULL;void Font_Print(float x, float y, char *String, …)
{
char *Text=NULL, *Ptr=NULL;
BITMAPINFO BitmapInfo;
RECT Rect;
SIZE Size;
unsigned char *Bitmap;
int i;
va_list ap;Text=(char *)malloc(strlen(String)*2);
if(Text==NULL)
return;va_start(ap, String);
vsprintf(Text, String, ap);
va_end(ap);hFontDC=CreateCompatibleDC(NULL);
hFont=CreateFont(32, 0, 0, 0, FW_BLACK, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, NULL);
SelectObject(hFontDC, hFont);memset(&Size, 0, sizeof(SIZE));
for(Ptr=Text, i=0;;*Ptr++, i++)
{
if(*Ptr==’
‘| |*Ptr==’\0’)
{
SIZE StringSize;GetTextExtentPoint32(hFontDC, Ptr-i, i, &StringSize); if(StringSize.cx>Size.cx) Size.cx=StringSize.cx; Size.cy+=StringSize.cy; if(*Ptr=='\0') break; i=0; }
}
memset(&BitmapInfo, 0, sizeof(BITMAPINFO));
BitmapInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
BitmapInfo.bmiHeader.biWidth=Size.cx;
BitmapInfo.bmiHeader.biHeight=Size.cy;
BitmapInfo.bmiHeader.biBitCount=8;
BitmapInfo.bmiHeader.biPlanes=1;hFontBitmap=CreateDIBSection(hFontDC, &BitmapInfo, DIB_PAL_COLORS, &Bitmap, NULL, 0);
SelectObject(hFontDC, hFontBitmap);SetBkColor(hFontDC, DIBINDEX(0));
SetTextColor(hFontDC, DIBINDEX(255));SetRect(&Rect, 0, 0, Size.cx, Size.cy);
DrawText(hFontDC, Text, -1, &Rect, DT_NOCLIP);// No texture object, just texture OpenGL 1.0 style!
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_ALPHA8, Size.cx, Size.cy, 0, GL_ALPHA, GL_UNSIGNED_BYTE, Bitmap);
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0.0f, (float)Size.cy);
glVertex2f(x, y+(float)Size.cy);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(x, y);
glTexCoord2f((float)Size.cx, (float)Size.cy);
glVertex2f(x+(float)Size.cx, y+(float)Size.cy);
glTexCoord2f((float)Size.cx, 0.0f);
glVertex2f(x+(float)Size.cx, y);
glEnd();
glDisable(GL_TEXTURE_RECTANGLE_EXT);DeleteObject(hFont);
DeleteObject(hFontBitmap);
DeleteDC(hFontDC);free(Text);
}
Edit:
BTW, feel free to use this code if you want! I know some might find it useful (make a unicode version and display chinese, japanese, etc).
Edit again:
Forgot to fix a few things in the code…
[This message has been edited by NitroGL (edited 06-20-2003).]