LibGDX 使用视口时的 Box2D 矩阵渲染问题

LibGDX Box2D matrix rendering question when using viewports

我有一个关于使用 box2d 和 libgdx 渲染的问题。 正如您在下面的屏幕截图中看到的,我在更改 window 分辨率时遇到了问题。

Box2d 在整个屏幕上缩放,尽管视口只使用了它的一小部分。灯光也被缩放并且不再匹配真实位置(但我认为这与同一问题有关)。

我的想法是我需要在渲染之前以某种方式调整 box2d 的矩阵 (b2dCombinedMatrix),但我不知道如何。

我个人认为我需要告诉它它应该使用与视口相同的 "render boundaries" 但我不知道该怎么做。

这里是渲染方法(问题在绘图灯评论部分之后):

public void render(final float alpha) {
    viewport.apply();

    spriteBatch.begin();
    AnimatedTiledMapTile.updateAnimationBaseTime();
    if (mapRenderer.getMap() != null) {
        mapRenderer.setView(gameCamera);
        for (TiledMapTileLayer layer : layersToRender) {
            mapRenderer.renderTileLayer(layer);
        }
    }

    // render game objects first because they are in the same texture atlas as the map so we avoid a texture binding --> better performance
    for (final Entity entity : gameObjectsForRender) {
        renderEntity(entity, alpha);
    }
    for (final Entity entity : charactersForRender) {
        renderEntity(entity, alpha);
    }
    spriteBatch.end();

    // draw lights
    b2dCombinedMatrix.set(spriteBatch.getProjectionMatrix());
    b2dCombinedMatrix.translate(0, RENDER_OFFSET_Y, 0);
    rayHandler.setCombinedMatrix(b2dCombinedMatrix, gameCamera.position.x, gameCamera.position.y, gameCamera.viewportWidth, gameCamera.viewportHeight);
    rayHandler.updateAndRender();
    if (DEBUG) {
        b2dRenderer.render(world, b2dCombinedMatrix);
        Gdx.app.debug(TAG, "Last number of render calls: " + spriteBatch.renderCalls);
    }
}

这是将视口向上移动 4 个世界单位的调整大小方法:

public void resize(final int width, final int height) {
    viewport.update(width, height, false);
    // offset viewport by y-axis (get distance from viewport to viewport with offset)
    renderOffsetVector.set(gameCamera.position.x - gameCamera.viewportWidth * 0.5f, RENDER_OFFSET_Y + gameCamera.position.y - gameCamera.viewportHeight * 0.5f, 0);
    gameCamera.project(renderOffsetVector, viewport.getScreenX(), viewport.getScreenY(), viewport.getScreenWidth(), viewport.getScreenHeight());
    viewport.setScreenY((int) renderOffsetVector.y);
}

经过几个小时摆弄矩阵,我终于让它工作了但是实际上有一个非常简单的方法可以解决我的问题:D

基本上 rayhandler 的渲染方法一直在搞乱我的矩阵计算,原因是我没有告诉它使用自定义视口。

所以将调整大小的方法调整为这个

public void resize(final int width, final int height) {
    viewport.update(width, height, false);
    // offset viewport by y-axis (get distance from viewport to viewport with offset)
    renderOffsetVector.set(gameCamera.position.x - gameCamera.viewportWidth * 0.5f, RENDER_OFFSET_Y + gameCamera.position.y - gameCamera.viewportHeight * 0.5f, 0);
    gameCamera.project(renderOffsetVector, viewport.getScreenX(), viewport.getScreenY(), viewport.getScreenWidth(), viewport.getScreenHeight());
    viewport.setScreenY((int) renderOffsetVector.y);

    rayHandler.useCustomViewport(viewport.getScreenX(), viewport.getScreenY(), viewport.getScreenWidth(), viewport.getScreenHeight());
}

并将渲染方法简化为

 // draw lights
    rayHandler.setCombinedMatrix(gameCamera);
    rayHandler.updateAndRender();
    if (DEBUG) {
        b2dRenderer.render(world, b2dCombinedMatrix);
        Gdx.app.debug(TAG, "Last number of render calls: " + spriteBatch.renderCalls);
    }

解决了我的问题。

也许我很笨,但我在任何文档中都没有找到 useCustomViewport 方法。 总之,解决了!