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

时间:2018-09-24 18:26:50

标签: matrix libgdx rendering box2d offset

我有一个关于使用box2d和libgdx渲染的问题。 正如您在下面的屏幕快照中看到的那样,更改窗口分辨率时出现问题。

Box2d会在整个屏幕上缩放,尽管视口只使用了一小部分。另外,灯光会缩放,不再与实际位置匹配(但是我认为这与同一问题有关)。

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

我个人认为我应该告诉它应该使用与视口相同的“渲染边界”,但是我不知道该怎么做。

这里是render方法(问题在“绘制灯光注释”部分之后):

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

Unscaled

Scaled image

1 个答案:

答案 0 :(得分:0)

经过数小时的摆弄之后,我终于使它起作用了。但是实际上,有一个非常简单的解决方案可以解决我的问题:D

基本上,光线处理器的render方法一直困扰着我的矩阵计算,原因是我没有告诉它使用自定义视口。

因此将调整大小方法调整为此

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 方法。 无论如何,解决了!