Another wglUseFontBitmaps problem

Started by
7 comments, last by Darkor 19 years, 7 months ago

HDC hdc = mWindow->getHDC();
HGLRC hglrc = mWindow->getHGLRC();
wglMakeCurrent(hdc, hglrc);

oldFont = (HFONT) SelectObject(hdc, newFont);
BOOL success = wglUseFontBitmaps(hdc, 32, 96, base);

This doesn't work, the call to wglUseFontBitmaps fail.

HDC hdc = mWindow->getHDC();
HGLRC hglrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hglrc);

oldFont = (HFONT) SelectObject(hdc, newFont);
BOOL success = wglUseFontBitmaps(hdc, 32, 96, base);

This works and text displays, however, this affects other renderables. But the funny thing is that only renderables that are rendered in orthogonal projection works. Why does wglUseFontBitmaps require a call to wglCreateContext when I already have a context? Does the context expire or something?
Advertisement
Hey guys, I need to draw some text. Help would be greatly appreciated!

The thing is, when the function call sfails I use GetLastError() but it says that the operation completes successfully... what gives?
I've already searched on the forums... while lots of others have sufferend similar problems using wglUseFontBitmaps(), none of the solutions I've tried has worked.

I guess I should state things cleanly. wglUseFontBitmaps() returns FALSE but when I use GetLastError() it tells me that the operation completed successfully.

I got it to work by using (and it returns TRUE):

HGLRC hglrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hglrc);

And this allows fonts to be displayed, which works perfectly if not for the fact that I can't draw anything else that is in non orthonal mode.

Please help.
You're definately doing something wrong somewhere else in the code.It doesn't make any sense to me.(especially that thing you say that it renders only in ortho mode,that's crazy).

Well,for now,just don't use the window dc for the font.You don't necessary need a DC that supports OpenGL for wglUseFontBitmaps.Create a new dc using CreateCompatibleDC(),select the font,call wglUseFontBitmaps and then destroy the dc.
Are you sure you're not calling that function before your OpenGL context has been created? That's the only reason I can think of that accounts for the function succeeding if you call wglCreateContext().

As for GetLastError() returning nothing useful, if you had any function calls between the failed function and and the GetLastError() call, the failure information would probably be wiped. Be sure you make the GetLastError() call immediately after the wgl* call.
Thanks for the replies, I was starting to think that no one would help me =x

Dave Hunt: I am certain that I've called wglCreateContext() prior to setting up the font. Plus I don't have any function calls in between both functions. This is rather perplexing.

mikeman: I'm trying that now, but it still doesn't work. Sometimes I get an error saying that it's the wrong pixel format. And I read somewhere that it won't work with double buffered pixel formats. Erm what is this and how do I disable it?
Actually,I don't think wglUseFontBitmaps has any problem with double buffers.I've used it with window dc's that support OpenGL and double-buffer and it works fine.If you're reffering to this:

Quote:
MSDN:
In the current version of Microsoft's implementation of OpenGL in Windows NT and Windows 95, you cannot make GDI calls to a device context that has a double-buffered pixel format. Therefore, you cannot use the GDI fonts and text functions with such device contexts. You can use the wglUseFontBitmaps function to circumvent this limitation and draw text in a double-buffered device context.


That says that you can't draw text using GDI in a double-buffered pixel format,and that's the reason you need wglUseFontBitmaps.Anyway,I can't figure out what causes your problem.Try this code:

   HDC hdc=CreateCompatibleDC(0);   LOGFONT     lf;   HFONT       newfont, oldfont;   GLYPHMETRICSFLOAT agmf[256];   // Let's create a TrueType font to display.   memset(&lf,0,sizeof(LOGFONT));   lf.lfHeight               =   -20 ;   lf.lfWeight               =   FW_NORMAL ;   lf.lfCharSet              =   ANSI_CHARSET ;   lf.lfOutPrecision         =   OUT_DEFAULT_PRECIS ;   lf.lfClipPrecision        =   CLIP_DEFAULT_PRECIS ;   lf.lfQuality              =   DEFAULT_QUALITY ;   lf.lfPitchAndFamily       =   FF_DONTCARE|DEFAULT_PITCH;   lstrcpy (lf.lfFaceName, "Tahoma") ;newfont = CreateFontIndirect(&lf);oldfont = (HFONT) SelectObject(hdc,newfont);BOOL success = wglUseFontBitmaps(hdc, 32, 96, base);cout<<"SUCCESS :"<<success<<endl;DeleteObject(SelectObject(hdc,oldfont));DeleteDC(hdc);


This works fine on my system.If that doesn't work on yours,I don't know.
mikeman: It still doesn't work. But I appreciate the help you've given me so far. I'll post some codes on how I set up OpenGL and see if you guys could spot any problems. =p

void Win32Window::setupPixelFormat(){	PIXELFORMATDESCRIPTOR pfd =	{			sizeof(PIXELFORMATDESCRIPTOR),		// size		1,									// version		PFD_SUPPORT_OPENGL |		PFD_DRAW_TO_WINDOW |		PFD_DOUBLEBUFFER,					// support float-buffering		PFD_TYPE_RGBA,						// color type		mBits,									// prefered color depth		0, 0, 0, 0, 0, 0,					// color bits (ignored)		0,									// no alpha buffer		0,									// alpha bits (ignored)		0,									// no accumulation buffer		0, 0, 0, 0,							// accum bits (ignored)		16,									// depth buffer		0,									// no stencil buffer		0,									// no auxiliary buffers		PFD_MAIN_PLANE,						// main layer		0,									// reserved		0, 0, 0,							// no layer, visible, damage masks	};	SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd);}


void Win32Window::setupPalette(){	int pixelFormat = GetPixelFormat(hDC);	PIXELFORMATDESCRIPTOR pfd;	LOGPALETTE* pPal;	int paletteSize;	int redMask, greenMask, blueMask;	int i;	DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);	if (pfd.dwFlags & PFD_NEED_PALETTE)		paletteSize = 1 << pfd.cColorBits;	else		return;	pPal = (LOGPALETTE*)LocalAlloc(LPTR, sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));	pPal->palVersion = 0x300;	pPal->palNumEntries = (short)paletteSize;	//	build a simple RGB color palette	redMask   = (1 << pfd.cRedBits)   - 1;	greenMask = (1 << pfd.cGreenBits) - 1;	blueMask  = (1 << pfd.cBlueBits)  - 1;	for (i=0; i<paletteSize; ++i)	{	pPal->palPalEntry.peRed = (BYTE)(			(((i >> pfd.cRedShift) & redMask) * 255) / redMask);		pPal->palPalEntry.peGreen = (BYTE)(			(((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask);		pPal->palPalEntry.peBlue = (BYTE)(			(((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask);		pPal->palPalEntry.peFlags = 0;	}	hPalette = CreatePalette(pPal);	LocalFree(pPal);	if (hPalette)	{		DeleteObject(SelectPalette(hDC, hPalette, FALSE));		RealizePalette(hDC);	}


void Win32Window::create(){	hDC = GetDC(hWnd);	setupPixelFormat();	setupPalette();	hGLRC = wglCreateContext(hDC);	wglMakeCurrent(hDC, hGLRC);	if (hGLRC == 0)	{		throwEx(Exception::INTERNAL_ERROR, "Error creating OpenGL window", "Win32Window::create");	}}


void RenderSystem::initialise(){	mFaceCount = mVertexCount = 0;	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);	glClearDepth(1.0f);	glEnable(GL_DEPTH_TEST);	glDepthFunc(GL_LEQUAL);	glEnable(GL_CULL_FACE);	glFrontFace(GL_CCW);	//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);	//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	glEnable(GL_SMOOTH);	glEnable(GL_COLOR_MATERIAL);	glShadeModel(GL_SMOOTH);	ImageCodec::loadImageCodecs();	Material* mat = (Material*) MaterialManager::getInstance().create("white");	mat->setShininess(16.0f);	mat->setAmbient(0.5f, 0.5f, 0.5f);	mat->setSpecular(1.0f, 1.0f, 1.0f);	mat->setDiffuse(0.5f, 0.5f, 0.5f);	loadExtensions();}
Yes! I got it working. For the benefit of those who might encounter the same problem (however slight that chance), I'll post what went wrong.

I kinda forgot that my RenderSystem isn't a MonoState and happily declared another one. Due to the degree of automation, it magically created a seperate window that never displayed but nonetheless existed.

So at the point where I was trying to use the existing HDC to create the font, it was using a new HDC that wasn't prepared with OpenGL, and thus the call to wglUseFontBitmaps() failed. This was fixed by creating a new context and making it current, but obviously wasn't the solution because now we have two windows, with the font being prepared on the wrong one.

This is once instance why some classes should simply be MonoStates or Singletons.

This topic is closed to new replies.

Advertisement