The Last Word in Text Rendering

emzic: sorry, you aren’t using the TextRenderer correctly. You need to call beginRendering(int width, int height) before any draw() commands and endRendering() afterward, each frame. Please see the demos.j2d.TestTextRenderer and demos.j2d.FlyingText demos in the jogl-demos workspace. Does doing that make your app work correctly?

All: I’ve notified the forum admin about not being able to see the attachment; hopefully this can be cleared up.

yes, that solves the problem! thanks.

i was looking in the source and i see that these functions also set up a orthogonal projection. the same which i already have for the GUI rendering. and infact, sometimes i dont want to have the orthogonal projection since i want the text to be in the 3d world. do you think it is possible to add functions that allow the user to set up his viewport and projection matrix himself?

So your kind do have a weakness. The time has come for the resistance - rise my comrades, rise up and throw down your false gods!

Do you have a suggestion for what this API would look like? In your app, what do you mean by drawing text in the 3D scene – do you mean drawing text that isn’t screen-aligned, or do you mean drawing screen-aligned text at a certain distance from the near plane so 3D objects occlude it? I think it would be straightforward to add APIs to support the latter case, but I’m not sure what the APIs would look like to support the former, at least without doing more of a higher-level, scene graph style API.

You can already change the modelview and projection matrices after you call TextRenderer.beginRendering(); the FlyingText demo does this. However, the (x,y) coordinates you pass to the draw() command then don’t work as specified – the origin (0, 0) or some other specific point is probably the only point for which you can reason about the on-screen location.

i mean the first case that you described. text can be used to put letters on houses, waypoints or name plates above characters.

as you said i could accomplish this by modifying the projection matrix after the beginRendering() but wouldn’t that be some unnecessary state changes?

and for the api, it could do the texture caching stuff in the draw() function while omitting the viewport and projection at all, so calling beginDraw and endDraw becomes optional if someone doesnt want to use his own setup, but the one provided by these functions. :slight_smile:

Do you have a suggestion for what this API would look like?
In my opinion state pushing and restoring isn’ t necessary in a low level API like JOGL. The method draw(String str, int x, int y) should just draw a String with the offset (x, y) in the current world space with current state. This provides more flexibility (rendering text everywhere in space) and better performance (perhaps the user of the API wants to render more things with the same gl state as the text…).

My suggestion:
-there should be a method beginRendering which just prepares everything to render simple text quads in current gl state
-glPushAttrib and glDisable calles should be moved from beginOrthoRendering and put into the demo app (if needed)
-beginOrthoRendering should call beginRendering after setting up ortho

just my opinion ;D

bienator

It isn’t this simple. The size of the rectangle being drawn in world-space coordinates isn’t as well defined as it is when you’re rendering screen-aligned, unscaled text, which is basically what the TextRenderer class supports.

If you build a prototype and a small demo showing what you have in mind, we’ll be glad to consider including it.

We can separate out the orthographic projection setup, but I’m not sure that doing so really makes sense in the context of this class. The lower-level TextureRenderer can be used for this, though in that case you’d be responsible for the placement of text on the Java 2D managed backing store.

Please help me understand what you want by building a prototype.

You need to do state pushing and popping unless you want to specify that certain OpenGL states (like the current texture binding) are destroyed by certain APIs, which breaks modularity.

The TextRenderer.draw() method does exactly what you state it should do. It’s the beginRendering() / endRendering() methods which push and pop state and modify the projection matrices. Please look at the code.

I’m not in favor of pulling the low-level state setup (binding the background texture, etc.) out of the TextRenderer. There are a couple of things which are absolutely required for correct results such as the binding of the background texture (which is not exposed in the public API for good reason – it can change over time as the backing store grows). The setup of the projection matrices is another question and I’d be glad to rethink this, but I’d appreciate it if you would build a concrete prototype and show me what you have in mind. I don’t know how to specify the behavior of 2D text rotated with an arbitrary 3D orientation in the context of a 3D scene – there are too many potential problems with differing scale factors between the TextRenderer and the surrounding scene and I think the API would become too complex. I think it’s better to use a scene graph like Xith for this case.

I think you got me wrong Ken,

JOGL should not handle the 3d rendering, it should be handled by the application. Just provide additionally to the ortho rendering methods, methods which do not transform or rotate anything - just render the with text textured quads.
This enables you to render the text like emzic said everywhere in the scene without duplicated transformations or changes in the projection matrix.

As I said states I had this in mind:
gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_TRANSFORM_BIT);
gl.glDisable(GL.GL_DEPTH_TEST);
gl.glDisable(GL.GL_CULL_FACE);
gl.glDisable(GL.GL_LIGHTING);
IMO this should be also done by the application. (the Font’s Textures should be of course handled by JOGL)

I will send you the prototype you requested…

dont get me wrong this are just suggestions, i am very happy with the current implementation of JOGL :wink:

What should the width and height of the textured quads (in world coordinates) be?

It’s easy enough to transform screen-coordinated to world-coordinates yourself.

The text is on a plane, just translate/scale/rotate until it fits your needs. (if you render the text at 0,0 it’s easiest)

Let’s say the bounding-rectangle of the text in screenspace is: (0, 0) (250x24)
Normalize vertices to (0, 0) (1x1) by scaling (1/w, 1/h)
As we’re dealing with 3D now, we can as well add the Z (it is 0), (0, 0, 0) (1x1x0)
Which size do we want in world-coordinates? Let’s say: 0x105x11cm, positioned at 143x168x78cm from the origin


glPushMatrix();
glTranslate(1.43f, 1.68f, 0.78f);
glRotatef(90, 0, 1, 0);
glScalef(1.0f, 1.0f/250, 1.0f/24);
glScalef(1.0f, 1.05f, 0.11f);
   renderText();
glPopMatrix();

My basic point is this: what should the specification of the class say about the units in use in this scenario, compared to the orthographic, unscaled case? Do you want to specify a scale factor to be applied to both the width and height of the 3D rectangle? If you don’t specify one (for example, if you normalize the rectangle to size (1, 1)), different lines of text will be rendered with different scales. What exactly should the new draw3D() method take as arguments, and what should the javadoc specification look like?

You don’t normalize (0, 0, xEnd, yEnd) which results into each line having another scale (y axis)
if you normalize (xOff, yOff, xEnd, yEnd) to (0, 0, 1, 1), all lines have the same Y-scale.

The TextRenderer utility-class maybe shouldn’t be too generic?
If people want text in their scene, they probably need 3d text anyway, or if they
want to project it: RTT using TextRenderer without any transformations.

(alpha blended) 2d text in the middle of your scene looks crap anyway.

BTW, bienator, I couldn’t PM you (full inbox? I’ve notified the admin) but send me an email with no attachment if you sent me something and didn’t get a reply. My work email blocks mail with .zip attachments, for example.

A new TextFlow demo has been checked in to the jogl-demos workspace which shows how to do dynamic text layout and how the TextRenderer handles it. A significant number of bug fixes and robustness improvements have gone into the TextRenderer and implementing classes as a side-effect of this, and it hopefully should “just work” in many more cases.

emzic: if you have a chance, could you retry your program with a nightly build dated 1/14 or later? I’d like to make sure I didn’t introduce a bug which impacts your app.

We’ll look into the issue of 2D text placement in 3D soon, hopefully next week.

ok, i will give it a try soon and report back here. thanks for the update!

edit: ok it works. nothing seems to be different as before. is there anything special i should look out for?

No, just making sure nothing was broken. Thanks.

This is exactly what i was looking for, but how good is it? For example, can we render small sharp text with pixel precision like the letters in this post and do you have any screenshots?

A picture is worth a thousand words…

This demo is checked in to the jogl-demos workspace under demos.j2d.TextFlow. On-line web start demos of this and other new stuff are coming.

Thats really Impressive. Congratulations.