当前位置: 首页 > 知识库问答 >
问题:

OpenGL渲染到帧缓冲区会产生白色矩形纹理

卢骏俊
2023-03-14

这是我试图执行的主要程序:

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

但是,我看到的不是纹理而是白色矩形。如果我在屏幕上渲染,我会得到预期的结果(因此渲染代码应该没有问题)。这是FrameBuffer类:

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);
        }
    };

其他一切都经过测试,所以问题应该在主程序的逻辑或帧缓冲区中。

顺便说一下,视口大小iz与窗口大小完全相同。

共有1个答案

端木弘方
2023-03-14

假设create方法中的注释正确,这将不起作用:

        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);

不能将深度纹理附加到颜色缓冲区。纹理格式GL_DEPTH_COMPONENT*GL_DEPTH*_STENCIL*永远无法进行颜色渲染。

我不知道评论是否只是一个输入错误,你是否打算创建一个标准的RGB或RGBA颜色纹理,或者你是否真的想要深度缓冲区的纹理。在后一种情况下,可以将其附着到深度附着点(而不是像当前那样使用renderbuffer)。然后,可以执行仅深度渲染过程,完全不需要颜色缓冲区。

但也许你只需要一个32位的单通道纹理,你可以使用格式GL_R32F,这样你的片段着色器输出的r通道就可以被存储。也可以通过这种方式将每个片段gl_FragDepth存储在颜色缓冲区中(但这可能不如直接使用深度纹理的深度附件有效,尤其是因为实际深度测试基本上仍然需要使用深度缓冲区)。

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

        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_DepthBufferID);
 类似资料:
  • 我做了一个在上面渲染天空盒和粒子的应用程序。我想添加一些效果,我需要使用帧缓冲区来渲染天空盒、粒子颜色、深度和位置以分离纹理。然后我想使用简单的着色器来使用这些纹理中的值并以适当的方式混合它们。我为纹理、帧缓冲区和屏幕四边形(渲染简单的矩形)编写了辅助类,但不幸的是——当我尝试使用它时没有任何渲染。 当绑定帧缓冲区被注释掉时,我的场景如下所示: 修改着色器表明深度和位置值计算正确。因此问题在于纹理

  • 这是更大项目的一部分,基本上,我用以下方式创建带有颜色、深度和模具缓冲区的帧缓冲区: 我用以下方法将其绑定: 当我转储附加的纹理: 我收到主帧缓冲区(0)的内容。 知道我哪里错了吗?先谢谢你。

  • 我正在使用JOGL,但这个问题一般适用于OpenGL。似乎存在类似的问题,但它们要么针对GLSL代码,要么与复制帧缓冲区的内容有关,要么是一般建议-使用帧缓冲区对象,而不是。 我正在做一些阴影映射。如何使用帧缓冲对象将深度通道直接渲染到纹理? 能否请你贴一段初始化纹理和帧缓冲对象的代码,以及渲染场景前初始化一切的代码? 目前,我使用<code>glCopyTexSubImage2D<code>。我

  • 我正在尝试使用OpenGL GLSL着色器渲染到纹理。首先,我尝试用白色填充30x30纹理的每个像素。我将顶点着色器索引从0传递到899,表示纹理的每个像素。对吗?顶点着色器: 片段着色器:

  • 这是代码中唯一可能有错误的部分: 你能在这段代码中看到什么错误吗?启用glEnable(GL_TEXTURE_2D)并没有什么不同。纹理坐标是正确的,片段和顶点着色器肯定是正确的。 解决了这不是问题,我仍在使用glGenerateMipmap(…)在glTexImage2D(…)之前。真正的问题是,当我的图像是GL_RGB格式时,我通过了格式GL_RGBA。另外我的t-

  • 我是OpenGL的新手。我想使用帧缓冲区读取并保存渲染场景中的所有深度值。我设法将其设置为附加到深度组件的帧缓冲区。但是当我将深度纹理渲染到默认帧缓冲区(显示窗口)时,它只显示白色,即使我线性化了深度值(教程从https://learnopengl.com/开始)。当我在默认帧缓冲区片段着色器中从gl_FragCoord. z访问深度值时,我会得到一个深度图,并且绘图也可以,但是当将深度作为纹理从