FBO纹理显示为完全黑色

时间:2015-11-17 15:24:37

标签: java opengl glsl lwjgl texturing

我正在尝试关注ThinMatrix's water tutorial。为此,我需要创建一个FBO并将其渲染为纹理。

然而,正如您所看到的,水是完全黑色的: enter image description here

我直接使用教程中的source code provided(从链接中复制)。

基本上,我创建了一个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);

我无法找出错误的原因,以及为什么纹理没有显示任何渲染的内容。

我知道的事情错误:

我肯定正确地绘制和纹理水本身。我可以使用任何预先加载的纹理和纹理水就好了: enter image description here

此外,渲染到FBO的对象具有正确的平移,旋转等。如果我没有绑定任何帧缓冲区,则在我的屏幕上正确绘制(和看到)用于FBO的树叶。

1 个答案:

答案 0 :(得分: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());
    }

可能不是同一个问题,因为我的错误特别简单,但是值得一试。

有人知道此解决方案是否正确,还是对更大的问题有帮助?