Strange behaviour with wglUseFontBitmaps

  • Follow


Hi,

Hope this is on-topic here as it's about a wgl function rather than 
portable OpenGL code (if not, please can someone suggest a more 
appropriate newsgroup?)

I was trying to code up a quick text renderer this evening using 
wglUseFontBitmaps (as I've done a number of times in the past) and for 
once it decided to be temperamental. (This despite the fact that pretty 
much the exact same code worked fine elsewhere.) The code involved was this:

TextRenderer::TextRenderer(const std::string& typeface, int pointSize)
{
	m_base = glGenLists(128);

	HDC hdc = wglGetCurrentDC();
	std::wstring ws(typeface.begin(), typeface.end());
	m_pixelHeight = pointSize * GetDeviceCaps(hdc, LOGPIXELSY) / 72;

	HFONT font = CreateFont(-m_pixelHeight, 0, 0, 0, FW_NORMAL, false, 
false, false, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, 
ANTIALIASED_QUALITY, DEFAULT_PITCH|FF_DONTCARE, ws.c_str());

	HFONT oldFont = (HFONT)SelectObject(hdc, font);
	bool succeeded = wglUseFontBitmaps(hdc, 32, 96, m_base+32) != 0;
	SelectObject(hdc, oldFont);
	DeleteFont(font);
	if(!succeeded) throw Exception("<Whatever>");
#else
	#error TextRenderer - Platform not yet supported.
#endif
}

Here wglUseFontBitmaps was returning false, but GetLastError(), which is 
supposed to return additional error information, was returning 0 (i.e. 
no error) when I added it in to check what was going on. (I also found 
that the call succeeded if I constructed a TextRenderer object in 
certain parts of the code base, but not others - note that the project's 
single-threaded, so it's not a threading issue AFAICS. Also, replacing 
the OpenGL rendering context via HGLRC hrc = wglCreateContext(hdc); 
wglMakeCurrent(hdc, hrc); made the call succeed but - naturally - messed 
up everything else.) After some googling, I found that sometimes calling 
wglUseFontBitmaps multiple times works when it fails the first time, but 
no real explanation as to why that might be the case. Replacing the line 
above with the loop below works, but I'm at a loss to explain what's 
going on:

// Try and generate the font bitmaps - note that this sometimes has to
// be called multiple times to get it to work, which is seriously dodgy. 
// If we fail several times in a row, just give up.
bool succeeded = false;
const int MAX_TRIES = 5;
for(int i=0; i<MAX_TRIES && !succeeded; ++i)
{
	succeeded = wglUseFontBitmaps(hdc, 32, 96, m_base+32) != 0;
}

Any ideas as to what might be wrong please? Is it something I'm doing 
wrong (99% chance!) or is it more likely to be an issue with the driver 
implementation?

Cheers,
Stu

P.S. I know this whole approach to text rendering is sub-optimal (I 
intend to replace it at a later date) - I'm just genuinely curious as to 
what's going on at this point.
0
Reply Stuart 11/12/2009 11:25:09 PM

"Stuart Golodetz" <blah@blah.com> wrote in message 
news:G92dnUW8yv3JBGHXnZ2dnUVZ7t6dnZ2d@pipex.net...
> Hi,
>
> Hope this is on-topic here as it's about a wgl function rather than 
> portable OpenGL code (if not, please can someone suggest a more 
> appropriate newsgroup?)
>
> I was trying to code up a quick text renderer this evening using 
> wglUseFontBitmaps (as I've done a number of times in the past) and for 
> once it decided to be temperamental. (This despite the fact that pretty 
> much the exact same code worked fine elsewhere.) The code involved was 
> this:
>
> TextRenderer::TextRenderer(const std::string& typeface, int pointSize)
> {
> m_base = glGenLists(128);
>
> HDC hdc = wglGetCurrentDC();
> std::wstring ws(typeface.begin(), typeface.end());
> m_pixelHeight = pointSize * GetDeviceCaps(hdc, LOGPIXELSY) / 72;
>
> HFONT font = CreateFont(-m_pixelHeight, 0, 0, 0, FW_NORMAL, false, false, 
> false, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, 
> ANTIALIASED_QUALITY, DEFAULT_PITCH|FF_DONTCARE, ws.c_str());
>
> HFONT oldFont = (HFONT)SelectObject(hdc, font);
> bool succeeded = wglUseFontBitmaps(hdc, 32, 96, m_base+32) != 0;
> SelectObject(hdc, oldFont);
> DeleteFont(font);
> if(!succeeded) throw Exception("<Whatever>");
> #else
> #error TextRenderer - Platform not yet supported.
> #endif
> }
>
> Here wglUseFontBitmaps was returning false, but GetLastError(), which is 
> supposed to return additional error information, was returning 0 (i.e. no 
> error) when I added it in to check what was going on. (I also found that 
> the call succeeded if I constructed a TextRenderer object in certain parts 
> of the code base, but not others - note that the project's 
> single-threaded, so it's not a threading issue AFAICS. Also, replacing the 
> OpenGL rendering context via HGLRC hrc = wglCreateContext(hdc); 
> wglMakeCurrent(hdc, hrc); made the call succeed but - naturally - messed 
> up everything else.) After some googling, I found that sometimes calling 
> wglUseFontBitmaps multiple times works when it fails the first time, but 
> no real explanation as to why that might be the case. Replacing the line 
> above with the loop below works, but I'm at a loss to explain what's going 
> on:
>
> // Try and generate the font bitmaps - note that this sometimes has to
> // be called multiple times to get it to work, which is seriously dodgy. 
> // If we fail several times in a row, just give up.
> bool succeeded = false;
> const int MAX_TRIES = 5;
> for(int i=0; i<MAX_TRIES && !succeeded; ++i)
> {
> succeeded = wglUseFontBitmaps(hdc, 32, 96, m_base+32) != 0;
> }
>
> Any ideas as to what might be wrong please? Is it something I'm doing 
> wrong (99% chance!) or is it more likely to be an issue with the driver 
> implementation?
>
> Cheers,
> Stu
>
> P.S. I know this whole approach to text rendering is sub-optimal (I intend 
> to replace it at a later date) - I'm just genuinely curious as to what's 
> going on at this point.


Are you sure you have a valid rendering context? (sounds like you dont).

jbw 


0
Reply jbwest 11/13/2009 12:59:43 AM


jbwest wrote:
> "Stuart Golodetz" <blah@blah.com> wrote in message 
> news:G92dnUW8yv3JBGHXnZ2dnUVZ7t6dnZ2d@pipex.net...
>> Hi,
>>
>> Hope this is on-topic here as it's about a wgl function rather than 
>> portable OpenGL code (if not, please can someone suggest a more 
>> appropriate newsgroup?)
>>
>> I was trying to code up a quick text renderer this evening using 
>> wglUseFontBitmaps (as I've done a number of times in the past) and for 
>> once it decided to be temperamental. (This despite the fact that pretty 
>> much the exact same code worked fine elsewhere.) The code involved was 
>> this:
>>
>> TextRenderer::TextRenderer(const std::string& typeface, int pointSize)
>> {
>> m_base = glGenLists(128);
>>
>> HDC hdc = wglGetCurrentDC();
>> std::wstring ws(typeface.begin(), typeface.end());
>> m_pixelHeight = pointSize * GetDeviceCaps(hdc, LOGPIXELSY) / 72;
>>
>> HFONT font = CreateFont(-m_pixelHeight, 0, 0, 0, FW_NORMAL, false, false, 
>> false, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, 
>> ANTIALIASED_QUALITY, DEFAULT_PITCH|FF_DONTCARE, ws.c_str());
>>
>> HFONT oldFont = (HFONT)SelectObject(hdc, font);
>> bool succeeded = wglUseFontBitmaps(hdc, 32, 96, m_base+32) != 0;
>> SelectObject(hdc, oldFont);
>> DeleteFont(font);
>> if(!succeeded) throw Exception("<Whatever>");
>> #else
>> #error TextRenderer - Platform not yet supported.
>> #endif
>> }
>>
>> Here wglUseFontBitmaps was returning false, but GetLastError(), which is 
>> supposed to return additional error information, was returning 0 (i.e. no 
>> error) when I added it in to check what was going on. (I also found that 
>> the call succeeded if I constructed a TextRenderer object in certain parts 
>> of the code base, but not others - note that the project's 
>> single-threaded, so it's not a threading issue AFAICS. Also, replacing the 
>> OpenGL rendering context via HGLRC hrc = wglCreateContext(hdc); 
>> wglMakeCurrent(hdc, hrc); made the call succeed but - naturally - messed 
>> up everything else.) After some googling, I found that sometimes calling 
>> wglUseFontBitmaps multiple times works when it fails the first time, but 
>> no real explanation as to why that might be the case. Replacing the line 
>> above with the loop below works, but I'm at a loss to explain what's going 
>> on:
>>
>> // Try and generate the font bitmaps - note that this sometimes has to
>> // be called multiple times to get it to work, which is seriously dodgy. 
>> // If we fail several times in a row, just give up.
>> bool succeeded = false;
>> const int MAX_TRIES = 5;
>> for(int i=0; i<MAX_TRIES && !succeeded; ++i)
>> {
>> succeeded = wglUseFontBitmaps(hdc, 32, 96, m_base+32) != 0;
>> }
>>
>> Any ideas as to what might be wrong please? Is it something I'm doing 
>> wrong (99% chance!) or is it more likely to be an issue with the driver 
>> implementation?
>>
>> Cheers,
>> Stu
>>
>> P.S. I know this whole approach to text rendering is sub-optimal (I intend 
>> to replace it at a later date) - I'm just genuinely curious as to what's 
>> going on at this point.
> 
> 
> Are you sure you have a valid rendering context? (sounds like you dont).
> 
> jbw

I wondered that, but wglGetCurrentContext returns something non-NULL 
when I put it in. Its documentation says:

"If the calling thread has a current OpenGL rendering context, 
wglGetCurrentContext returns a handle to that rendering context. 
Otherwise, the return value is NULL."

Also, the documentation for wglGetCurrentDC says:

"If the calling thread has a current OpenGL rendering context, the 
function returns a handle to the device context associated with that 
rendering context by means of the wglMakeCurrent function. Otherwise, 
the return value is NULL."

If wglGetCurrentDC is giving me a valid (i.e. non-NULL) device context, 
which it is, then that implies that the calling thread has a current 
OpenGL rendering context. Also, wglGetCurrentDC is giving me the same 
device context I get if I query SDL for the HWND of the window and call 
GetDC on that - so I think I'm safe in saying that the device context is 
valid, and hence the rendering context is as well.

This is what's puzzling me :) Along with the fact that calling 
wglUseFontBitmaps twice can fail the first time and work the second 
time. If the rendering context was invalid, you'd expect it to fail both 
times surely?

Cheers,
Stu
0
Reply Stuart 11/13/2009 1:19:56 PM

"Stuart Golodetz" <blah@blah.com> wrote in message 
news:9v-dncQJyN5jwWDXnZ2dnUVZ8rCdnZ2d@pipex.net...
> jbwest wrote:
>> "Stuart Golodetz" <blah@blah.com> wrote in message 
>> news:G92dnUW8yv3JBGHXnZ2dnUVZ7t6dnZ2d@pipex.net...
>>> Hi,
>>>
>>> Hope this is on-topic here as it's about a wgl function rather than 
>>> portable OpenGL code (if not, please can someone suggest a more 
>>> appropriate newsgroup?)
>>>
>>> I was trying to code up a quick text renderer this evening using 
>>> wglUseFontBitmaps (as I've done a number of times in the past) and for 
>>> once it decided to be temperamental. (This despite the fact that pretty 
>>> much the exact same code worked fine elsewhere.) The code involved was 
>>> this:
>>>
>>> TextRenderer::TextRenderer(const std::string& typeface, int pointSize)
>>> {
>>> m_base = glGenLists(128);
>>>
>>> HDC hdc = wglGetCurrentDC();
>>> std::wstring ws(typeface.begin(), typeface.end());
>>> m_pixelHeight = pointSize * GetDeviceCaps(hdc, LOGPIXELSY) / 72;
>>>
>>> HFONT font = CreateFont(-m_pixelHeight, 0, 0, 0, FW_NORMAL, false, 
>>> false, false, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, 
>>> ANTIALIASED_QUALITY, DEFAULT_PITCH|FF_DONTCARE, ws.c_str());
>>>
>>> HFONT oldFont = (HFONT)SelectObject(hdc, font);
>>> bool succeeded = wglUseFontBitmaps(hdc, 32, 96, m_base+32) != 0;
>>> SelectObject(hdc, oldFont);
>>> DeleteFont(font);
>>> if(!succeeded) throw Exception("<Whatever>");
>>> #else
>>> #error TextRenderer - Platform not yet supported.
>>> #endif
>>> }
>>>
>>> Here wglUseFontBitmaps was returning false, but GetLastError(), which is 
>>> supposed to return additional error information, was returning 0 (i.e. 
>>> no error) when I added it in to check what was going on. (I also found 
>>> that the call succeeded if I constructed a TextRenderer object in 
>>> certain parts of the code base, but not others - note that the project's 
>>> single-threaded, so it's not a threading issue AFAICS. Also, replacing 
>>> the OpenGL rendering context via HGLRC hrc = wglCreateContext(hdc); 
>>> wglMakeCurrent(hdc, hrc); made the call succeed but - naturally - messed 
>>> up everything else.) After some googling, I found that sometimes calling 
>>> wglUseFontBitmaps multiple times works when it fails the first time, but 
>>> no real explanation as to why that might be the case. Replacing the line 
>>> above with the loop below works, but I'm at a loss to explain what's 
>>> going on:
>>>
>>> // Try and generate the font bitmaps - note that this sometimes has to
>>> // be called multiple times to get it to work, which is seriously dodgy. 
>>> // If we fail several times in a row, just give up.
>>> bool succeeded = false;
>>> const int MAX_TRIES = 5;
>>> for(int i=0; i<MAX_TRIES && !succeeded; ++i)
>>> {
>>> succeeded = wglUseFontBitmaps(hdc, 32, 96, m_base+32) != 0;
>>> }
>>>
>>> Any ideas as to what might be wrong please? Is it something I'm doing 
>>> wrong (99% chance!) or is it more likely to be an issue with the driver 
>>> implementation?
>>>
>>> Cheers,
>>> Stu
>>>
>>> P.S. I know this whole approach to text rendering is sub-optimal (I 
>>> intend to replace it at a later date) - I'm just genuinely curious as to 
>>> what's going on at this point.
>>
>>
>> Are you sure you have a valid rendering context? (sounds like you dont).
>>
>> jbw
>
> I wondered that, but wglGetCurrentContext returns something non-NULL when 
> I put it in. Its documentation says:
>
> "If the calling thread has a current OpenGL rendering context, 
> wglGetCurrentContext returns a handle to that rendering context. 
> Otherwise, the return value is NULL."
>
> Also, the documentation for wglGetCurrentDC says:
>
> "If the calling thread has a current OpenGL rendering context, the 
> function returns a handle to the device context associated with that 
> rendering context by means of the wglMakeCurrent function. Otherwise, the 
> return value is NULL."
>
> If wglGetCurrentDC is giving me a valid (i.e. non-NULL) device context, 
> which it is, then that implies that the calling thread has a current 
> OpenGL rendering context. Also, wglGetCurrentDC is giving me the same 
> device context I get if I query SDL for the HWND of the window and call 
> GetDC on that - so I think I'm safe in saying that the device context is 
> valid, and hence the rendering context is as well.
>
> This is what's puzzling me :) Along with the fact that calling 
> wglUseFontBitmaps twice can fail the first time and work the second time. 
> If the rendering context was invalid, you'd expect it to fail both times 
> surely?
>
> Cheers,
> Stu

yes, you would, unless the 1st pass causes a side-effect. Very strange 
indeed.

jbw


0
Reply jbwest 11/13/2009 7:22:30 PM

On Nov 13, 2:22=A0pm, "jbwest" <jbw...@acm.org> wrote:
> "Stuart Golodetz" <b...@blah.com> wrote in message
>
> news:9v-dncQJyN5jwWDXnZ2dnUVZ8rCdnZ2d@pipex.net...
>
>
>
> > jbwest wrote:
> >> "Stuart Golodetz" <b...@blah.com> wrote in message
> >>news:G92dnUW8yv3JBGHXnZ2dnUVZ7t6dnZ2d@pipex.net...
> >>> Hi,
>
> >>> Hope this is on-topic here as it's about a wgl function rather than
> >>> portable OpenGL code (if not, please can someone suggest a more
> >>> appropriate newsgroup?)
>
> >>> I was trying to code up a quick text renderer this evening using
> >>> wglUseFontBitmaps (as I've done a number of times in the past) and fo=
r
> >>> once it decided to be temperamental. (This despite the fact that pret=
ty
> >>> much the exact same code worked fine elsewhere.) The code involved wa=
s
> >>> this:
>
> >>> TextRenderer::TextRenderer(const std::string& typeface, int pointSize=
)
> >>> {
> >>> m_base =3D glGenLists(128);
>
> >>> HDC hdc =3D wglGetCurrentDC();
> >>> std::wstring ws(typeface.begin(), typeface.end());
> >>> m_pixelHeight =3D pointSize * GetDeviceCaps(hdc, LOGPIXELSY) / 72;
>
> >>> HFONT font =3D CreateFont(-m_pixelHeight, 0, 0, 0, FW_NORMAL, false,
> >>> false, false, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
> >>> ANTIALIASED_QUALITY, DEFAULT_PITCH|FF_DONTCARE, ws.c_str());
>
> >>> HFONT oldFont =3D (HFONT)SelectObject(hdc, font);
> >>> bool succeeded =3D wglUseFontBitmaps(hdc, 32, 96, m_base+32) !=3D 0;
> >>> SelectObject(hdc, oldFont);
> >>> DeleteFont(font);
> >>> if(!succeeded) throw Exception("<Whatever>");
> >>> #else
> >>> #error TextRenderer - Platform not yet supported.
> >>> #endif
> >>> }
>
> >>> Here wglUseFontBitmaps was returning false, but GetLastError(), which=
 is
> >>> supposed to return additional error information, was returning 0 (i.e=
..
> >>> no error) when I added it in to check what was going on. (I also foun=
d
> >>> that the call succeeded if I constructed a TextRenderer object in
> >>> certain parts of the code base, but not others - note that the projec=
t's
> >>> single-threaded, so it's not a threading issue AFAICS. Also, replacin=
g
> >>> the OpenGL rendering context via HGLRC hrc =3D wglCreateContext(hdc);
> >>> wglMakeCurrent(hdc, hrc); made the call succeed but - naturally - mes=
sed
> >>> up everything else.) After some googling, I found that sometimes call=
ing
> >>> wglUseFontBitmaps multiple times works when it fails the first time, =
but
> >>> no real explanation as to why that might be the case. Replacing the l=
ine
> >>> above with the loop below works, but I'm at a loss to explain what's
> >>> going on:
>
> >>> // Try and generate the font bitmaps - note that this sometimes has t=
o
> >>> // be called multiple times to get it to work, which is seriously dod=
gy.
> >>> // If we fail several times in a row, just give up.
> >>> bool succeeded =3D false;
> >>> const int MAX_TRIES =3D 5;
> >>> for(int i=3D0; i<MAX_TRIES && !succeeded; ++i)
> >>> {
> >>> succeeded =3D wglUseFontBitmaps(hdc, 32, 96, m_base+32) !=3D 0;
> >>> }
>
> >>> Any ideas as to what might be wrong please? Is it something I'm doing
> >>> wrong (99% chance!) or is it more likely to be an issue with the driv=
er
> >>> implementation?
>
> >>> Cheers,
> >>> Stu
>
> >>> P.S. I know this whole approach to text rendering is sub-optimal (I
> >>> intend to replace it at a later date) - I'm just genuinely curious as=
 to
> >>> what's going on at this point.
>
> >> Are you sure you have a valid rendering context? (sounds like you dont=
).
>
> >> jbw
>
> > I wondered that, but wglGetCurrentContext returns something non-NULL wh=
en
> > I put it in. Its documentation says:
>
> > "If the calling thread has a current OpenGL rendering context,
> > wglGetCurrentContext returns a handle to that rendering context.
> > Otherwise, the return value is NULL."
>
> > Also, the documentation for wglGetCurrentDC says:
>
> > "If the calling thread has a current OpenGL rendering context, the
> > function returns a handle to the device context associated with that
> > rendering context by means of the wglMakeCurrent function. Otherwise, t=
he
> > return value is NULL."
>
> > If wglGetCurrentDC is giving me a valid (i.e. non-NULL) device context,
> > which it is, then that implies that the calling thread has a current
> > OpenGL rendering context. Also, wglGetCurrentDC is giving me the same
> > device context I get if I query SDL for the HWND of the window and call
> > GetDC on that - so I think I'm safe in saying that the device context i=
s
> > valid, and hence the rendering context is as well.
>
> > This is what's puzzling me :) Along with the fact that calling
> > wglUseFontBitmaps twice can fail the first time and work the second tim=
e.
> > If the rendering context was invalid, you'd expect it to fail both time=
s
> > surely?
>
> > Cheers,
> > Stu
>
> yes, you would, unless the 1st pass causes a side-effect. Very strange
> indeed.
>
> jbw

Have you found a soultion to this? I just ran across the exact same
thing.

0
Reply rodif 12/22/2009 4:52:47 AM

4 Replies
398 Views

(page loaded in 0.169 seconds)

Similiar Articles:











7/21/2012 7:33:37 PM


Reply: