Discussion:
glCallLists and glRasterPos - How to calculate the location of the next row ?
(too old to reply)
R.Wieser
2013-08-31 11:14:27 UTC
Permalink
Hello All,

I'm drawing some text using the glCallLists method, and am using the
glRasterPos command to determine where the text should be placed.

A few questions:

1) How do I find out where to start a new line just below the one just drawn
(intention: implementing CRLF)

2) How do I calculate the location of the end of the text I've just drawn
(intention : draw a line with some text colored).

Also: I've been looking a NeHe's tutorials, but do not directly see
anything in relation to a method to create a 2D overlay (so something like
"HUD" text (and maybe 2D graphics) can be easily drawn ontop of the 3D
scene). Is such a method available under OpenGL ?

Regards,
Rudy Wieser
Jean-Christophe
2013-08-31 13:25:12 UTC
Permalink
"R.Wieser"
I'm drawing some text using the glCallLists method, and am using the
glRasterPos command to determine where the text should be placed.
1) How do I find out where to start a new line just below
the one just drawn (intention: implementing CRLF)
2) How do I calculate the location of the end of the text
I've just drawn (intention : draw a line with some text colored).
Had the same problem, fixed by selecting a fixed font
and increasing the Y position by a constant factor,
the height of the text. To find the position of
the end of a string at position [x,y] just do this :
pos = x + ( width * strlen(string) );
I used this to draw a rectangle around any
arbitrary text located at arbitrary 2D position.
Plus, note that you can set text location at 3D pos
inside yer scene by using glRasterPos3d(x,y,z);

----

void fctInitText(HDC h)
{ // select font
SelectObject(h,GetStockObject(ANSI_FIXED_FONT));
wglUseFontBitmaps(hd,0,255,INDEX_LIST_TEXT);
}

// draw text
const int height = 14, width = 12; // font's text width/height
int x=64, y=16; // XY text initial 2D position
glRasterPos2i(x,y); // text pos line N
... // display text
glRasterPos2i(x,y+=height); // text pos line N+1
... // display text

HTH
R.Wieser
2013-08-31 14:14:36 UTC
Permalink
Hello Jean-Christophe,
Post by Jean-Christophe
Had the same problem, fixed by selecting a
fixed font and increasing the Y position by a
constant factor,
I also thought about using such a constant factor, but that won't work in a
3D environment: points further away from the camera seem to move closer to
each other (at some point in the distance causing the lines of text to
overlap, as text does not get scaled).

Also, I would like to be able to retrieve/calculate that 'constant factor'
value for whatever font and scale I'm using/is selected (Like you can do
when using windows GDI).
Post by Jean-Christophe
Plus, note that you can set text location at 3D pos
inside yer scene by using glRasterPos3d(x,y,z);
Yeah, I noticed it. I did draw the text "Square" over a flat square (duh)
in a 3D world (using a glRasterPos Z of 0), and noticed the text getting ...
chopped off at the bottom (getting partially obscured by the square).
Using a Z of 0.1 made it float a bit infront of the square, and the text was
whole again.

Regards,
Rudy Wieser
Post by Jean-Christophe
"R.Wieser"
I'm drawing some text using the glCallLists method, and am using the
glRasterPos command to determine where the text should be placed.
1) How do I find out where to start a new line just below
the one just drawn (intention: implementing CRLF)
2) How do I calculate the location of the end of the text
I've just drawn (intention : draw a line with some text colored).
Had the same problem, fixed by selecting a fixed font
and increasing the Y position by a constant factor,
the height of the text. To find the position of
pos = x + ( width * strlen(string) );
I used this to draw a rectangle around any
arbitrary text located at arbitrary 2D position.
Plus, note that you can set text location at 3D pos
inside yer scene by using glRasterPos3d(x,y,z);
----
void fctInitText(HDC h)
{ // select font
SelectObject(h,GetStockObject(ANSI_FIXED_FONT));
wglUseFontBitmaps(hd,0,255,INDEX_LIST_TEXT);
}
// draw text
const int height = 14, width = 12; // font's text width/height
int x=64, y=16; // XY text initial 2D position
glRasterPos2i(x,y); // text pos line N
... // display text
glRasterPos2i(x,y+=height); // text pos line N+1
... // display text
HTH
Jean-Christophe
2013-08-31 18:48:40 UTC
Permalink
Post by R.Wieser
Jean-Christophe
selecting a fixed font and increasing
the Y position by a constant factor
"R.Wieser"
I also thought about using such a constant factor, but that won't work in a
3D environment: points further away from the camera seem to move closer to
each other (at some point in the distance causing the lines of text to
overlap, as text does not get scaled).
Sound strange to me because I used this with 2D and 3D text
position and it worked : along the Z axis the numbers don't shrink.
Loading Image...

There is also the option to create your own 3D set of ASCII
symbols, then you'll be able to do everything you want in 3D.
Also, I would like to be able to retrieve/calculate that 'constant factor'
value for whatever font and scale I'm using/is selected (Like you can do
when using windows GDI).
Did you try to retreive width/height of current font ?

TEXTMETRIC tm;
long width, height;
GetTextMetrics( hdc, &tm );
width = tm.tmAveCharWidth;
height = tm.tmHeight + tm.tmExternalLeading;
R.Wieser
2013-08-31 19:49:16 UTC
Permalink
Hello Jean-Christophe,
Post by Jean-Christophe
Sound strange to me because I used this with 2D
and 3D text position and it worked : along the Z
axis the numbers don't shrink.
I wasn't talking about the strings themselves, but about the 3D objects :
the further they are away from the camera, the smaller they look.

As an example, I used NeHes tutorial as found here for two basic forms:
http://nehe.gamedev.net/tutorial/your_first_polygon/13002/

And than I added some code to draw text pretty-much straight from another of
NeHes tutorials as found here:
http://nehe.gamedev.net/tutorial/bitmap_fonts/17002/

After drawing the triangle I did draw a bit of text, "Triangle", using a
glRasterPos2i of 0,0. After the drawing the square I did draw a second bit
of text, "Square", again using a glRasterPos2i of 0,0.

No problems there. Both bits of text are drawn, starting from the center of
the triangle and the square respectivily, and not overlapping at all.

Than I changed, in the first translation, the Z translation from -6 to -30.
That causes the two objects to be drawn quite a bit further in the distance,
making the objects, measured in pixels, appear much closer to each other.
And that causes the text, which does not get any smaller, to partially
overlap.

And thats the problem. I must either include some sort of calculation that
will take the distance to the camera in account, or I must find an OpenGL
function which will do it for me (and I'm hoping for the latter). :-)
Post by Jean-Christophe
Did you try to retreive width/height of current font ?
I can. But that will not solve anything I'm afraid. Well, maybe if I only
draw at a distance of Zero to the camera (a kind of overlay position).
Actually, I would probably need to adjust those values anyway, as VOF and
possibly the initial SetPixelFormat (and maybe other stuff too) will
influence it.

Regards,
Rudy Wieser
Post by Jean-Christophe
Post by R.Wieser
Jean-Christophe
selecting a fixed font and increasing
the Y position by a constant factor
"R.Wieser"
I also thought about using such a constant factor, but that won't work
in
Post by Jean-Christophe
a
3D environment: points further away from the camera seem to move closer to
each other (at some point in the distance causing the lines of text to
overlap, as text does not get scaled).
Sound strange to me because I used this with 2D and 3D text
position and it worked : along the Z axis the numbers don't shrink.
http://cjoint.com/data/0HFuPeD5Xha_0d.jpg
There is also the option to create your own 3D set of ASCII
symbols, then you'll be able to do everything you want in 3D.
Also, I would like to be able to retrieve/calculate that 'constant factor'
value for whatever font and scale I'm using/is selected (Like you can do
when using windows GDI).
Did you try to retreive width/height of current font ?
TEXTMETRIC tm;
long width, height;
GetTextMetrics( hdc, &tm );
width = tm.tmAveCharWidth;
height = tm.tmHeight + tm.tmExternalLeading;
Jean-Christophe
2013-09-01 07:33:40 UTC
Permalink
(...) Than I changed, in the first translation, the Z translation from -6
to -30.
That causes the two objects to be drawn quite a bit further in the distance,
making the objects, measured in pixels, appear much closer to each other.
And that causes the text, which does not get any smaller, to partially
overlap.
And thats the problem. I must either include some sort of calculation that
will take the distance to the camera in account, or I must find an OpenGL
function which will do it for me (and I'm hoping for the latter). :-)
I doubt you can shrink/resize the text drawn by glRasterPos()
I suggest again that you create 3D models of the letters
of the alphabet and use them as 3D objects in your
3D scene - I think it will solve all your problems.

Another alternative is to create a transparent RGBA
BMP as an array of 26 squares with letters drawn,
( or 26 small BMPs, one for each letter )
load the BMP at the start-up on your program,
and to display a string, use an index/pointer
to fetch the corresponding (sub)BMP for display.
( doesn't sound straightforward, but it is : I used this for
a 3D chess board (8x8x8) and when the user rotates the
chessboard, the letters turn so they are always readable )
Post by Jean-Christophe
Did you try to retreive width/height of current font ?
I can. But that will not solve anything I'm afraid.
Yes, now I realize that it would be useless under OpenGL
since those values are only Windows-related.
Well, maybe if I only
draw at a distance of Zero to the camera (a kind of overlay position).
Actually, I would probably need to adjust those values anyway, as VOF and
possibly the initial SetPixelFormat (and maybe other stuff too) will
influence it.
R.Wieser
2013-09-01 08:35:48 UTC
Permalink
Hello Jean-Christophe,
Post by Jean-Christophe
I doubt you can shrink/resize the text drawn by glRasterPos()
Thats not what I ment.

What I tried to explain is that *any* constant you might want to add to the
Y position of the previous line to get to the position of the new line will
fail to work if the distance-to-the-camera is not a constant too.

And as I want to be able to draw multi-part/line text next to any 3D point
(near or far) I need a different solution (than a constant).
Post by Jean-Christophe
Yes, now I realize that it would be useless under
OpenGL since those values are only Windows-related.
Thats not it I'm afraid (at least not for me, as I'm writing under/for
Windows).

Just shrink the size of the window window that is used to draw the OpenGL
scene into, and you will see that the drawn (3D) objects will become smaller
too, although the text doesn't. It will give the same problem as drawing
the objects further away.

In other words: For that "take a constant" solution to work you have to
limit yourself/your drawing in quite a few ways. :-\

Thanks for your response though,

Regards,
Rudy Wieser

P.s.
Please take a look at the image you posted, and notice how the distance
between the digits on the X and Z axis seem to get smaller going from the
positive to the negative end. Stretch either axis a bit further in the
negative direction and the digits (the text) will start to overlap, even
though the distance in 3D units stays the same over the length of the axis
...
Post by Jean-Christophe
(...) Than I changed, in the first translation, the Z translation from -6
to -30.
That causes the two objects to be drawn quite a bit further in the distance,
making the objects, measured in pixels, appear much closer to each other.
And that causes the text, which does not get any smaller, to partially
overlap.
And thats the problem. I must either include some sort of calculation that
will take the distance to the camera in account, or I must find an OpenGL
function which will do it for me (and I'm hoping for the latter). :-)
I doubt you can shrink/resize the text drawn by glRasterPos()
I suggest again that you create 3D models of the letters
of the alphabet and use them as 3D objects in your
3D scene - I think it will solve all your problems.
Another alternative is to create a transparent RGBA
BMP as an array of 26 squares with letters drawn,
( or 26 small BMPs, one for each letter )
load the BMP at the start-up on your program,
and to display a string, use an index/pointer
to fetch the corresponding (sub)BMP for display.
( doesn't sound straightforward, but it is : I used this for
a 3D chess board (8x8x8) and when the user rotates the
chessboard, the letters turn so they are always readable )
Post by Jean-Christophe
Did you try to retreive width/height of current font ?
I can. But that will not solve anything I'm afraid.
Yes, now I realize that it would be useless under OpenGL
since those values are only Windows-related.
Well, maybe if I only
draw at a distance of Zero to the camera (a kind of overlay position).
Actually, I would probably need to adjust those values anyway, as VOF and
possibly the initial SetPixelFormat (and maybe other stuff too) will
influence it.
R.Wieser
2013-09-01 08:55:50 UTC
Permalink
Post by R.Wieser
What I tried to explain is that *any* constant you might want to add to the
Y position of the previous line to get to the position of the new line will
fail to work if the distance-to-the-camera is not a constant too.
Also, you would need to have a constant orientation. Take the Z axis for
example. If you have the standard orientation where that axis points
straight outof the screen all its points will seem to lie ontop of each
other (in effect displaying the Z axis as a single dot in the center of the
screen). Rotate the X axis over 90 degrees (a different camera position)
and the Y axis will take the place of the Z axis. At that moment the
difference-in-pixels between any two points on that Y axis will always be
Zero.

That also means that adding some constant (by way of glRasterPos) to the Y
position will not have any effect for the pixel-position on the screen ...
Nobody
2013-09-01 11:11:25 UTC
Permalink
Post by R.Wieser
I'm drawing some text using the glCallLists method, and am using the
glRasterPos command to determine where the text should be placed.
1) How do I find out where to start a new line just below the one just
drawn (intention: implementing CRLF)
2) How do I calculate the location of the end of the text I've just drawn
(intention : draw a line with some text colored).
You need metrics for the font; how to get those depends upon the font API
being used.

GLUT provides glutBitmapWidth() for the width of a bitmap character and
glutBitmapLength() for the width of a bitmap string, and similarly
glutStrokeWidth() and glutStrokeLength() for stroke fonts.

For platform fonts (e.g. wglUseFontBitmaps() or glXUseXFont()), you need
to use the platform's functions for querying the metrics.
Post by R.Wieser
Also: I've been looking a NeHe's tutorials, but do not directly see
anything in relation to a method to create a 2D overlay (so something like
"HUD" text (and maybe 2D graphics) can be easily drawn ontop of the 3D
scene). Is such a method available under OpenGL ?
After rendering the 3D scene, set an orthographic projection matrix.
Disable depth tests/writes (or clear the depth buffer if you need to
use depth tests within the 2D overlay).
R.Wieser
2013-09-01 12:29:04 UTC
Permalink
Hello Nobody,
Post by Nobody
You need metrics for the font; how to get those depends
upon the font API being used.
And than some ... :-(

As I tried to explain to Jean-Christophe, the *location* of the end of the
text or the line under it seems to be dependant on the location in the 3D
world its drawn in as well as the camera position (relative to the draw
text).

Currently I do not see any easy possibility to draw multi-line text
(assuming a constant appearance) in a 3D world where the camera can move
around.
Post by Nobody
After rendering the 3D scene, set an orthographic projection
matrix.
Disable depth tests/writes (or clear the depth buffer if you
need to use depth tests within the 2D overlay).
Yep, I just found the method to do so (finished no more than 10 min ago).
Note to self: Do not reverse the top and bottom coordinates (possibly also
left and right), 'cause you won't see much when you do. :-)

Also, the ortho projection must match the size of the used window, otherwise
changing the windowsize will (again) change textlocations/spacing too.

By the way, I also tried to mix-and-match OpenGL with GDI drawing (TextOut)
to the DC. I saw the text flickering when I resized the window, but it
would not "stick".

Regards,
Rudy Wieser
Post by Nobody
Post by R.Wieser
I'm drawing some text using the glCallLists method, and am using the
glRasterPos command to determine where the text should be placed.
1) How do I find out where to start a new line just below the one just
drawn (intention: implementing CRLF)
2) How do I calculate the location of the end of the text I've just drawn
(intention : draw a line with some text colored).
You need metrics for the font; how to get those depends upon the font API
being used.
GLUT provides glutBitmapWidth() for the width of a bitmap character and
glutBitmapLength() for the width of a bitmap string, and similarly
glutStrokeWidth() and glutStrokeLength() for stroke fonts.
For platform fonts (e.g. wglUseFontBitmaps() or glXUseXFont()), you need
to use the platform's functions for querying the metrics.
Post by R.Wieser
Also: I've been looking a NeHe's tutorials, but do not directly see
anything in relation to a method to create a 2D overlay (so something like
"HUD" text (and maybe 2D graphics) can be easily drawn ontop of the 3D
scene). Is such a method available under OpenGL ?
After rendering the 3D scene, set an orthographic projection matrix.
Disable depth tests/writes (or clear the depth buffer if you need to
use depth tests within the 2D overlay).
R.Wieser
2013-09-02 13:03:55 UTC
Permalink
Replying to myself:

Drawing text on an overlay in Windows turned out to be simpler than I
thought:

After having executed wglSwapBuffers (effectivily ending the draw-cycle) I
only needed to add a glFinish before attempting to use a TextOut (or other)
GDI calls to draw to the DC.

Adding a call to SetBkMode resulted in the blocks "around the text" being
gone too.

Regards,
Rudy Wieser
Post by R.Wieser
Hello All,
I'm drawing some text using the glCallLists method, and am using the
glRasterPos command to determine where the text should be placed.
1) How do I find out where to start a new line just below the one just drawn
(intention: implementing CRLF)
2) How do I calculate the location of the end of the text I've just drawn
(intention : draw a line with some text colored).
Also: I've been looking a NeHe's tutorials, but do not directly see
anything in relation to a method to create a 2D overlay (so something like
"HUD" text (and maybe 2D graphics) can be easily drawn ontop of the 3D
scene). Is such a method available under OpenGL ?
Regards,
Rudy Wieser
Loading...