Sign in to follow this  

Another wglUseFontBitmaps problem

This topic is 4856 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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[i].peRed = (BYTE)(
(((i >> pfd.cRedShift) & redMask) * 255) / redMask);
pPal->palPalEntry[i].peGreen = (BYTE)(
(((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask);
pPal->palPalEntry[i].peBlue = (BYTE)(
(((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask);
pPal->palPalEntry[i].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();
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

This topic is 4856 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this