TextRenderer & TileRenderer Weird Problem Solved

I’d like to use TileRenderer to create huge screenshots. I also use TextRenderer in my display method
to draw labels. Do TileRenderer and TextRenderer work together or do they disturb each other in terms
of the projection matrix??? Any experience what the maximum size of a screeshot might be???

Thanks for your answers!

I don’t know about the TextRenderer (although I would be very surprised if it was incompatible with tile rendering), but the maximum image size of a tile-rendered screenshot depends, I suppose, on how much hard disk space you have left. :slight_smile:

The flies in the ointment that is tile-rendering are GL_LINE* and GL_POINTS. Their width is measured in pixels and is thus resolution-dependent, and you need to specify a border on the tiles so that they are not incorrectly clipped.

The TextRenderer’s beginRendering() and endRendering() methods do modify the projection matrix, but if you can figure out how to use begin3DRendering() / end3DRendering() instead then it should “just work” with the TileRenderer. Experiment a little with it and post to tell us what you found.

Well, I tried to call something like

draw3D("some label", x, y, 0, viewPort.width / component.getWidth()); 

This basically gives me labels with correct position and size. However, I loose crispness of
labels, which is crucial for my app. Any suggestions how I can achieve crisp labels even
when using draw3D() ??? Thanks!!!

Increase the font size and decrease the scale factor of the quad you use to draw the text.

ken, cough mipmapping cough cough

:wink: ;-D

I don’t think this is that problem. Remember that he’s making huge screenshots and that what is happening is that the same number of pixels for the drawn text are being stretched over an area covering more pixels in the screenshot.

Hi, it’s the TextRenderer stress maker again!

It literally took me a while to figure out how to combine crisp text rendering (via TextRenderer) and
generating huge screenshots (via TileRenderer). The problem for my specific case is that I have
to render a scene in world coordinates, but for me it is mandatory to render text in pixel coordinates.
Only that way I achieve crisp labels and can assure that labels have the same size in a huge
screenshot (say 8000x8000) and on screen! To create huge screenshots I use the TileRenderer
class. However, since I combine world coordinates rendering (of the scene) and pixel cooridinates
rendering (of the labels), I have to pay special attention to the tiling process.

In any case, I figured out how this works; my scene is always tiled correctly!
BUT, I discovered a strange problem that drove me nuts!!! When I render a few (depends on tile size
and screenshot size) labels to a huge tiled screenshot everything works out well. BUT, when I have
to render more and more labels, some appear in tiles where they should not be and labels that
should be on a tile are not shown!

Since that behavior seemed a bit non-deterministic, I blamed it to the TextRenderer. To support that
hypothesis I added code that draws a simple GL_POINT directly where a label is supposed to appear.
Interestingly, both labels AND points show the same weird erroneous behavior! Since rendering of a
label is independent from rendering a point, I would have expected that at least the points appear
correctly! So, the call to the TextRenderer’s draw(…) method must be the problem. And yes, when I
comment out just the calls to that method, then ALL points are drawn correctly. There must be a problem
with the call of draw(…). It seems the problem also depends on length of labels.

I created a test case, so that you can reproduce my problem. The test case simply shows a torus (the
scene in world coordinates) and draws a circle of labels (and points) (in pixel coordinates).
You can press ‘x’ to render a large tiled screenshot (several .png files will be generated in the working directory).
You will see that the tiles do not have correct labeling!!! You can press ‘l’ to disable calls to draw(…) and
take a new screenshot. Then you will see that all points are rendered correctly!!! You can also use
‘+’ and ‘-’ to inc/decrease the number of labels (recall that fewer labels do not cause the mentioned problem).

Bottom line: My impression is that there is something wrong either with the way I use the TextRenderer or with the
TextRenderer itself. I would very much appreciate if anyone could reproduce the behavior I described above.

I have tested on WindowsXP and Linux and ATI and NVIDIA! I use the latest jogl runtime!

Attached are two tiles. One shows that label positions are correct, but calls to draw(…) have to be disabled
to get to this correct rendering. Once calls to draw(…) labels are shown, BUT labels AND points disappear
somehow??!!! The test case is attached too.

I mentioned above that TextRenderer.beginRendering() and TextureRenderer.beginRendering() do modify the projection matrix using glOrtho, which is incompatible with the TileRenderer. You need to switch to using begin3DRendering() instead. You can probably still render your text in pixel coordinates, but you’ll need to manually set up the projection matrix using the TileRenderer after calling begin3DRendering().

Thanks for the reply Ken. Yes, I know that TextRenderer alters the projection matrix. Nonetheless, I figured out how to
adjust things after calling beginRendering() such that theoretically labels can be rendered correctly. And it works fine
if I render only few labels. Please take a look at the test case provided. You will see that it is possible to combine
TextRenderer and TileRenderer. However, you will also see that calls to draw(…) will cause a problem.

I’ll try to make it more clear:


beginRendering() // Enter rendering phase for labels
if (renderScreenShot) adjustMatrices() // Adjust matrices such that label are theoretically drawn correctly

for (label in labels) {
  draw(x, y, label)  // draw a label
  glPoint(x, y)      // draw a point
}

if (renderScreenShot) undoAdjustments() // Restore things that have been changed
endRendering() // Finish rendering phase for labels

What I expect from the pseudo-code above is that it renders points AND labels. Indeed it does
this up to a certain: number of labels, tile size, image size, or label length. That is, if any of these
exceed certain limits, neither labels NOR points appear where they are supposed to appear. When
I comment out the call to draw(), the points are rendered correctly. This implies that in theory everything
should work fine. It also implies that the call to draw() must have some disastrous side effects that
even affect the rendering of simple GL_POINTS!!!

The basic question is: Why does my test case only work until certain limits are reached. Or put it
differently, what causes my approach to fail after the limits have been reached???

TextRenderer.draw() may need to destroy and re-create the backing TextureRenderer as strings are rendered. If this happens, it will call beginRendering() or begin3DRendering() as needed (depending on which one was called originally) to set up the newly-created TextureRenderer. This will destroy the fixups you’re doing after calling beginRendering() yourself. Note that there is no interposition point where you can add this code, since at least one draw() command will complete and place the label in the wrong position before you get a chance to hack the modelview matrix.

The best solution is for you to switch to using begin3DRendering() and either specify the locations of your labels in 3D in your app or use gluUnProject() to compute a 3D point at which to render these labels.

Thank you very much for this enlightening post. I wasn’t aware of the
fact that beginRendering() might be called again at some point. So what
I do now is I do not longer tamper with the matrices, but adjust the label
positions manually, I have to compute their positions anyhow. Everything
works nice and smooth now!

Combining TextRenderer and TileRenderer works, even when world coordinate
scene rendering and pixel coordinate text rendering are combined !!!

Thanks a lot!!!

P.S.: Maybe it makes sense to add a note to the TextRenderer’s javadoc to make
users aware that altering matrices after calling beginRendering() should be avoided!

Glad things are working for you. I’ve added a note to the TextRenderer’s overview javadoc on using it in conjunction with the TileRenderer.