Java OpenGL-为什么我的fbo/纹理保持黑色?

Java OpenGL-为什么我的fbo/纹理保持黑色?,java,opengl,rendering,lwjgl,framebuffer,Java,Opengl,Rendering,Lwjgl,Framebuffer,*我一直在努力使用OpenGL的framebuffering和Java的LWJGL库来实现可渲染纹理功能。然而,我总是得到一个100%**黑色**纹理* 我只是想了解一下问题所在。我没有渲染任何特定的形状。我绑定生成的帧缓冲区并调用glClearColor(1,0,0,1)然后是glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)然后解除帧缓冲区的绑定。但是当我尝试渲染绑定到帧缓冲区的纹理时,纹理只显示黑色,实际上应该是红色,对吗 另外,glChe

*我一直在努力使用OpenGL的framebuffering和Java的LWJGL库来实现可渲染纹理功能。然而,我总是得到一个100%**黑色**纹理*

我只是想了解一下问题所在。我没有渲染任何特定的形状。我绑定生成的帧缓冲区并调用
glClearColor(1,0,0,1)然后是
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
然后解除帧缓冲区的绑定。但是当我尝试渲染绑定到帧缓冲区的纹理时,纹理只显示黑色,实际上应该是红色,对吗

另外,
glCheckFramebufferStatus()
返回
GL\u FRAMEBUFFER\u 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;
}
我将清除颜色设置为黑色
(0,0,0,1)
,然后清除屏幕。然后调用
texture.bindAsRenderTarget(true)
纹理
对象包含上面的
初始化
方法,因此该方法和
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\u FRAMEBUFFER,0)

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

差不多就这些了

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

因此,要说清楚,主要问题是:

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


编辑:我觉得这可能与不同gl项目的边界有关。renderbuffer是否必须在渲染点绑定到其帧缓冲区?不是吗?这有关系吗?质地怎么样?他们应该在什么时候?我做了一件非常愚蠢的事。我在(
renderabletexte.class
)中初始化fbo纹理的类是
texture.class
的子类。包括textureID的绑定方法应该从Texture类继承,因为我已将id变量声明为受保护的。但是,我意外地在子类中创建了一个本地
private
变量,因此,在生成纹理时,将textureID保存到本地id变量,在绑定时,使用超类中未初始化的id。很抱歉,有人试图解决此问题却无法解决此问题:s

当您完成绘制到帧缓冲区纹理并解除帧缓冲区的绑定后,在要再次渲染到后缓冲区之前,请尝试glDrawBuffer(GL_back);谢谢你的回答,罗宾逊:)不幸的是,这并没有解决问题。问题可能存在于fbo渲染中,而不是后缓冲区渲染中。从代码中不清楚问题是实际渲染到纹理/fbo,还是将纹理渲染到默认帧缓冲区。文章的重点是我不知道问题出在哪里,但我认为它位于渲染到纹理中,而不是渲染到defaultbframebuffer中。但是,我在帖子中添加了一个主要问题:)您是否正在创建核心概要文件上下文?
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;
}