简体   繁体   中英

Libgdx Rendering Bitmap font to pixmap texture causes extremely slow rendering

I'm using libgdx scene2d to render 2d actors. Some of these actors 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:

    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);

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, affect 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?

I have not tested this, but I think you can enable culling for the whole Stage by setting its root view to use a cullingArea matching the world width and height of the viewport. I would do this in resize after updating the Stage Viewport just in case the update affects the world width and height of the viewport.

@Override
public void resize(int width, int height) {
    //...
    stage.getViewport().update(width, height, true);
    stage.getRoot().setCullingArea(
        new Rectangle(0f, 0f, stage.getViewport().getWorldWidth(), stage.getViewport().getWorldHeight())
    );
}

It will only be able to cull Actors that have their x, y, width, and height set properly. This is true I think of anything in the scene2d UI package, but for your own custom Actors you will need to do it yourself.

If a child of your root view is a Group that encompasses more than the screen and many actors, you might want to cull its children, too, such that even if the group as a whole is not culled by the root view, the group can still cull a portion of its own children. To figure out the culling rectangle for this, I think you would intersect a rectangle of the group's size with the viewport's world size rectangle offset by -x and -y of the group's position (since the culling rectangle is relative to the position of the group it's set on).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM