OpenGl下可以方便的操作字符,但是对字符串显示的支持不够.OpenGL本身不提供文字的显示和处理能力,如要显示文字的借助于第三方的扩展程序。初涉OpenGl, 想请教有什么好的方法可以解决这个问题?网上觅得bluebohe三年前的一篇文章, 在vs2005下实现他的代码, 编译通过了, 但是结果显示不出来. 可否帮忙看看? COpenGLText源码
bluebohe的原文:
      一直以来,OpenGL状态下的文字显示都是一个问题,本文使用嵌套显示列表的方式进行OpenGL状态下的字符串的显示。
     有以下几点需要注意:

     1:本程序显示按照给定的高度和文字的位置显示某一种字体的文字,其中一些字体的参数定义在OpenGLText内部给定,可以随意将它抽出来。如果将代码用于实际应用中,建议文字的文字间距自己设定,也可以随意添加文字的倾斜角、旋转角度、定位方式等等参数。

     2:wglUseFontOutlines函数的第五个参数表示文字的精度(弦偏差),一般设置成零,但这样缺省的做法会导致文字太粗糙,可以将它设置成一个比较小的数,以提高文字显示的精确度,但这样会增加内存的占用量。

     3:如果文字的高度比较小,文字的线条可能会出现断裂的现象,影响美观,解决这类问题有以下几种方式:(1)使用OpenGL反走样技术;(2)把文字的轮廓用线条勾勒出来;(3)在文字的Draw成员函数中多次调用glCallList函数,每次调用向周围平移一个像素,这样的话会使文字的线条断裂问题大为改观,速度也是三种方式中最快的。

应用方式如下:

         COpenGLText text;
         COpenGLText text2;

         text2.m_dX=0;
         text2.m_dY=200;

         glLoadIdentity(); 
         glClear(GL_COLOR_BUFFER_BIT); 
         glColor4f(0.0f, 0.0f, 1.0f, 1.0f);

         text.Draw("宋体");
         text2.Draw("楷体_GB2312");

         glFlush();

类的声明和实现如下:

  1#include <string>
  2#include <GL/glut.h>
  3
  4using namespace std;
  5
  6class COpenGLText  
  7{
  8public:
  9
 10    //构造文字
 11    COpenGLText();
 12    virtual ~COpenGLText();
 13
 14    //绘制制定字体的文字,字体只在第一次绘制时进行设置,之后可以传入空值
 15    void Draw(char *strFontName);
 16
 17    //释放文字所占空间
 18    void Free();
 19    //文字字符串
 20    string m_str;
 21    //字符串高度
 22    double m_dHeight;
 23    //字符串位置
 24    double m_dX;
 25    double m_dY;
 26
 27protected:
 28    BOOL GenList();
 29    BOOL GenCharsLists(char *strFontName);
 30    int m_iDisplayList;
 31}
;
 32
 33//////////////////////////////////////////////////////////////////////
 34
 35// COpenGLText Class
 36
 37//////////////////////////////////////////////////////////////////////
 38
 39//////////////////////////////////////////////////////////////////////

 40
 41// Construction/Destruction
 42
 43//////////////////////////////////////////////////////////////////////
 44
 45COpenGLText::COpenGLText()
 46{
 47    m_dX=0;
 48    m_dY=0;
 49    m_str="abc中国";
 50    m_dHeight=100;
 51    m_iDisplayList=0;
 52}

 53
 54COpenGLText::~COpenGLText()
 55{
 56    Free();
 57}

 58
 59BOOL COpenGLText::GenCharsLists(char *strFontName)
 60{
 61    HDC hdc;
 62    const char *str=m_str.c_str()
 63    hdc=CreateDC( "DISPLAY""""", NULL );
 64    int iNum=_mbslen((const unsigned char *)str);
 65
 66    m_iDisplayList=glGenLists(iNum+1);     
 67    HFONT hNewCFont;
 68    LOGFONT CLogFont; //存储当前字体参数
 69
 70    //初始化字体参数
 71
 72    memset( &CLogFont, 0sizeof(LOGFONT) );     
 73    CLogFont.lfEscapement = CLogFont.lfOrientation = 0;
 74    CLogFont.lfWeight = FW_NORMAL;
 75    CLogFont.lfCharSet =  GB2312_CHARSET;
 76    CLogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
 77    CLogFont.lfQuality=DEFAULT_QUALITY;
 78    CLogFont.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
 79    strcpy( CLogFont.lfFaceName, LPCTSTR(strFontName) );
 80    CLogFont.lfHeight=-10;
 81    CLogFont.lfWidth=0;     
 82
 83    hNewCFont=CreateFontIndirect(&CLogFont);
 84    HFONT hOldFont=(HFONT)SelectObject(hdc,hNewCFont);
 85
 86    int i=0,j=0,iTotal=strlen(str);;
 87    UINT nChar=0;
 88
 89    while(i<iTotal)
 90    {
 91        j++;
 92
 93        if(IsDBCSLeadByte(str[i]))
 94        {
 95            nChar=((unsigned char)str[i])*0x100+(unsigned char)str[i+1];
 96            i+=2;
 97        }

 98        else
 99        {
100            nChar=str[i];
101            i++;
102
103        }

104        GLYPHMETRICSFLOAT agmf[1];
105        BOOL bOK=wglUseFontOutlines(hdc,nChar,1,m_iDisplayList+j,0.002f,0,WGL_FONT_POLYGONS,agmf);
106
107    }

108
109    SelectObject(hdc,hOldFont);
110    DeleteObject(hNewCFont);
111    DeleteDC(hdc);
112
113    return TRUE;
114
115}

116
117BOOL COpenGLText::GenList()
118{
119    int iNum=_mbslen((const unsigned char *)m_str.c_str());
120    glNewList( m_iDisplayList, GL_COMPILE);
121
122    for(int i=1;i<=iNum;i++)
123    {
124
125        glPushMatrix();
126
127        //此处修改文字间距
128
129        glTranslated(m_dX+m_dHeight*(i-1),m_dY,0);
130
131        glScaled(m_dHeight,m_dHeight,1);
132
133        glCallList(m_iDisplayList+i);
134
135        glPopMatrix();
136
137    }

138    glEndList();
139
140    return TRUE;
141}

142
143void COpenGLText::Free()
144{
145    if(glIsList(m_iDisplayList))
146        glDeleteLists(m_iDisplayList,_mbslen((const unsigned char *)m_str.c_str())+1);
147    m_iDisplayList=0;
148}
 
149
150void COpenGLText::Draw(char *strFontName)
151{
152    if(!glIsList(m_iDisplayList))
153    {
154        GenCharsLists(strFontName);
155        GenList();
156    }

157    glCallList(m_iDisplayList);
158}

159
posted on 2007-04-12 15:26 哈哈 阅读(3735) 评论(2)  编辑 收藏 引用

评论:
# re: 请教:OpenGl中的文字显示 2007-05-25 22:20 | shpb
可以显示  回复  更多评论
  
# re: 请教:OpenGl中的文字显示 2007-05-26 21:17 | pengkuny
可以吗?怎么应用,在什么环境下应用
望shpb赐教  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理