FTGL font engine

  • Follow


After trying to use wglUseFontBitmaps to render text I've since ditched this 
and have chosen to use FreeType2 and FTGL.

However I'm still having an issue with my text being mirror-reflected on the 
horizontal axis, essentially making the text appear upside down.

I think this is due to the fact that the surface I'm restriced to using is a 
GDI dibsection. It seems a dibsection is stored in a row-reversed manner 
with the first row of pixels in memory being the last row of the actual 
image.

Does anyone know how I can manipulate the stored image of the font created 
by FreeType2 and/or FTGL so that the character set is upside and will thus 
render correctly?

While I'm here I would like to give the finger to whoever decided that 
dibsections should be stored upside down :)

Apparently this is all due to the bad old days of OS2 and Presentation 
Manager. Isn't progress wonderful?

Any help on this would be greatly appreciated. 


0
Reply Seefer 7/2/2006 9:31:56 PM

Seefer wrote:

> After trying to use wglUseFontBitmaps to render text I've since ditched
> this and have chosen to use FreeType2 and FTGL.
> 
> However I'm still having an issue with my text being mirror-reflected on
> the horizontal axis, essentially making the text appear upside down.
> 
> I think this is due to the fact that the surface I'm restriced to using is
> a GDI dibsection. It seems a dibsection is stored in a row-reversed manner
> with the first row of pixels in memory being the last row of the actual
> image.

The row ordering of GDI DIBSECTION images and OpenGL (with one exception
though) is bottom to top.

So I think, that the image is correct and you're just displaying wrong.

The one exception in OpenGL scanline ordering are cube maps. While OpenGL
texture targets GL_TEXTURE_[123]D and glDrawPixels/glReadPixels see data
bottom to top, cubemap face images are top to bottom ordered. This has
however no technical but a historic reason, that cubemaps were first used
by the Renderman software and beeing top to bottom ordered. This convention
has been taken over to OpenGL. This inconsistency is - well - inconsitant,
not logical for any reason and IMHO the bottom feeder had this brilliant
"idea" to keep this convention torturing OpenGL with it - and all its
fellow users wanting to use cubemaps running into this pitfall, including
me - should become tared and feathered.

Wolfgang Draxinger

0
Reply Wolfgang 7/2/2006 10:58:37 PM


When you say I'm displaying wrong, I am not actually using any of my code to 
do the rendering. I'm simply calling the relevant FTGL API calls (which 
subsequently use the FreeType2 font service) for loading a font file then 
using the FTGL Render class method to display the string.

I guess I need some way to access the buffer that FreeType2 uses to generate 
the font from the font file, then process it so that the scanlines are 
reversed. However, the FreeType2 and FTGL APIs do not provide any method of 
access to this font image buffer.

Any suggestions?


"Wolfgang Draxinger" <wdraxinger@darkstargames.de> wrote in message 
news:e89j2t$c2n$1@svr7.m-online.net...
> Seefer wrote:
>
>> After trying to use wglUseFontBitmaps to render text I've since ditched
>> this and have chosen to use FreeType2 and FTGL.
>>
>> However I'm still having an issue with my text being mirror-reflected on
>> the horizontal axis, essentially making the text appear upside down.
>>
>> I think this is due to the fact that the surface I'm restriced to using 
>> is
>> a GDI dibsection. It seems a dibsection is stored in a row-reversed 
>> manner
>> with the first row of pixels in memory being the last row of the actual
>> image.
>
> The row ordering of GDI DIBSECTION images and OpenGL (with one exception
> though) is bottom to top.
>
> So I think, that the image is correct and you're just displaying wrong.
>
> The one exception in OpenGL scanline ordering are cube maps. While OpenGL
> texture targets GL_TEXTURE_[123]D and glDrawPixels/glReadPixels see data
> bottom to top, cubemap face images are top to bottom ordered. This has
> however no technical but a historic reason, that cubemaps were first used
> by the Renderman software and beeing top to bottom ordered. This 
> convention
> has been taken over to OpenGL. This inconsistency is - well - inconsitant,
> not logical for any reason and IMHO the bottom feeder had this brilliant
> "idea" to keep this convention torturing OpenGL with it - and all its
> fellow users wanting to use cubemaps running into this pitfall, including
> me - should become tared and feathered.
>
> Wolfgang Draxinger
> 


0
Reply Seefer 7/2/2006 11:05:16 PM

Seefer wrote:

> When you say I'm displaying wrong, I am not actually using any
> of my code to do the rendering. I'm simply calling the relevant
> FTGL API calls (which subsequently use the FreeType2 font
> service) for loading a font file then using the FTGL Render
> class method to display the string.

What I meant was, that you're probably setting up your OpenGL
context wrong, or assume wrong ordering of OpenGL scanlines in
the window. OpenGL sees it's origin in the _lower left_.
Probably you're using glOrtho with the width and height of your
viewport for a HUD of some sort and got the parameters set
wrong.

To get the up vector right the parameters should be something
like

glOrtho(
0,     // left
width, // right
0,     // bottom
height,// top
-1,    // near
1,     // far
);

Note that bottom is "0" while top is "height". Probably you've
been fooled by the GDI that has the origin in the upper left.
 
> I guess I need some way to access the buffer that FreeType2
> uses to generate the font from the font file, then process it
> so that the scanlines are reversed. However, the FreeType2 and
> FTGL APIs do not provide any method of access to this font
> image buffer.

You don't have to access the buffer because FTGL already
everything prepares for you to get things right.

As a rule of thumb you should always first assume that _your own_
code is broken, not the one provided by third parties. Only if
everything in your own code works you may blame others.

Wolfgang Draxinger
-- 

0
Reply Wolfgang 7/3/2006 7:23:42 AM

Playing with the coordinate system for the projection matrix to reverse the 
Y axis orientation was the first thing I tried.

Alas it makes no difference other than the fact the mirror-reversed text is 
printed either at top left or bottom right when I position it with 
glRasterPos2f() :(


"Wolfgang Draxinger" <wdraxinger@darkstargames.de> wrote in message 
news:v8tmn3-qsb.ln1@darkstargames.dnsalias.net...
> Seefer wrote:
>
>> When you say I'm displaying wrong, I am not actually using any
>> of my code to do the rendering. I'm simply calling the relevant
>> FTGL API calls (which subsequently use the FreeType2 font
>> service) for loading a font file then using the FTGL Render
>> class method to display the string.
>
> What I meant was, that you're probably setting up your OpenGL
> context wrong, or assume wrong ordering of OpenGL scanlines in
> the window. OpenGL sees it's origin in the _lower left_.
> Probably you're using glOrtho with the width and height of your
> viewport for a HUD of some sort and got the parameters set
> wrong.
>
> To get the up vector right the parameters should be something
> like
>
> glOrtho(
> 0,     // left
> width, // right
> 0,     // bottom
> height,// top
> -1,    // near
> 1,     // far
> );
>
> Note that bottom is "0" while top is "height". Probably you've
> been fooled by the GDI that has the origin in the upper left.
>
>> I guess I need some way to access the buffer that FreeType2
>> uses to generate the font from the font file, then process it
>> so that the scanlines are reversed. However, the FreeType2 and
>> FTGL APIs do not provide any method of access to this font
>> image buffer.
>
> You don't have to access the buffer because FTGL already
> everything prepares for you to get things right.
>
> As a rule of thumb you should always first assume that _your own_
> code is broken, not the one provided by third parties. Only if
> everything in your own code works you may blame others.
>
> Wolfgang Draxinger
> -- 
> 


0
Reply Seefer 7/3/2006 5:10:58 PM

Seefer wrote:

> Playing with the coordinate system for the projection matrix to
> reverse the Y axis orientation was the first thing I tried.
> 
> Alas it makes no difference other than the fact the
> mirror-reversed text is printed either at top left or bottom
> right when I position it with glRasterPos2f() :(

Oh, I didn't read your first post not right: You're using
glDrawPixels (glRasterPos only makes sense then).

First let me tell you, that you should better use textured quads,
as glDrawPixels is very slow. Nevertheless you can still use
glPixelZoom(1,-1) to mirror the image upside down, if you don't
want to to scanline swapping. However this will make
glDrawPixels even slower.

Wolfgang Draxinger

0
Reply Wolfgang 7/3/2006 7:27:17 PM

I'm only using glRasterPos to position the start of the text, but I'm simply 
relying on the FTGL API to both handle the construction of my text and to 
render it out. I'm not directly reading pixels and plotting them myself. All 
functionality in FTGL and FreeType2 is encapsulated in classes so I have no 
idea how it's doing things internally to render text. I presume it's using 
the appriorate techniques depending on what kind of font I'm using such as 
those below.

FTGL allows you to create various types of text - bitmaps, pixmaps, polygon, 
outline etc, with a simple API call such as the following:

font = new FTGLPixmapFont(DEFAULT_FONT);

or

font = new FTGLTextureFont(DEFAULT_FONT);

or

font = new FTGLPolygonFont(DEFAULT_FONT);


I'm working in 2D and from the quality of the text in the FTGL demos, the 
Pixmap or Texture fonts are exactly what I need for good 
quality-antialiasing. However, whether I use the font = new 
FTGLPixmapFont(DEFAULT_FONT); or  font = new FTGLTextureFont(DEFAULT_FONT);.

If I then call

font->Render("Test String");

to print my text, the result is still upside down text. I'm not sure whether 
the fault lies within OpenGL or with the structure of the dibsection surface 
I'm rendering to. The odd thing is, if I render text out to the same surface 
using GDI/GDI+ mixed in with OpenGL code for darwing primitives, everything 
looks fine. I'm beginning to think I should resort to using GDI/GDI+ methods 
for printing text considering the lack of hgher level support for text 
rendering in OpenGL.

To me, it seems FreeType2 and FTGL do not allow any manipulation of the 
character set buffer from which they index the fonts characters once it has 
been created. Otherwise I would just try and flip the bitmaps of each 
character in the buffer so that it comes out the right way up without having 
to do this every time for each render command.

Things are made all the more difficult because most OpenGL APIs from 
third-parties I've been exposed to appear to be lacking in clear, easy to 
understand API documentation. FTGL is particularly poor (further development 
of FTGL seems to have halted). The FreeType2 docs, although much better than 
FTGL, are not exactly good either. All OpenGL API developers seem to adopt a 
"technical textbook' approach rather than a more friendlier and much more 
helpful "tutorial style" approach to using their OpenGL APIs.

Things are very confusing for me at the moment, that's for sure :)

I guess it's just a question of struggling through it all and getting help 
from more experienced users such as yourself and the other helpful posters 
in this forum :)


"Wolfgang Draxinger" <wdraxinger@darkstargames.de> wrote in message 
news:ll7on3-j6c.ln1@darkstargames.dnsalias.net...
> Seefer wrote:
>
>> Playing with the coordinate system for the projection matrix to
>> reverse the Y axis orientation was the first thing I tried.
>>
>> Alas it makes no difference other than the fact the
>> mirror-reversed text is printed either at top left or bottom
>> right when I position it with glRasterPos2f() :(
>
> Oh, I didn't read your first post not right: You're using
> glDrawPixels (glRasterPos only makes sense then).
>
> First let me tell you, that you should better use textured quads,
> as glDrawPixels is very slow. Nevertheless you can still use
> glPixelZoom(1,-1) to mirror the image upside down, if you don't
> want to to scanline swapping. However this will make
> glDrawPixels even slower.
>
> Wolfgang Draxinger
> 


0
Reply Seefer 7/3/2006 8:43:28 PM

Seefer wrote:

> to print my text, the result is still upside down text. I'm not
> sure whether the fault lies within OpenGL or with the structure
> of the dibsection surface I'm rendering to. The odd thing is,
> if I render text out to the same surface using GDI/GDI+ mixed
> in with OpenGL code for darwing primitives, everything looks
> fine.

DIBSECTIONs are DIBs (device independent bitmaps) in a memory
area and have thus the same structure like a DIB-File (= .BMP).
Those have their origin in the lower left, so I think you're
just reading the DIBSECTION in the wrong order.

Why not just post the source code? This would help a lot (if you
don't want to publish you may also send it to me to my E-Mail
address. My public PGP-Key with the fingerprint 

2FC8 319E C7D7 1ADC 0408 65C6 05F5 A645 1FD3 BD3E

can be found on all major keyservers.

Wolfgang Draxinger
-- 

0
Reply Wolfgang 7/3/2006 9:31:02 PM

I greatly appreciate your help and offer to look at my source code.

However the source code has a lot of proprietary sections in it so it would 
be difficult to send you something complete.

First of all, I am not directly creating the dibsection for my own use. It 
is provided to me by the Flight Simulator 2004 system to use in order to 
render avionics gauge visuals. I am given a hardware device context, which I 
use to create an OpenGL render context.

I am not directly accessing or writing to the dibsection with my own code 
either. I am simply using the FreeType2 and FTGL API calls as explained in 
the docs to create a font and render it.

I also get the same upside down text if I use the simple wglUseFontBitmap 
method of creating a character set in a display list and then using 
glCallList().

The odd thing is, I usually learn about using things for the first time by 
creating a demo using a plain Win32 project and follow any tutorials. For 
example, when learning about the wglUseFontBitmap method of rendering text, 
I looked to tutorial number 13 on NeHe's website. Within the context of my 
stand-alone Win32 test, everything worked as expected.

However, when I cut-n-past the same OpenGL code into the context of my 
Flight Simulator DLL code, everything worked fine apart from the fact the 
text is upside down.

All very odd if you ask me :)


"Wolfgang Draxinger" <wdraxinger@darkstargames.de> wrote in message 
news:mteon3-2dc.ln1@darkstargames.dnsalias.net...
> Seefer wrote:
>
>> to print my text, the result is still upside down text. I'm not
>> sure whether the fault lies within OpenGL or with the structure
>> of the dibsection surface I'm rendering to. The odd thing is,
>> if I render text out to the same surface using GDI/GDI+ mixed
>> in with OpenGL code for darwing primitives, everything looks
>> fine.
>
> DIBSECTIONs are DIBs (device independent bitmaps) in a memory
> area and have thus the same structure like a DIB-File (= .BMP).
> Those have their origin in the lower left, so I think you're
> just reading the DIBSECTION in the wrong order.
>
> Why not just post the source code? This would help a lot (if you
> don't want to publish you may also send it to me to my E-Mail
> address. My public PGP-Key with the fingerprint
>
> 2FC8 319E C7D7 1ADC 0408 65C6 05F5 A645 1FD3 BD3E
>
> can be found on all major keyservers.
>
> Wolfgang Draxinger
> -- 
> 


0
Reply Seefer 7/3/2006 10:24:32 PM

Seefer wrote:

> I am not directly accessing or writing to the dibsection with
> my own code either. I am simply using the FreeType2 and FTGL
> API calls as explained in the docs to create a font and render
> it.

I don't think, that this is an OpenGL problem. Probably you just
got a problem with the ordering of the DIBSECTION. A quick test
is to render a colorbar to see in which direction it increments.
Say you got a width x height pixel DIBSECTION, then the
following code will render a mixture of red and green to it IIRC
DIBSECTIONs are BGR

struct BGR
{
unsigned char blue;
unsigned char green;
unsigned char red;
};
int width, height;
BGR *p=//DIBSECTION Data
for(int y=0; y<height; ++y)
{
for(int x=0; x<width; ++x)
{
p.red   = x & 0xff;
p.green = y & 0xff;
}
}

Dealing with new image manipulation functions it's always good to
first get aware of the general conditions. The above pattern is
a good starting point, as it gives you a good hint of the
direction.

If a picture supplied to FS2004 by this has the gradients growing
intensities from upwards then reading the data with glReadPixels
to the DIBSECTION requires no intermediate steps. If however the
gradient is downwards you've to mirror the rendered image
vertically. This is easiest done by scaling the Projection
Matrix with glScale(1,-1,1); If you use only Orthographic
projection you may also just swap the "top" and "bottom"
parameters.

Wolfgang Draxinger
-- 

0
Reply Wolfgang 7/3/2006 10:41:03 PM

9 Replies
331 Views

(page loaded in 0.681 seconds)

Similiar Articles:










7/21/2012 9:17:36 PM


Reply: