需要帮助来优化LibGDX,SpriteBatch上的纹理绘制

时间:2019-05-31 19:07:17

标签: libgdx spritebatch

我正在使用LibGDX将我的游戏Hold and Drag从Swift(SpriteKit)转换为Android,我创建了'SpriteKit'API,该API与Xcode上的官方版本相同。

我正在寻找优化纹理渲染的方法,特别是因为我得到了FPS下降(45-60 / 60 fps) 当我不绘制纹理时,我得到60(最大值)。

我希望你能尽可能有效地帮助我!

@Override
public void draw() {
    if (texture == null)
        return;

    Gdx.gl.glEnable(GL20.GL_BLEND);
    Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

    spriteBatch.setTransformMatrix(getTransformMatrix());
    spriteBatch.begin();
    Color color = spriteBatch.getColor();
    color.a = getAlpha();
    spriteBatch.setColor(color);
    spriteBatch.draw(texture, -size.width / 2, -size.height / 2, size.width, size.height);
    spriteBatch.end();

    Gdx.gl.glDisable(GL20.GL_BLEND);
}
public List<SKNode> getParents() {
    List<SKNode> parents = new ArrayList<>();
    if (parent != null) {
        parents.add(parent);
        parents.addAll(parent.getParents());
    }
    return parents;
}

public Matrix4 getTransformMatrix() {
    List<SKNode> nodes = getParents();
    Collections.reverse(nodes);
    nodes.add(this);

    Matrix4 transformMatrix = new Matrix4();
    transformMatrix.idt();
    for (SKNode node : nodes) {
        transformMatrix.translate(node.position.x + node.origin.x, node.position.y + node.origin.y, 0);
        transformMatrix.rotate(0, 0, 1, node.zRotation);
        transformMatrix.scale(node.xScale, node.yScale, 0);
        transformMatrix.translate(-node.origin.x, -node.origin.y, 0);
    }

    return transformMatrix;
}

1 个答案:

答案 0 :(得分:2)

执行导致“精灵”批处理“刷新”的操作很慢,这意味着它必须发出大量OpenGL命令并传输顶点数据等。在调用spriteBatch.end()时也会发生刷新发生以下情况:

  • 绘制与最后绘制的纹理实例不同的纹理
  • 更改投影或变换矩阵
  • 启用/禁用混合

因此,您要进行组织,以免在绘制的每个对象上触发冲洗。通常要做的是开始批处理,然后使用包含所有所需参数的spriteBatch.draw()方法之一在其特定位置绘制每个精灵。像这样:

batch.setProjectionMatrix(camera.combined);
batch.begin();
for (GameObject obj : myGameObjects)
    obj.draw();
batch.end();

//And in your game object / sprite class
public void draw() {
    if (texture == null)
        return;
    spriteBatch.setColor(1f, 1f, 1f, getAlpha());
    spriteBatch.draw(texture, -size.width / 2, -size.height / 2, size.width, size.height);
}

请注意,以上假设假定您在每个对象中都引用相同的sprite批处理实例。

现在,要使其表现得更像SpriteKit(我假设是因为我没有使用过),所以每个对象都需要转换。但是您不想呼叫setTransformMatrix,否则将触发刷新。相反,您可以使用Affine2类而不是Matrix4。它也可以用于保存2D对象的变换数据。然后,您可以使用spriteBatch.draw(textureRegion, width, height, affine2Transform)绘制它而不会触发冲洗。

为避免触发使用不同纹理实例的冲洗,应使用TextureAtlas和纹理区域。您可以在其Wiki上的LibGDX文档中阅读有关内容。

此外,使用SpriteBatch时,不需要进行OpenGL调用即可启用和禁用混合。这是由SpriteBatch在内部处理的。请致电spriteBatch.enableBlending()