简体   繁体   中英

OpenGL rendering to Framebuffer results in a white rectangle texture

This is the main program I'm trying to execute:

FrameBuffer* buffer = new FrameBuffer(960, 540);
buffer->Bind();
// render some textures
buffer->Unbind();
glViewport(0, 0, 960, 540);

Texture* texture = buffer->GetTexture();
// render the texture

However instead of the textures I see a white rectangle. If I render on a screen, I get the expected results (so there should be no problem with the rendering code). Here is the FrameBuffer class:

class FrameBuffer
{
private:
    Texture* m_Texture;
    unsigned int m_FrameBufferID;
    unsigned int m_DepthBufferID;
    unsigned int m_Width;
    unsigned int m_Height;
    Vector4f m_ClearColor;

public:
    FrameBuffer(unsigned int width, unsigned int height)
        : m_Width(width), m_Height(height), m_ClearColor(Maths::Vector4f(0, 0, 0, 0))
    {
        Create(m_Width, m_Height);
    }

    ~FrameBuffer()
     {
        glDeleteFramebuffers(1, &m_FrameBufferID);
     }

    void Bind() const
    {
        glBindFramebuffer(GL_FRAMEBUFFER, m_FrameBufferID);
        glViewport(0, 0, m_Width, m_Height);
    }

    void Unbind() const
    {
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }
    void Clear() const
    {
        glClearColor(m_ClearColor.x, m_ClearColor.y, m_ClearColor.z, m_ClearColor.w);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    }

    inline const Texture* GetTexture() const { return m_Texture; }

    private:
        void Create(unsigned int width, unsigned int height)
        {
            glGenFramebuffers(1, &m_FrameBufferID);
            glGenRenderbuffers(1, &m_DepthBufferID);

            Texture::SetFilterMode(TextureFilter::Linear);
            m_Texture = new Texture(width, height, 32);  // This creates a 32 bit texture (RGBA) with GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER set to linear

            glBindFramebuffer(GL_FRAMEBUFFER, m_FrameBufferID);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_Texture->GetTextureID(), 0);

            glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBufferID);
            glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);

            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_DepthBufferID);

            glBindFramebuffer(GL_FRAMEBUFFER, 0);
        }
    };

Everything else is tested, so the problem should be in the main program's logic or in the FrameBuffer.

By the way the viewport size iz exactly the same as the window size.

Assuming the comments in your create methods are correct, this will not work:

        m_Texture = new Texture(width, height, 32);  // This creates a 32 bit depth texture with GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER set to linear

        glBindFramebuffer(GL_FRAMEBUFFER, m_FrameBufferID);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_Texture->GetTextureID(), 0);

You cannot attach a depth texture to a color buffer. Texture formats GL_DEPTH_COMPONENT* and GL_DEPTH*_STENCIL* are never color-renderable .

I don't know if the comment is just a typo and you intend to create a standard RGB or RGBA color texture, or if you actually want the texture for the depth buffer. In the latter case, you could just attach it to the depth attachment point (instead of using a renderbuffer as you currently do). You then can do a depth-only render pass and don't need a color buffer at all.

But maybe you just want a single channel 32 Bit texture, and you could use the format GL_R32F for that, so that the r channel of your fragment shader's output can be stored. You could also store the each fragments gl_FragDepth in the color buffer that way (but that might not be as efficient as directly using the depth attachment with a depth texture, especially since you basically need to still use a depth buffer for the actual depth test).

        glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBufferID);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);

        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_DepthBufferID);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM