首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络游戏 >

OpenGL文字显示困扰解决方案

2012-04-03 
OpenGL文字显示困扰根据 NeHe 教程显示文字的 13 课,使用函数 wglUseFontBitmaps 显示二维的文字文字是能

OpenGL文字显示困扰
根据 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 BaseGLYPHMETRICSFLOAT m_glYPHMetric[256];            // Storage For Information About Our Outline Font CharactersLRESULT 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;} 





[解决办法]
这些3d程序的框架不能改吧,不是普通程序
[解决办法]
在wtl的消息循环里Render,貌似
C/C++ code
MSG msg;    while(1)                                            // Do our infinate loop    {                                                    // Check if there was a message        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))         {             if(msg.message == WM_QUIT)                    // If the message wasnt to quit                break;            TranslateMessage(&msg);                        // Find out what the message does            DispatchMessage(&msg);                        // Execute the message        }        else                                            // if there wasn't a message        {             // Render the scene every frame to update the rotating cube            RenderScene();                                        }     }
[解决办法]
可以看一下nehe的代码,全是这样搞的,一般Win32的程序也是这样做的,CPU 占用率不会高。如果想限制一下帧率,可以控制Render的调用次数即可
[解决办法]
用glWindowPos2i ,不要用 glTranslatef

热点排行