【问题标题】:OpenGL - Why does my fbo/texture remain black?OpenGL - 为什么我的 fbo/纹理保持黑色?
【发布时间】:2015-02-19 10:07:23
【问题描述】:

*我一直在尽最大努力使用 OpenGL 的帧缓冲和来自 Java 的 LWJGL 库来实现可渲染的纹理功能。但是,我总是得到的结果是 100% **black ** 纹理。*

我只是想就问题所在寻求一些建议。我没有渲染任何特定的形状。我绑定生成的帧缓冲区并调用glClearColor(1, 0, 0, 1);,然后调用glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);,然后取消绑定帧缓冲区。但是当我尝试渲染绑定到帧缓冲区的纹理时,纹理只显示黑色,实际上应该是红色的,对吧?

另外,glCheckFramebufferStatus() 返回GL_FRAMEBUFFER_COMPLETE,所以我认为错误出在渲染部分,而不是初始化阶段。但无论如何我都会展示初始化代码。

初始化代码:

public RenderableTexture initialize(int width, int height, int internalFormat, int[] attachments, boolean useDepthBuffer) {
    if(!GLContext.getCapabilities().GL_EXT_framebuffer_object) {
        System.err.println("FrameBuffers not supported on your graphics card!");
    }

    this.width = width;
    this.height = height;
    hasDepthBuffer = useDepthBuffer;

    fbo = glGenFramebuffers();
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    id = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, id);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer) null);


    if(useDepthBuffer) {
        rbo = glGenRenderbuffers();
        glBindRenderbuffer(GL_RENDERBUFFER, rbo);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
    }

    glFramebufferTexture2D(GL_FRAMEBUFFER, attachments[0], GL_TEXTURE_2D, id, 0);

    int[] drawBuffers = new int[attachments.length];

    for(int i = 0; i < attachments.length; i++)
        if(attachments[i] == GL_DEPTH_ATTACHMENT)
            drawBuffers[i] = GL_NONE;
        else
            drawBuffers[i] = attachments[i];

    glDrawBuffers(Util.toIntBuffer(drawBuffers));

    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        System.err.println("Warning! Incomplete Framebuffer");
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    return this;
}

internalFormat 的值是 GL_RGBA8widthheight 的值是 512 和 512。attachments[] 仅包含 1 个值,即 GL_COLOR_ATTACHMENT0useDepthBuffer 设置为 true

上面的代码只被调用一次。

这是渲染代码:

public RenderManager draw() {
    glClearColor(bg.x, bg.y, bg.z, bg.w);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    texture.bindAsRenderTarget(true);
    texture.releaseRenderTarget();
    quad.draw();

    return this;
}

我将清除颜色设置为黑色(0, 0, 0, 1),然后清除屏幕。然后我打电话给texture.bindAsRenderTarget(true);texture 对象包含上面的 initialize 方法,因此该方法和 bindAsRenderTarget() 之间共享一些变量。

这个方法看起来像这样:

public RenderableTexture bindAsRenderTarget(boolean clear) {
    glViewport(0, 0, width, height);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
    glClearColor(1, 0, 0, 1f);
    if(clear)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    return this;
}

如您所见,我将视口调整为纹理/帧缓冲区的大小。然后我绑定帧缓冲区并将清除颜色设置为红色。然后,由于我在渲染代码中传递了true,它(我相信)将当前绑定的帧缓冲区清除为红色。

texture.releaseRenderTarget(); 调整视口以适应显示,然后调用glBindFramebuffer(GL_FRAMEBUFFER, 0);

最后一行代码quad.draw();简单地将绑定到帧缓冲区的纹理的textureID绑定,然后用它绘制一个简单的四边形。

差不多就这些了。

我可以向您保证,我正在正确渲染四边形,因为我可以将从 PNG 文件加载的纹理绑定到它并且纹理已成功显示。

所以为了清楚起见,主要问题是:

到底为什么纹理在透明后是黑色的,因为它应该是红色的?我在哪里做错了什么?

编辑:我感觉这可能与不同 gl ojects 的边界有关。渲染缓冲区是否必须在渲染点绑定到它的帧缓冲区?不是吗?有关系吗?质感怎么样?他们应该在什么时候?

【问题讨论】:

  • 当您完成绘制到帧缓冲区纹理并解除绑定帧缓冲区后,在您想再次渲染到后台缓冲区之前,请尝试 glDrawBuffer(GL_BACK);
  • 感谢罗宾逊的回答 :) 不幸的是,这并没有解决问题。问题可能在于 fbo 渲染而不是后台缓冲区渲染。
  • 嗯,从您的代码中不清楚问题是否实际上是渲染进入纹理/FBO,或者是否将纹理渲染到默认帧缓冲区。
  • 帖子的重点是我真的不知道问题出在哪里,但我认为它在于渲染到纹理而不是渲染到默认bframebuffer。但是,我在帖子中添加了一个主要问题:)
  • 您是否正在创建核心配置文件上下文?

标签: java opengl rendering lwjgl framebuffer


【解决方案1】:

我做了一件非常愚蠢的事。我在 (RenderableTextue.class) 中初始化 fbo 纹理的类是 Texture.class 的子类。包含 textureID 的绑定方法应该是从 Texture 类继承的,因为我已将 id 变量声明为protected。但是,我意外地在子类中创建了一个本地 private 变量,因此,在生成纹理时,将 textureID 保存到本地 id 变量中,并且在绑定时,使用了超类中未初始化的 id。很抱歉有人试图解决这个问题而无法这样做:s

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多