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)
|