+ -
当前位置:首页 → 问答吧 → OpenGL文字显示困扰

OpenGL文字显示困扰

时间:2011-12-02

来源:互联网

根据 NeHe 教程显示文字的 13 课,使用函数 wglUseFontBitmaps 显示二维的文字

文字是能显示,但奇怪的是文字显示出来后就一直在窗口移动/漂移,我没做任何坐标偏移,运行程序,很快偏移到一定位置后,

停在那不动,然后每当鼠标单击一下窗口,就开始飘移一段距离,单击一下,就开始漂移,就这么简单的几段代码,怎么可能会

这样呢,估计是响应了 Paint 消息,然后重画,但重画也不至于漂移啊,为什么会位置变化,我没动。

另外:我使用的是 Windows 下 WTL 作为框架的,不是基于 Win32 的,在 OnPaint 里渲染场景的,找了好几天这个问题的原

因,就是找不到原因。

主要代码如下:

C/C++ code

#include "StdAfx.h"
#include "XXX.h"

HDC m_hDC;
GLuint m_uFontBase;                                // Storage for Font List Base
GLYPHMETRICSFLOAT m_glYPHMetric[256];            // Storage For Information About Our Outline Font Characters

LRESULT XXX::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
    CPaintDC dc(m_hWnd);

    RenderGLScene();
    dc.SwapBuffers();

    return 0;
}

LRESULT CMy3DVideoUIDemoView::OnEraseBkgnd(HDC hdc)
{
    return TRUE; // background is erased
}

GLvoid BuildFont(GLvoid)    // Build Our Font
{
    HFONT hFont, hOldFont;

    m_uFontBase = glGenLists(256);    // Storage For 256 Characters

    hFont = CreateFont(-12,                            // Height Of Font
        0,                            // Width Of Font
        0,                            // Angle Of Escapement
        0,                            // Orientation Angle
        FW_LIGHT,                        // Font Weight
        FALSE,                        // Italic
        FALSE,                        // Underline
        FALSE,                        // Strikeout
        ANSI_CHARSET,                // Character Set Identifier
        OUT_TT_PRECIS,                // Output Precision
        CLIP_DEFAULT_PRECIS,            // Clipping Precision
        ANTIALIASED_QUALITY,            // Output Quality
        FF_DONTCARE|DEFAULT_PITCH,    // Family And Pitch
        _T("Comic Sans MS"));        // Font Name

    hOldFont = (HFONT)SelectObject(m_hDC, hFont);
    /*    wglUseFontOutlines(m_hDC, 0, 255, m_uFontBase, 0.0f, 0.2f, WGL_FONT_POLYGONS, m_glYPHMetric);*/
    wglUseFontBitmaps(m_hDC, 0, 256, m_uFontBase);
    SelectObject(m_hDC, hOldFont);
    DeleteObject(hFont);
}

GLvoid glPrint(const char *format, ...)    // Custom GL "Print" Routine
{
    glDisable(GL_DEPTH_TEST);

    glPushMatrix();

    glTranslatef(-7.5f, 0.0f, 0.0f);
    glScalef(0.5f, 0.5f, 0.5f);
    /*    glTranslatef(0.0f, 0.0f, -15.0f);*/

    glColor3f(1.0f, 0.0f, 1.0f);

    char chText[256];
    va_list    ap;

    if (format == NULL)
        return;

    va_start(ap, format);
    vsprintf_s(chText, format, ap);
    va_end(ap);

    float fLength = 0.0f;
    for (UINT n = 0; n < strlen(chText); n++)                // Loop To Find Text Length
        fLength += m_glYPHMetric[chText[n]].gmfCellIncX;    // Increase Length By Each Characters Width
    glTranslatef(-fLength / 2, 0.0f, 0.0f);                    // Center Our Text On The Screen

    glPushAttrib(GL_LIST_BIT);                                // Pushes The Display List Bits
    glListBase(m_uFontBase);                                // Sets The Base Character to 0
    glCallLists(strlen(chText), GL_UNSIGNED_BYTE, chText);    // Draws The Display List Text
    glPopAttrib();                                            // Pops The Display List Bits

    glPopMatrix();

    glEnable(GL_DEPTH_TEST);
}

LRESULT XXX::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    // The PIXELFORMATDESCRIPTOR structure describes the pixel format of a drawing surface
    PIXELFORMATDESCRIPTOR pfd;
    memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
    pfd.nSize      = sizeof(PIXELFORMATDESCRIPTOR);
    pfd.nVersion   = 1;
    pfd.dwFlags    = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 32;
    pfd.iLayerType = PFD_MAIN_PLANE ;

    HDC hDC = GetDC();
    m_hDC = hDC;
    int nPixelFormat = ChoosePixelFormat(hDC, &pfd);
    ATLASSERT(nPixelFormat != 0);

    BOOL bRet = SetPixelFormat(hDC, nPixelFormat, &pfd);
    ATLASSERT(bRet);

    m_hRC = wglCreateContext(hDC);        //Get A Rendering Context
    ATLASSERT(m_hRC);

    bRet = wglMakeCurrent(hDC, m_hRC);    // Try To Activate The Rendering Context
    ATLASSERT(bRet);

    ReSizeGLScene(lpCreateStruct->cx, lpCreateStruct->cy);
    InitGL();

    BuildFont();

    return 0;
}

LRESULT XXX::OnSize(UINT state, CSize Size)
{
    ReSizeGLScene(Size.cx, Size.cy);

    return 0;
}

LRESULT XXX::OnDestroy(void)
{
    if (m_hRC)
    {
        wglMakeCurrent(NULL, NULL);
        wglDeleteContext(m_hRC);
        m_hRC = NULL;
    }

    return 0;
}

BOOL CMy3DVideoUIDemoView::InitGL(GLvoid)
{
    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    return TRUE;
}

GLvoid XXX::ReSizeGLScene(GLsizei nWidth, GLsizei nHeight)    // Resize And Initialize The GL Window
{
    glViewport(0, 0, nWidth, nHeight);    // Reset The Current Viewport

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // Calculate The Aspect Ratio Of The Window
    if (nWidth < nHeight)
        gluPerspective(45.0f, (GLfloat)nHeight / (GLfloat)nWidth, 0.1f, 100.0f);
    else
        gluPerspective(45.0f, (GLfloat)nWidth / (GLfloat)nHeight, 0.1f, 100.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

BOOL XXX::RenderGLScene(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glPrint("Hello World");

    return TRUE;
}



作者: exceed_me   发布时间: 2011-12-02

主要是下面这两个函数,拷贝到 NeHe 代码的框架中,没问题,但我用 WTL,在 OnPaint 里 Render 就出问题,到底是为何?

C/C++ code

GLvoid BuildFont(GLvoid)    // Build Our Font
{
    HFONT hFont, hOldFont;

    m_uFontBase = glGenLists(256);    // Storage For 256 Characters

    hFont = CreateFont(-12,                            // Height Of Font
        0,                            // Width Of Font
        0,                            // Angle Of Escapement
        0,                            // Orientation Angle
        FW_LIGHT,                        // Font Weight
        FALSE,                        // Italic
        FALSE,                        // Underline
        FALSE,                        // Strikeout
        ANSI_CHARSET,                // Character Set Identifier
        OUT_TT_PRECIS,                // Output Precision
        CLIP_DEFAULT_PRECIS,            // Clipping Precision
        ANTIALIASED_QUALITY,            // Output Quality
        FF_DONTCARE|DEFAULT_PITCH,    // Family And Pitch
        _T("Comic Sans MS"));        // Font Name

    hOldFont = (HFONT)SelectObject(m_hDC, hFont);
    /*    wglUseFontOutlines(m_hDC, 0, 255, m_uFontBase, 0.0f, 0.2f, WGL_FONT_POLYGONS, m_glYPHMetric);*/
    wglUseFontBitmaps(m_hDC, 0, 256, m_uFontBase);
    SelectObject(m_hDC, hOldFont);
    DeleteObject(hFont);
}

GLvoid glPrint(const char *format, ...)    // Custom GL "Print" Routine
{
    glDisable(GL_DEPTH_TEST);

    glPushMatrix();

    glTranslatef(-7.5f, 0.0f, 0.0f);
    glScalef(0.5f, 0.5f, 0.5f);
    /*    glTranslatef(0.0f, 0.0f, -15.0f);*/

    glColor3f(1.0f, 0.0f, 1.0f);

    char chText[256];
    va_list    ap;

    if (format == NULL)
        return;

    va_start(ap, format);
    vsprintf_s(chText, format, ap);
    va_end(ap);

    float fLength = 0.0f;
    for (UINT n = 0; n < strlen(chText); n++)                // Loop To Find Text Length
        fLength += m_glYPHMetric[chText[n]].gmfCellIncX;    // Increase Length By Each Characters Width
    glTranslatef(-fLength / 2, 0.0f, 0.0f);                    // Center Our Text On The Screen

    glPushAttrib(GL_LIST_BIT);                                // Pushes The Display List Bits
    glListBase(m_uFontBase);                                // Sets The Base Character to 0
    glCallLists(strlen(chText), GL_UNSIGNED_BYTE, chText);    // Draws The Display List Text
    glPopAttrib();                                            // Pops The Display List Bits

    glPopMatrix();

    glEnable(GL_DEPTH_TEST);
}

作者: exceed_me   发布时间: 2011-12-02

如果使用 wglUseFontOutlines 函数,那么不会有问题,但字体大小就调节不了,晕,除非使用 glScalef/glTranslatef 来使得缩小,但效果比较差,我也不需要 3D 的问题,就是要 2D 的。

作者: exceed_me   发布时间: 2011-12-02

热门下载

更多