如何正确使用LIBGDX FrameBuffer

问题描述 投票:0回答:1

这是我的第一个问题。我试图查看源代码(link)搜索stackoverflow并阅读一些常规说明。但是我对如何正确设置(或理解)它没有任何明智的认识。

我不了解投影矩阵或许多GL术语。我不知道当您设置相机(camera.setToOrtho())时应该更新相机时会发生什么或何时设置批次的投影矩阵。到目前为止,我对此的唯一使用仅限于下面所示的draw()方法中使用的代码。

我有一个带有图层的基于图块的游戏。我想使用FrameBuffer将水层绘制到TextureRegion。因此,我以后可以尝试使用着色器对其进行操作。我认为这就是做到这一点的方法。

(我没有使用任何“ Scene2d”或“ Tiled”类)

Example of what the layer looks like

我如何绘制图层:

public void draw(OrthographicCamera camera) {

        Gdx.gl.glClearColor(0, 0, 0, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA,GL20.GL_ONE_MINUS_SRC_ALPHA); // [1]
        BATCH.setProjectionMatrix(camera.combined);
        BATCH.begin();

        for (int i = 0; i < NUM_LAYERS; i++) {
            if (RENDER[i]) {
                if (SORT[i]) Collections.sort(LAYERS.get(i));
                for (DrwDat dat: LAYERS.get(i)) {                           // [2]
                    dat.draw(BATCH);
                }
            }
        }
        BATCH.end();
    }

1。不知道这是什么,但我似乎不需要它。[2]。 DrwDat只是一个包含可绘制对象的类。在这种情况下,这些是图块。

好因此,在绘制循环中,我放置了一个在绘制水层时要调用的方法。目前我想绘制应该在屏幕上显示的每个图块,然后将它们绘制到缓冲区。然后:在屏幕上绘制缓冲区。

问题:我可以在下面的“ renderFBO()”方法中添加什么以使其起作用?又为什么呢要基本上让屏幕准确显示它的显示内容,而无需使用FrameBuffer

(当前代码纯属绝望,是这样,因为我尝试使用YouTube教程作为模板,但不了解。)

private void renderFBO(OrthographicCamera camera, int layer) {
        BATCH.end();
        frameBuffer.begin();
        Gdx.gl.glClearColor(0, 0, 0, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);


        BATCH.begin();

        camera.setToOrtho(false);
        camera.position.set(FocusPoint.position.x,FocusPoint.position.y,0);  // [3]
        camera.update();
        BATCH.setProjectionMatrix(camera.combined);

        for (DrwDat dat: LAYERS.get(layer)) {
            dat.draw(BATCH);
        }

        frameBuffer.end();                                                             // [4]
        BATCH.end();
        camera.setToOrtho(false);

        //BATCH.setProjectionMatrix(camera.combined);
        BATCH.begin();
        BATCH.draw(bufferTexture.getTexture(),0,0,Settings.SCREEN_W,Settings.SCREEN_H);
        BATCH.end();

        camera.position.set(FocusPoint.position.x,FocusPoint.position.y,0);
        camera.update();
        BATCH.setProjectionMatrix(camera.combined);

        BATCH.begin();

}

[3]。 FocusPoint只是相机所要跟踪的一个点(例如:鼠标单击位置)

[4]。由于某些原因,在batch.end()下面有framebuffer.end()不会呈现任何内容。

这是我初始化FrameBuffer的方式:

private FrameBuffer frameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888,Settings.SCREEN_W,Settings.SCREEN_H,false);
private TextureRegion bufferTexture = new TextureRegion(frameBuffer.getColorBufferTexture());

很抱歉,如果这太笼统了。但是任何帮助都值得赞赏。我能读到的任何提示也会非常有帮助。

libgdx framebuffer
1个回答
0
投票

我现在没有很多时间来调试您的长renderFBO方法,但是这是我将FBO内容呈现到屏幕的方式。就像您的方法一样,它可以在中断batch.begin()batch.end()之间完成的现有图形的前提下工作。

private final Matrix4 idt = Matrix4();

public void renderWaterFBO(FrameBuffer fbo, Batch batch) {
    // Store the current Batch state for things we're going to temporarily change.
    Matrix4 originalMatrix = batch.getProjectionMatrix();
    ShaderProgram originalShader = batch.getShaderProgram();

    /* When you have a custom shader, here's where you would prepare it.
    batch.setShader(waterFboShader);
    waterFboShader.setUniformf("u_someUniformAttribute", someUniformAttribute);
    etc.
    */

    batch.setProjectionMatrix(idt); // Identity matrix makes it easy to draw a fullscreen rect.
    batch.draw(fbo.getColorBufferTexture(), -1, 1, 2, -2); // Dimensions to the corners of the screen when using an identity matrix for projection. Negative height to flip vertically. (OpenGL image space and world space have opposite Y directions for some reason.)

    // Restore state from before this method was called.
    batch.setShader(originalShader);
    batch.setProjectionMatrix(originalMatrix);
}

请注意,您不必在批处理上调用end()begin(),因为当您更改着色器或投影矩阵时,它将自动刷新其内容。

© www.soinside.com 2019 - 2024. All rights reserved.