2

我使用以下代码创建纹理 + 帧缓冲区(在 C# 中使用 openTK):

    public void Create(int width, int height, SurfaceFormat format)
    {
        bool multisample = format.Multisample > 1;
        int samples = Math.Max(1, Math.Min(format.Multisample, 4));
        TextureTarget target = multisample ? TextureTarget.Texture2DMultisample : TextureTarget.Texture2D;
        Width = width;
        Height = height;
        textureHandle = GL.GenTexture();
        //bind texture
        
        GL.BindTexture(target, textureHandle);
        Log.Error("Bound Texture: " + GL.GetError());
        GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
        GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
        GL.TexParameter(target, TextureParameterName.TextureWrapS, (int)format.WrapMode);
        GL.TexParameter(target, TextureParameterName.TextureWrapT, (int)format.WrapMode);
        
        Log.Error("Created Texture Parameters: " + GL.GetError());
        if (format.Multisample < 2)
            GL.TexImage2D(target, 0, format.InternalFormat, Width, Height, 0, format.PixelFormat, format.SourceType, format.Pixels);
        else
            GL.TexImage2DMultisample(TextureTargetMultisample.Texture2DMultisample, samples, format.InternalFormat, Width, Height, false);
        Log.Error("Created Image: " + GL.GetError());
        //unbind texture
        GL.BindTexture(target, 0);
        //create depthbuffer
        if (format.DepthBuffer)
        {
            GL.GenRenderbuffers(1, out dbHandle);
            GL.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, dbHandle);
            
            if(multisample)
                GL.RenderbufferStorageMultisample(RenderbufferTarget.RenderbufferExt, samples, RenderbufferStorage.Depth24Stencil8, Width, Height);
            else
                GL.RenderbufferStorage(RenderbufferTarget.RenderbufferExt, RenderbufferStorage.DepthComponent24, Width, Height);
        }

        //create fbo
        fboHandle = GL.GenFramebuffer();
        GL.BindFramebuffer(FramebufferTarget.FramebufferExt, fboHandle);
        GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, target, textureHandle, 0);
        
        if(format.DepthBuffer)
            GL.FramebufferRenderbuffer(FramebufferTarget.FramebufferExt, FramebufferAttachment.DepthAttachmentExt, RenderbufferTarget.RenderbufferExt, dbHandle);
        Log.Debug("Framebuffer status: " + GL.CheckFramebufferStatus(FramebufferTarget.FramebufferExt));
        Log.Error("Created Framebuffer: " + GL.GetError());
        GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
    }

我收到以下错误:

[错误]:创建的纹理参数:InvalidEnum

[LOG]:帧缓冲区状态:FramebufferIncompleteMultisample

当我尝试使用多重采样创建表面时 (2)

任何想法出了什么问题?该代码适用于 ms < 2。

4

1 回答 1

7

GL_INVALID_ENUM触发错误是因为作为调用的GL_TEXTURE_2D_MULTISAMPLE第一个参数无效TexParameter()

多重采样纹理只能在具有该texelFetch()功能的着色器中访问。它们不支持 mipmap、线性采样或任何其他采样属性。因此,GL_TEXTURE_2D_MULTISAMPLE不是glTexParameteri().

关于GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE错误,这很可能是由此调用的最后一个参数引起的:

GL.TexImage2DMultisample(TextureTargetMultisample.Texture2DMultisample, samples,
                         format.InternalFormat, Width, Height, false);

最后一个参数是fixedsamplelocations,因此调用会禁用固定样本位置。

OpenGL 规范的帧缓冲区完整性部分包括以下错误情况:

TEXTURE_FIXED_SAMPLE_LOCATIONS 的值对于所有附加的纹理都是相同的;并且,如果附加图像是渲染缓冲区和纹理的混合,则所有附加纹理的 TEXTURE_FIXED_SAMPLE_LOCATIONS 的值必须为 TRUE。{FRAMEBUFFER_INCOMPLETE_MULTISAMPLE}

这正是你所拥有的条件。FBO 的附件是纹理和渲染缓冲区的混合体。为避免此错误,纹理必须使用固定的采样位置。这是通过将上述调用中的最后一个参数更改为 true 来完成的:

GL.TexImage2DMultisample(TextureTargetMultisample.Texture2DMultisample, samples,
                         format.InternalFormat, Width, Height, true);
于 2014-07-14T00:23:32.830 回答