(Resolved) BitmapText in scene does not work?

It figures: I try to find a solution for hours, then after I finally post about it I figure it out only half an hour later.

setQueueBucket(RenderQueue.Bucket.Inherit)



Oh well, hopefully this helps someone else out in the future.



(the following is the original post)



I am adding BitmapText objects to my scene, and they are acting as though they are in the guiNode, obeying the ortho projection, even though they are not.



I have a worldNode attached to the rootNode. I have a bunch of objects derived from a type ‘Obj extends Geometry’ in my scene, each Obj having its own, personal local node (in which it is at (0,0,0)), the local nodes being placed in the worldNode where the object needs to reside. I wanted to be able to attach special effects to an object by applying them to its local node.



I wanted every object owned by a player to have a BitmapText representing that player’s name at its location. So every obj has a ‘BitmapText textImage’ which is placed at (0,0,1) in the object’s local node.



When I run the application, normal objects derived from Geometry work as expected, but the BitmapText objects do not; they do not get placed properly. Each object’s textImage is being placed on the screen as though it is in the guiNode. For example, if an object and its local node are at (200,200,z) in the scene, the textImage for that object displays 200 pixels up and 200 pixels right from the corner of the window, and it stays there when the camera moves.



Is this how BitmapText is supposed to behave? Is there a way to force it to behave as I am expecting, being at the desired location in the scene with its object?



(edit)

Almost forgot to say:

I’ve tried searching for the answer, but most of the stuff I find applies to jME2, and I’m not sure it’s relevant. And I found one forum topic in which people suggested figuring out where a point in the scene is on the screen and move text around the gui node to match to keep text above a player’s head, but I have a ton of text objects in the scene so that is less practical, and that doesn’t seem like a good solution anyway since I should be able to just put the text in the scene. I have also seen a little bit of discussion about drawing on a BufferedImage then making that into a Texture (which is actually something else I posted about recently, what a coincidence) to apply to a Picture. But I’m thinking there has to be a practical solution that I’m just not aware of which you guys might be able to reveal. Some setting to change it so the text is just in the perspective projection instead of ortho would be great.

1 Like

I think this behavior is confusing. BitmapText adds itself to the Gui bucket by default but I don’t think this is intuitive or necessary since it should inherit that from the guiNode if it was actually part of the gui.



I’ve removed that in my local version and text seems to still work ok… I’m just waiting for confirmation that my understanding of buckets is correct before committing it.

Yeah, so I fixed this. BitmapText will now automatically inherit the bucket from the parent. It should go into the next nightly build.



I was about to run into this myself with Mythruna since I want to show the networked player’s names above their heads. Fortunately, someone else was kind enough to stumble over it before I did. :slight_smile:

pspeed said:
I'm just waiting for confirmation that my understanding of buckets is correct before committing it.


I am somewhat new to jMonkey, but I have been using vanilla OpenGL in C++ for a while. Based on my understanding of OpenGL combined with the naming scheme jMonkey uses here, I would assume that this is a scheme where the jMonkey engine traverses the scene graph and decides how to render everything, but instead of rendering on the spot it adds all of its decisions into queues that represent the OpenGL state.

So when jMonkey sees the BitmapText instance and decides that it should be rendered with an ortho projection it tosses it into "the gui bucket," then when it gets around to rendering everything at once it just iterates through the contents of each bucket, then it only has to change the OpenGL state a few times instead of continually doing end/begin and changing between every object.

That is just a guess, but it makes sense to me.

That is, it makes sense that the buckets work in the above-mentioned fashion. Having the text default to the gui bucket does not make sense, so I agree with you.

Yes, that is all logical and also my experience with scene graphs. However, bitmap text in particular sometimes defies logic. :wink:

I still don’t really understand what the solution is here. Does simply specifying:



[java]setQueueBucket(RenderQueue.Bucket.Inherit)[/java]



… allow text to be rendered in the scene?

Well… I just tested it and answered my own question. Thanks for this thread!

Here is what I did:



[java]

BitmapFont font = assetManager.loadFont(“Interface/Fonts/Default.fnt”);

BitmapText helloText = new BitmapText(font, false);

helloText.setSize(font.getCharSet().getRenderedSize());

helloText.setText(“Hello World”);

helloText.setLocalTranslation(0, helloText.getLineHeight(), 0);

helloText.setQueueBucket(Bucket.Inherit);

rootNode.attachChild(helloText);

[/java]



Does that make sense? I mean, it renders, but I can’t control the color of the text nor the background color. So it’s just white text on black boxes right now.

Update to a recent nightly build. It sounds like you are running old alpha 4 jme.



I mean, I’m guessing because: a) bitmap text now is Bucket.Inherit by default and b) I fixed a bug where you could only set color at a specific time (before or after setting the text, I don’t remember).