Using Getglyphoutline to render fonts in OpenGL under Windows

Source: Internet
Author: User

Welcome reprint, please indicate the source: http://blog.csdn.net/tianyu2202/

No figure no JB, first. Use OpenGL to draw fonts, support a variety of fonts, support TrueType outline fonts, support the font texture size and output size of the AutoShape, and support drawing in three-dimensional space.

There are a lot of tutorials on the display of fonts in OpenGL, but there are more simple ways to bitmap and more complex freetype ways. The way this article is introduced can only be implemented under Windows, but it has the same display effect as FreeType, the most important is very simple, just more than 200 lines of code can be achieved.

The first is the preservation of font information, each text has a number of information to be saved, including the texture of the width of the height, start position, font width and the number of the texture. This article saves dozens of words for each font as a texture, rather than a common texture. This is the first for the sake of simplicity, and secondly there are some peculiarities of application. Students with this requirement can optimize themselves.

Class Cfontdata{public:float M_width, M_height;float M_ORIGX, M_origy;float m_fontwidth; Gluint M_textureid; Cfontdata () {m_width = 0.0f;m_height = 0.0f;m_textureid = 0;m_fontwidth = 0.0F;M_ORIGX = 0.0f;m_origy = 0.0f;} ~cfontdata () {}};

Then is the text to draw the class, very simple, saved the font name, the font size and some resources, the method altogether two is in the three-dimensional space to draw and produces the texture font.

Class Cfontprinter{private:int m_fontsize;wchar_t m_fontname[64];std::map<wchar_t, CFontData*> m_FontMap; Hfont m_font;public:cfontprinter (int fontSize, const wchar_t* fontname) {wcscpy_s (m_fontname, +, fontname); m_fontsize = Fontsize;m_font = NULL;} ~cfontprinter () {}bool Makechar (wchar_t wchar); void Print3dtext (float x, float y, float z, float red, float green, float bl UE, float height, wchar_t* text), void Print3dtext (float x, float y, float z, float height, wchar_t* text) {return print3dte XT (x, Y, Z, 1.0f, 1.0f, 1.0f, height, Text);}};

In Makechar, textures are generated based on the characters passed in and stored in M_fontmap, which is drawn in Print3dtext. Direct use of Print3dtext can also automatically call Makechar for text data generation. First check if M_font has been generated, and no build is generated based on font information. It then uses the passed-in character to get the size of the buffer, and then builds the buffer and passes it into the function getglyphoutlintw to get the resulting font data. The data generated here is Gray64, and each byte represents a pixel and is 4-byte aligned. In order to save more video card resources here, I will pixelstore the pair of alignment to 1 bytes. Use a swapbuffer to align the data to 1 bytes and pass in the teximage2d.

The required data is then calculated and stored in the Fontmap waiting to be drawn.

BOOL Cfontprinter::makechar (wchar_t WCHAR) {HDC hdc = CreateCompatibleDC (WGLGETCURRENTDC ()); if (!HDC) return false; Hbitmap hbitmap = CreateCompatibleBitmap (hdc, 1, 1); Hbitmap hbitmapold = (hbitmap) SelectObject (hdc, HBITMAP); if (DWORD) Hbitmapold = = Gdi_error) return false; cfontdata* fontdata = new Cfontdata () glgentextures (1, &fontdata->m_textureid); Glbindtexture (GL_TEXTURE_2D, Fontdata->m_textureid); Gltexparameteri (gl_texture_2d, Gl_texture_min_filter, gl_linear); GlTexParameteri (GL_ texture_2d, Gl_texture_mag_filter, gl_linear); Gltexenvi (gl_texture_env, Gl_texture_env_mode, GL_MODULATE); Glpixelstorei (Gl_unpack_swap_bytes, Gl_false); Glpixelstorei (Gl_unpack_lsb_first, Gl_false); GlPixelStorei (GL_ Unpack_row_length, 0); Glpixelstorei (gl_unpack_skip_rows, 0); Glpixelstorei (gl_unpack_skip_pixels, 0); GlPixelStorei (gl_unpack_alignment, 1); int itexwidth = M_fontsize;int Itexheight = M_fontsize;int ilevel = 0;if (!m_Font) {//Create text M_Font = CREATEFONTW (-m_fontsize, 0, 0, 0, $, false, False, FALSe,default_charset, Out_tt_only_precis, clip_default_precis,default_quality, Default_pitch | (M_fontname?) Ff_dontcare:ff_swiss), m_fontname);} if (!m_font) return false; Hfont hfontold = (hfont) SelectObject (hdc, M_font); if (DWORD) Hfontold = = Gdi_error) return false; Glyphmetrics gm={0,}; MAT2 const matrix22_identity={{0,1},{0,0},{0,0},{0,1}};D Word dwbuffsize = getglyphoutlinew (hdc, WChar, ggo_gray8_ BITMAP, &AMP;GM, 0, NULL, &matrix22_identity); if (signed) dwbuffsize = = 1) {return false;} if (Getglyphoutlinew (hdc, WChar, Ggo_metrics, &AMP;GM, 0, NULL, &matrix22_identity) ==gdi_error) {return false;} BYTE *pbuff = new Byte[dwbuffsize]; BYTE *pswapbuff=new Byte[dwbuffsize];memset (Pbuff, 0xFF, dwbuffsize); memset (Pswapbuff, 0xFF, dwbuffsize); if ( Getglyphoutlinew (hdc, WChar, Ggo_gray8_bitmap, &AMP;GM, dwBuffSize, Pbuff, &matrix22_identity) = = GDI_ERROR) { Delete[] Pbuff;return false;} if (Gm.gmblackboxy = = 0) {printf ("black box Y Zero!!! \ n "); return false;} Convert from Gray64 to gray256unsigned int const UiroWsize = Dwbuffsize/gm.gmblackboxy; Byte* pptr; byte* psptr;for (unsigned int nY = 0; NY < gm.gmblackboxy; ny++) {pptr = Pbuff + uirowsize * ny;psptr = Pswapbuff + gm.gm Blackboxx * NY;FOR (unsigned int nX = 0; nx < Gm.gmblackboxx; nx++) {if (*pptr = = 0) {*psptr = 0;} else if (*pptr = = 0x40) {*psptr = 0xFF;} Else{*psptr = *pptr << 2;} pptr++;p sptr++;}} Loading Textures glteximage2d (gl_texture_2d, ilevel, Gl_luminance8, Gm.gmblackboxx, Gm.gmblackboxy, 0, Gl_luminance, GL_UNSIGNED _byte, Pswapbuff);//Record text message Fontdata->m_fontwidth = (float) gm.gmcellincx/(float) M_fontsize;fontdata->m_width = (float) Gm.gmblackboxx/(float) M_fontsize;fontdata->m_height = (float) gm.gmblackboxy/(float) m_fontsize; FONTDATA-&GT;M_ORIGX = (float) gm.gmptglyphorigin.x/(float) M_fontsize;fontdata->m_origy = 1.0f-(float) GM.GMPTGLYPHORIGIN.Y/(float) M_fontsize;m_fontmap[wchar] = fontdata;delete[] pbuff;delete[] PSwapBuff;return true;}

Create an OpenGL window in the main function, and initialize the text, and call Print3dtext in the render loop to draw.

void Render () {static float Frameid = 0;if (Frameid > 2 * PI) {Frameid = 0.0f;} Else{frameid + = pi/180.0f;} Gldrawbuffer (Gl_back); Glviewport (0, 0, m_width, m_height) Glclearcolor (0.3f, 0.4f, 0.5f, 1.0f); Glclear (gl_depth_ Buffer_bit | Gl_color_buffer_bit); Glmatrixmode (gl_projection); glloadidentity (); Glmatrixmode (Gl_modelview); glLoadIdentity (); for (int i = 0; i < i++) {Fontprinter->print3dtext (sin (frameid-pi180 * i) * 0.3f-0.7f, cos (frameid-pi180 *  i), 0.0f, 1.0f, 1.0f, 1.0f, 0.3f, L "Chinese output"); Fontprinter->print3dtext (cos (frameid-pi180 * i) * 0.4f-0.8f, sin (frameid -PI180 * i) * 0.4f, 0.0f, 0.0f, 1.0f, 0.0f, 0.2f, L "Hello Class"); Fontprintersong->print3dtext (cos (frameid-pi180 * i) * 0.5f-0.9f, sin (frameid-pi180 * i) * 0.6f, 0.0f, 0.0f, 0.0f, 1.0f, 0.4f, L "Font Class");} Fontprinter->print3dtext ( -0.7f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.2f, L "Font World"); Fontprintersong->print3dtext ( -0.7f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.2f, L "italicized word"); Fontprinter->print3dText ( -0.7f, -0.2f, 0.0f, 1.0f, 0.0f, 0.0f, 0.2f, L "Microsoft Jas Black"); Glflush (); Swapbuffers (M_HDC);} Initialize text void Initfont () {//parameter 1 maximum size of single text texture//Parameter 2 font file name Fontprinter = new Cfontprinter ("Microsoft Jas Black"); Fontprintersong = new Cfontprinter (L "Arial");} int __stdcall WinMain (__in hinstance hinstance, __in_opt hinstance hprevinstance, __in_opt LPSTR lpcmdline, __in int NSho WCMD) {msg msg; Createclientwindow (); Initfont (); while (true) {if (PeekMessage (&msg, NULL, 0, 0, pm_remove))//Is there a message waiting? { if (msg.message = = wm_quit)//Receive an exit message? {//exit program break;}                                  Else{translatemessage (&AMP;MSG);                                   Translation Message DispatchMessage (&AMP;MSG); Send Message}}else{render ();}} if (fontprinter! = NULL) {delete fontprinter;} return 0;}

Engineering code in http://download.csdn.net/detail/tianyu2202/7797885, Welcome to download.



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.