VC中OpenGL汉字显示解决方案 /// Head file // MiscGL.h: interface for the CMiscGL class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_MISCGL_H__F7358B14_F8AC_11D3_B5AC_0080C87978F2__INCLUDED_) #define AFX_MISCGL_H__F7358B14_F8AC_11D3_B5AC_0080C87978F2__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 //////////////////////////////////////////////////////////////////////// ///// // // OpenGL Misc function class // // Copyright (C) 2000 Risker. All rights are reserved. // // Description: // 1. Chinese character output. // 2. Texture managment. (略) // //////////////////////////////////////////////////////////////////////// ///// class CMiscGL { // Implementation public: CMiscGL(); virtual ~CMiscGL(); static void ShowStringOutline(CString strText, HFONT = NULL); static int ShowStringBitmap(LPCTSTR string, HFONT hFont = NULL, BOOL bUs eDisplayList = FALSE); static int GetTextBitmapBox( SIZE & sizeText, LPCTSTR string, HFONT hFon t); }; #endif // !defined(AFX_MISCGL_H__F7358B14_F8AC_11D3_B5AC_0080C87978F2__INCLUDED   ///////////////////////////// // CCP Files // MiscGL.cpp: implementation of the CMiscGL class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MiscGL.h" #include "gl/gl.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif CMiscGL::CMiscGL() { } CMiscGL::~CMiscGL() { } void CMiscGL::ShowStringOutline(CString strText, HFONT hFont /* = NULL */) { HDC hdc = wglGetCurrentDC(); ASSERT(hdc != NULL); if (hFont == NULL) { hFont = (HFONT)::GetStockObject(SYSTEM_FONT); } ASSERT(hFont != NULL); HFONT hOldFont = (HFONT)::SelectObject(hdc, hFont); UCHAR * pChar= (UCHAR*)strText.GetBuffer(strText.GetLength()); int nListNum; DWORD dwChar; glPushMatrix(); for(int i = 0; i < strText.GetLength(); i++) { if(IsDBCSLeadByte((BYTE)pChar[i])) { dwChar = (WORD)((pChar[i] << 8) | pChar[i+1]); i++; } else dwChar = pChar[i]; nListNum = glGenLists(1); GLYPHMETRICSFLOAT pgmf[1]; wglUseFontOutlines(hdc, dwChar, 1, nListNum, 0.0f, 0.1f, WGL_FON T_POLYGONS, pgmf); glCallList(nListNum); glDeleteLists(nListNum, 1); } glPopMatrix(); strText.ReleaseBuffer(); ::SelectObject(hdc,hOldFont); } int CMiscGL::ShowStringBitmap(LPCTSTR lpszText, HFONT hFont /* = NULL */ , BOOL bUseDisplayList /*= FALSE */) { CBitmap bitmap; BITMAP bm; SIZE size; UCHAR* pBmpBits; HFONT hOldFont; HDC hdc = wglGetCurrentDC(); if(!hFont) // use default system font { hFont = (HFONT)::GetStockObject(SYSTEM_FONT); } hOldFont = (HFONT)SelectObject(hdc, hFont); ::GetTextExtentPoint32(hdc, lpszText, strlen(lpszText), &size); bitmap.CreateBitmap(size.cx, size.cy, 1, 1, NULL); HDC hMemDC = ::CreateCompatibleDC(hdc); if(hMemDC) { HBITMAP hPrevBmp = (HBITMAP)SelectObject(hMemDC, bitmap); HFONT hPrevFont = (HFONT)SelectObject(hMemDC, hFont); SetBkColor(hMemDC, RGB(0, 0, 0)); SetTextColor(hMemDC, RGB(255, 255, 255)); SetBkMode(hMemDC, OPAQUE); TextOut(hMemDC, 0, 0, lpszText, strlen(lpszText)); // copy GDI bitmap to DIB bitmap.GetBitmap(&bm); size.cx = (bm.bmWidth + 31) & (~31); size.cy = bm.bmHeight; int bufsize = size.cy * (((bm.bmWidth + 31) & (~31)) / 8); pBmpBits = new UCHAR[bufsize]; memset(pBmpBits, 0, sizeof(UCHAR)*bufsize); struct { BITMAPINFOHEADER bih; RGBQUAD col[2]; }bic; BITMAPINFO *binf = (BITMAPINFO *)&bic; binf->bmiHeader.biSize = sizeof(binf->bmiHeader); binf->bmiHeader.biWidth = bm.bmWidth; binf->bmiHeader.biHeight = bm.bmHeight; binf->bmiHeader.biPlanes = 1; binf->bmiHeader.biBitCount = 1; binf->bmiHeader.biCompression = BI_RGB; binf->bmiHeader.biSizeImage = bufsize; binf->bmiHeader.biXPelsPerMeter = 1; binf->bmiHeader.biYPelsPerMeter = 1; binf->bmiHeader.biClrUsed = 0; binf->bmiHeader.biClrImportant = 0; ::GetDIBits(hdc, bitmap, 0, bm.bmHeight, pBmpBits, binf, DIB_RGB _COLORS); SelectObject(hMemDC, hPrevBmp); } ::DeleteDC(hMemDC); // delete font from DC SelectObject(hdc, hOldFont); // display text glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GLuint displist = 0; if(bUseDisplayList) { displist = glGenLists(1); glNewList(displist, GL_COMPILE); glBitmap(size.cx, size.cy, 0.0, 2.0, size.cx+2. 0f, 0.0,p BmpBits); glEndList(); } else; glBitmap(size.cx, size.cy, 0.0, 2.0, size.cx+2.0f, 0.0, pBmpBits ); delete pBmpBits; return displist; } int CMiscGL::GetTextBitmapBox(SIZE& sizeText, LPCTSTR string, HFONT hFont) { ASSERT(hFont != NULL); SIZE size; HFONT hOldFont; HDC hdc = wglGetCurrentDC(); hOldFont = (HFONT)SelectObject(hdc, hFont); ::GetTextExtentPoint32(hdc, string, strlen(string), &size); SelectObject(hdc, hOldFont); sizeText.cx = (size.cx + 31) & (~31); sizeText.cy = size.cy; return 0; }