OpenGL文字显示困扰
根据 NeHe 教程显示文字的 13 课,使用函数 wglUseFontBitmaps 显示二维的文字
文字是能显示,但奇怪的是文字显示出来后就一直在窗口移动/漂移,我没做任何坐标偏移,运行程序,很快偏移到一定位置后,
停在那不动,然后每当鼠标单击一下窗口,就开始飘移一段距离,单击一下,就开始漂移,就这么简单的几段代码,怎么可能会
这样呢,估计是响应了 Paint 消息,然后重画,但重画也不至于漂移啊,为什么会位置变化,我没动。
另外:我使用的是 Windows 下 WTL 作为框架的,不是基于 Win32 的,在 OnPaint 里渲染场景的,找了好几天这个问题的原
因,就是找不到原因。
主要代码如下:
#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;}
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