现在的位置: 首页 > 综合 > 正文

一个极好的OpenGL汉字显示类

2013年08月26日 ⁄ 综合 ⁄ 共 5624字 ⁄ 字号 评论关闭

 一个极好的OpenGL汉字显示类
作者:Y___Y
联系:
yinwei_88@sina.com
    笔者通过各方面的资料的收集,终于写出了一个OpenGL汉字显示类(最核心的内容都是从网上和NeHe的教程上找到的,这个类实际上是从各位原创作者“集合”成的,笔者只能算一个收集整理者),很好的解决了2D,3D以及图象,图形汉字(当然也包括字母)的显示。现将其公布出来。

 

//GLFont.h文件
#include <windows.h>
#include 
"gl/gl.h"
#pragma warning(disable:4244)
//OpenGL汉字显示类
class GLfont
{
    HFONT hFont;
    COLORREF cl;
public:
    GLfont();
    
virtual ~GLfont();
    
void SetTextColor(COLORREF textcolor);//字体颜色设置
    void CreateFont(char *facename, int height, int weight, bool italic,bool underline,bool strikeout);
    
void ShowText(int x, int y, LPCTSTR lpszText);//显示图象2D汉字
    void Show2DText(char *str);//显示图形2D汉字
    void Show3DText(unsigned char *str);//显示图形3D汉字
}
;

GLfont::GLfont()
{
    cl
=RGB(255,255,255);
}

GLfont::
~GLfont()
{
    
if(hFont) DeleteObject(hFont);
}


//只有关闭光照和纹理才能正确显示颜色
void GLfont::SetTextColor(COLORREF textcolor)//字体颜色设置
{
    cl
=textcolor;
}

void GLfont::CreateFont(char *facename, int height, int weight, bool italic,bool underline,bool strikeout)
{
    LOGFONT lf;
    lf.lfHeight 
= height;
    lf.lfWidth 
= 0;
    lf.lfEscapement 
= 0;
    lf.lfOrientation 
= 0;
    lf.lfWeight 
= weight;
    lf.lfItalic 
= italic;
    lf.lfUnderline 
= underline;
    lf.lfStrikeOut 
= strikeout;
    lf.lfCharSet 
= DEFAULT_CHARSET;
    lf.lfOutPrecision 
= OUT_TT_PRECIS;
    lf.lfClipPrecision 
= CLIP_DEFAULT_PRECIS;
    lf.lfQuality 
= PROOF_QUALITY;
    lf.lfPitchAndFamily 
= VARIABLE_PITCH | TMPF_TRUETYPE | FF_MODERN;
    strcpy(lf.lfFaceName,facename);
    
// 创建字体
    hFont = CreateFontIndirect(&lf);
}


//2D图像汉字只与屏幕相联系,与具体的变换矩阵无关,也就是说不能缩放旋转。
//x,y是2D图像汉字距屏幕左下角(注意不是左上角)的横向和纵向距离。
void GLfont::ShowText(int x, int y, LPCTSTR lpszText)
{
    
// 保存原投影矩阵,将投影矩阵设为平行投影
    glMatrixMode( GL_PROJECTION );
    glPushMatrix();
    glLoadIdentity();
    glOrtho( 
06400480-11 );
    
// 保存原模型变换矩阵,平移至( x, y )
    glMatrixMode( GL_MODELVIEW );
    glPushMatrix();
    glLoadIdentity();
    RECT rect;
    GetClientRect(GetActiveWindow(),
&rect);
    glTranslatef((
float)x,(float)y,0);
    HBITMAP hbitmap;
    BITMAP bm;
    SIZE size;
    UCHAR
* pBmpBits;
    HFONT hOldFont;
    HDC hdc 
= wglGetCurrentDC();
    hOldFont 
= (HFONT)SelectObject(hdc, hFont);
    ::GetTextExtentPoint32(hdc, lpszText, strlen(lpszText), 
&size);
    hbitmap 
= CreateBitmap(size.cx, size.cy,11, NULL);
    HDC hMemDC 
= ::CreateCompatibleDC(hdc);
    
if(hMemDC)
    
{
        HBITMAP hPrevBmp 
= (HBITMAP)SelectObject(hMemDC,hbitmap);
        HFONT hPrevFont 
= (HFONT)SelectObject(hMemDC, hFont);
        SetBkColor(hMemDC, RGB(
000));
        ::SetTextColor(hMemDC,RGB(
255,255,255));
        SetBkMode(hMemDC, OPAQUE);
        TextOut(hMemDC, 
00, lpszText, strlen(lpszText));
        
//把GDI位图复制到DIB
        SelectObject(hdc,hbitmap);
        GetObject(hbitmap, 
sizeof(bm), &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, 
0sizeof(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, hbitmap, 
0, bm.bmHeight, pBmpBits, binf,DIB_RGB_COLORS);
        SelectObject(hMemDC,hPrevBmp);
    }

    ::DeleteDC(hMemDC);
        DeleteObject( hbitmap );
    SelectObject(hdc, hOldFont);

    
//显示文字
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glColor3f(GetRValue(cl)
/255.0,GetGValue(cl)/255.0,GetBValue(cl)/255.0);
    glRasterPos2i(x,y);
    glBitmap(size.cx, size.cy, 
0.02.0, size.cx+2.0f0.0, pBmpBits);
    delete []pBmpBits;//修改
    
// 恢复投影矩阵和模型变换矩阵
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    glColor3f(
1.0,1.0,1.0);
}


void GLfont::Show2DText(char *str)
{
    
char FTextList[255];
    GLYPHMETRICSFLOAT gmf[
256];
    
int m_iCount=strlen(str);    
    GLuint m_listbase;
    HDC hDC
=wglGetCurrentDC();
    glPushMatrix();
    
    SelectObject(hDC,hFont);
    
int  i=0
    
int  j=0
    
int ich,cch;
    m_listbase 
= glGenLists(256);
    glColor3f(GetRValue(cl)
/255.0,GetGValue(cl)/255.0,GetBValue(cl)/255.0);
    
while(i<m_iCount)
    
{
        
if(IsDBCSLeadByte(str[i]))
        

            
//判断是否为双字节 
            ich=str[i]; 
            ich
=(ich<<8)+256////256为汉字内码“偏移量” 
            ich=ich+str[i+1]; 
            i
++;i++
            wglUseFontOutlines(hDC,
//字体轮廓设备联系DC 
                ich, //要转换为显示列表的第一个字符 
                1//要转换为显示列表的字符数 
                m_listbase+j,//显示列表的基数 
                1.0f//指定与实际轮廓的最大偏移量 
                0,//0.15f, //在Z轴负方向的值 
                WGL_FONT_POLYGONS, //指定显示列表线段或多边形 
                &gmf[j]); //接受字符的地址 
            FTextList[j]=j; 
            j
++
            
        }

        
else
        

            cch
=str[i]; 
            i
++
            wglUseFontOutlines(hDC, 
//字体轮廓设备联系DC 
                cch,//要转换为显示列表的第一个字符 
                1,//要转换为显示列表的字符数 
                m_listbase+j,//显示列表的基数 
                0.0f,//指定与实际轮廓的最大偏移量 
                0.0,//0.15f,//在Z轴负方向的值 
                WGL_FONT_POLYGONS, //指定显示列表线段或多边形 
                &gmf[j]);//接受字符的地址 
            FTextList[j]=j;
            j
++;
        }

抱歉!评论已关闭.