0
\$\begingroup\$

Im using libgdx scene2d to render 2d actors. Some of these actor groups originally included scene2d Label actors for rendering static text. The Labels work fine but drawing ~20 of them on the screen at once drops the frame rate by 10-15 frames, resulting in noticeably poor rendering while dragging.

I'm attempting to avoid the Labels by pre-drawing the text to textures, and rendering the textures as scene2d Image actors. I'm creating the texture using the code below. (Inspired by Libgdx FPS drop drawing alot of text)

I assumed, and have read, that textures are often faster. However when I replaced the Labels with the texture, it had the same, if not worse, effect on the frame rate. Oddly, I'm not experiencing this when adding textures from a file, which makes me think I'm doing something wrong in my code. Is there a different way I should be pre-rendering these pieces of text?

BitmapFont font =  manager.get(baseNameFont,BitmapFont.class);
GlyphLayout gl = new GlyphLayout(font,"Test Text");

int textWidth = (int)gl.width;
int textHeight = (int)gl.height;
LOGGER.info("textHeight: {}",textHeight);
//int width = Gdx.graphics.getWidth();
int width = textWidth;
//int height = 500;
int height = textHeight;

SpriteBatch spriteBatch = new SpriteBatch();

FrameBuffer m_fbo = new FrameBuffer(Pixmap.Format.RGB565, width,height, false);
m_fbo.begin();
Gdx.gl.glClearColor(1f,1f,1f,0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Matrix4 normalProjection = new Matrix4()

        .setToOrtho2D(0, 0, width,  height);
spriteBatch.setProjectionMatrix(normalProjection);

spriteBatch.begin();

font.draw(spriteBatch,gl,0,height);


spriteBatch.end();//finish write to buffer

Pixmap pm = ScreenUtils.getFrameBufferPixmap(0, 0, (int) width, (int) height);//write frame buffer to Pixmap

m_fbo.end();

m_fbo.dispose();
m_fbo = null;
spriteBatch.dispose();

Texture texture = new Texture(pm);
textTexture = new TextureRegion(texture);
textTexture.flip(false,true);
manager.add(texture);
\$\endgroup\$
4
  • \$\begingroup\$ Can you show any more details about how you go about drawing your labels and when and how you are creating them? You shouldn't see a noticable performance impact at 20 Labels unless they have extremely long text, thousands of Labels should run just fine even on a modest computer. \$\endgroup\$
    – bornander
    Commented Dec 9, 2021 at 15:41
  • \$\begingroup\$ I've just been informed by another user that libgdx does not automatically cull actors that are outside the viewport, despite seeing multiple other comments that say it does. So this may actually be part of the issue. This would mean 100+ labels are being "drawn" though only 20 of them are visible in the viewport. I can't find a good tutorial on how to get the culling area from the camera frustum though. \$\endgroup\$ Commented Dec 9, 2021 at 15:47
  • \$\begingroup\$ Still, thousands of labels on or off screen shouldn't be an issue. So it would still be interesting to see how you do it, @The Shoe Shiner. \$\endgroup\$
    – bornander
    Commented Dec 9, 2021 at 17:05
  • \$\begingroup\$ @bornander I think it would be if Libgdx had to call draw() on each of them. Label.draw() is a relatively expensive operation. The constructor you see above is all I'm doing. Libgdx handles drawing the Labels when they are added to an Actor within a Stage. \$\endgroup\$ Commented Dec 9, 2021 at 18:08

1 Answer 1

2
\$\begingroup\$

The cause of this slowness was my misunderstanding about Libgdx culling. Scene2d does not automatically cull objects outside of the view frustum. Therefore my hundreds of shapes and labels were having draw() called when they weren't even visible in the camera. My short term fix for this was that I test whether an object is within the frustum during draw(), and as soon it's not visible I call setVisible(false) which tells GDX to skip the draw. I think a more elegant solution would be to set the culling area on the stage, but I would need to adjust it as the user pans the camera. I have not tested this since I've gotten past my current performance issues, but I believe it should work.

The answer comes from the same question on StackOverflow.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .