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 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_listap;
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();
}
}