-1

ThinMatrix の水のチュートリアルに従おうとしています。これを行うには、FBO を作成し、テクスチャとしてレンダリングする必要があります。

ただし、ご覧のとおり、水は完全に真っ黒です。 ここに画像の説明を入力

チュートリアルから直接提供されたソース コードを使用しています (リンクからコピー)。

基本的に、FrameBuffer を作成します。

public FrameBufferObject() {//call when loading the game
    initialiseReflectionFrameBuffer();
    initialiseRefractionFrameBuffer(); //Let's ignore refraction for now, as I only use reflection at the moment.
}
private void initialiseReflectionFrameBuffer() {
    reflectionFrameBuffer = createFrameBuffer();
    reflectionTexture = createTextureAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
    reflectionDepthBuffer = createDepthBufferAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
    unbindCurrentFrameBuffer();
}

次に、テクスチャ アタッチメントを作成します。

private int createTextureAttachment( int width, int height) {
    int texture = GL11.glGenTextures();
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
    GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height,
            0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
    GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0,
            texture, 0);
    return texture;
}

また、深度バッファ アタッチメントも作成します。

private int createDepthBufferAttachment(int width, int height) {
    int depthBuffer = GL30.glGenRenderbuffers();
    GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
    GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_DEPTH_COMPONENT, width,
            height);
    GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT,
            GL30.GL_RENDERBUFFER, depthBuffer);
    return depthBuffer;
}

次に、オブジェクトをフレーム バッファー オブジェクトにレンダリングします。

Main.TerrainDemo.shader.start();
    fbos.bindReflectionFrameBuffer();
    for (Grass g : Main.TerrainDemo.toDraw){
        g.render();
    }
    fbos.unbindCurrentFrameBuffer();

次のようにフレーム バッファをバインドします。

private void bindFrameBuffer(int frameBuffer, int width, int height){
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
    GL11.glViewport(0, 0, width, height);
    System.out.println("Bound");
    if(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) == GL30.GL_FRAMEBUFFER_COMPLETE) {
        System.out.println("Frame buffer setup is complete: " + GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER));
    }
    System.out.println("Error: " + GL11.glGetError());
}

glGetError() を出力したときの「エラー」は正常0です。「フレーム バッファ セットアップ」メッセージは出力されます。

その後、呼び出しfbos.getReflectionTexture()によってテクスチャ ID が返されることを期待しています...そして、そうです! 正常にテクスチャ ID 12 を返します。ただし、バインドしたときのテクスチャは真っ黒です。

public int getReflectionTexture() {//get the resulting texture
    return reflectionTexture; //Remember, this was our original texture attachment.
}
 reflectionTexture = createTextureAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);

何が問題なのか、テクスチャにレンダリングされたものが表示されない理由がわかりません。

私が知っていることは間違っていません:

私は間違いなく水自体を正しく描画し、テクスチャリングしています。プリロードされたテクスチャを使用して、水をうまくテクスチャリングできます。 ここに画像の説明を入力

また、FBO にレンダリングされるオブジェクトには、正しい移動、回転などがあります。フレーム バッファをバインドしないと、FBO 用のフォリッジが画面に正しく描画 (および表示) されます。

4

1 に答える 1

1

だから、これはおそらくもう誰も気にしない超古い質問だと思いますが、最近、同じチュートリアルを実行して同様の問題を抱えていることに気づきました。

Google foo を少し試してみたところ、コードに非常に基本的なエラーがあり、同じ解決策になる可能性があることに気付きました。

私は単にやっていませんでした。

GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

これは、再びいっぱいになる前に、使用されているフレーム バッファ オブジェクトでした。

私は先に進んで、フレームバッファ関数のバインドの最後に置いたところ、うまくいきました!

 private void bindFrameBuffer(int frameBuffer, int width, int height){
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
        GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
        GL11.glViewport(0, 0, width, height);
        System.out.println("Bound");
        if(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) == GL30.GL_FRAMEBUFFER_COMPLETE) {
            System.out.println("Frame buffer setup is complete: " + GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER));
        }
        System.out.println("Error: " + GL11.glGetError());
    }

私のエラーが特に基本的だったので、同じ問題ではないかもしれませんが、試してみる価値があります。

この解決策が正しいか、それともより大きな問題に対するバンドエイドであるかを誰かが知っていますか?

于 2020-06-09T10:17:08.667 に答える