Skip to content

Instantly share code, notes, and snippets.

@Shtille
Last active January 3, 2016 17:20
Show Gist options
  • Save Shtille/30dff1757f5ab1c82122 to your computer and use it in GitHub Desktop.
Save Shtille/30dff1757f5ab1c82122 to your computer and use it in GitHub Desktop.
Create OpenGL diplay lists for custom Windows font
font = new Font();
const int nBmpSize = Font::GetBmpSize();
const int nCharSize = nBmpSize / 16;
// Read preferences
int iWidth = (bold) ? FW_BOLD : FW_DONTCARE;
DWORD dwItalic = (italic) ? TRUE : FALSE;
DWORD dwUnderline = (underline) ? TRUE : FALSE;
DWORD dwStrikeOut = (strikeout) ? TRUE : FALSE;
DWORD dwFamily = family;
// Create desired font
HFONT hFont;
hFont = CreateFontA(nCharSize, // The height, in logical units, of the font's character cell or character.
0, // The average width, in logical units, of characters in the requested font.
0, // The angle, in tenths of degrees, between the escapement vector and the x-axis of the device.
0, // The angle, in tenths of degrees, between each character's base line and the x-axis of the device.
iWidth, // The weight of the font in the range 0 through 1000
dwItalic, // Specifies an italic font if set to TRUE.
dwUnderline, // Specifies an underlined font if set to TRUE.
dwStrikeOut, // A strikeout font if set to TRUE.
RUSSIAN_CHARSET, // The character set.
OUT_OUTLINE_PRECIS, // The output precision.
CLIP_DEFAULT_PRECIS, // The clipping precision.
ANTIALIASED_QUALITY, // The output quality.
VARIABLE_PITCH | dwFamily, // The pitch and family of the font.
fontname); // A pointer to a null-terminated string that specifies the typeface name of the font.
assert(hFont);
if (!hFont)
{
delete font;
return;
}
// Create bitmap
HDC hdcWindow = GetDC(NULL);
HDC hdcBitmap = CreateCompatibleDC(hdcWindow);
HBITMAP hBitmap = CreateCompatibleBitmap(hdcWindow, nBmpSize, nBmpSize);
// Select objects
SelectObject(hdcBitmap, hBitmap);
SelectObject(hdcBitmap, hFont);
// Select colors
SetBkColor(hdcBitmap, 0);
SetTextColor(hdcBitmap, ((COLORREF)(((BYTE)(255) | ((WORD)((BYTE)(255)) << 8)) | (((DWORD)(BYTE)(255)) << 16))));
// Fill out our bitmap with symbols
if (GetCharABCWidths(hdcBitmap, 0, 255, font->Abc))
{
int i, x, y;
char temp[2] = {};
// We now have an array of ABC structures
for (i = 0; i < 256; ++i)
{
x = (i % 16) * nCharSize;
y = (i / 16) * nCharSize;
temp[0] = i;
TextOutA(hdcBitmap, x, y, temp, 1);
}
}
// Get the BITMAP from the HBITMAP
BITMAP bitmap;
GetObject(hBitmap, sizeof(BITMAP), &bitmap);
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bitmap.bmWidth;
bi.biHeight = bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
assert(bi.biBitCount == 32);
u8 *lpbitmap = new u8[bi.biWidth * bi.biHeight * (bi.biBitCount / 8)];
// Get bits from source image, but notice what all alpha bits are set to 0
GetDIBits(hdcBitmap, hBitmap, 0, (UINT)bitmap.bmHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
// Make pixels with text data non-transparent
for (int i = 0; i < bi.biWidth * bi.biHeight * 4; i += 4)
if (lpbitmap[i] > 0)
lpbitmap[i + 3] = 255;
CreateTextureFromData(font->texture_, (int)bi.biWidth, (int)bi.biHeight, graphics::Image::Format::kRGBA8, lpbitmap);
delete[] lpbitmap;
assert(font->texture_);
// Scale factor to scale new size to old size (supposed to be 1.6f)
const f32 scale = 1.6f;
// Finally create display lists
font->base_ = glGenLists(256);
ChangeTexture(font->texture_);
for (s32 i = 0; i < 16; i++)
{
for (s32 j = 0; j < 16; j++)
{
// standart sizes and offsets in pixels
s32 sym = i * 16 + j;
f32 offA = (f32)font->Abc[sym].abcA / (f32)nBmpSize; // 0 to 1
f32 offB = (f32)font->Abc[sym].abcB / (f32)nBmpSize; // 0 to 1
f32 offC = (f32)font->Abc[sym].abcC / (f32)nBmpSize; // 0 to 1
glTranslatef(offA * scale, 0.0f, 0.0f);
glNewList(font->base_ + sym, GL_COMPILE);
glBegin(GL_QUADS);
glTexCoord2f(j*0.0625f + offA, 1.0f - i*0.0625f);
glVertex2f(0.0f, 0.0625f * scale);
glTexCoord2f(j*0.0625f + offA + offB, 1.0f - i*0.0625f);
glVertex2f(offB * scale, 0.0625f * scale);
glTexCoord2f(j*0.0625f + offA + offB, 1.0f - (i*0.0625f + 0.0625f));
glVertex2f(offB * scale, 0.0f);
glTexCoord2f(j*0.0625f + offA, 1.0f - (i*0.0625f + 0.0625f));
glVertex2f(0.0f, 0.0f);
glEnd();
glTranslatef((offB + offC) * scale, 0.0f, 0.0f);
glEndList();
}
}
// Clean up all allocated data
DeleteObject(hBitmap);
DeleteObject(hdcBitmap);
ReleaseDC(NULL, hdcWindow);
DeleteObject(hFont);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment