使用 FBO 的 OpenGL 4 多重采样 - FBO 不完整

OpenGL 4 multisampling with FBO - FBO incomplete

我在 OpenTK(OpenGL 4 的 C# 包装器)中制作 2D 游戏,一切都很好,除了多边形的锯齿状边缘和东西跳跃和断断续续而不是平滑移动 - 所以我试图添加多重采样以抗锯齿我的纹理。

我的设置有几个相机,它们将所有场景对象渲染到一个 FrameBufferObject 纹理上(我希望这是 MSAA),然后将它们全部绘制到屏幕上(不需要多重采样),一个在另一个之上.

没有多重采样,它工作正常,但现在我试图将我所有的 Texture2D 调用更改为 Texture2DMultisample 等,但现在我得到 FBO Not Complete 错误并且绘制错误。我相信我也需要更改我的着色器,但我想先解决这个问题。

下面的代码引用了我制作的一些 类 之类的纹理,但我认为这不会影响它,我不想弄乱 post -如果需要,将提供 mroe 详细信息。

我为每台摄像机设置了 FBO:

 private void SetUpFBOTex()
    {
        _frameBufferTexture = new Texture(GL.GenTexture(), Window.W, Window.H);
        GL.BindTexture(TextureTarget.Texture2DMultisample, _frameBufferTexture.ID);           
        GL.TexImage2DMultisample(TextureTargetMultisample.Texture2DMultisample, 0, PixelInternalFormat.Rgba8, Window.W, Window.H, true);

        _frameBufferID = GL.GenFramebuffer();
    }

并绘制:

public void Render(Matrix4 matrix)
    {
        GL.Enable(EnableCap.Multisample);
        //Bind FBO to be the draw destination and clear it
        GL.BindFramebuffer(FramebufferTarget.Framebuffer, _frameBufferID);
        GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2DMultisample, _frameBufferTexture.ID, 0);
        GL.ClearColor(new Color4(0,0,0,0));
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

        //draw stuff here 
        foreach (Layer l in Layers)
            l.Render(Matrix);


        GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);

        //Bind the FBO to be drawn
        _frameBufferTexture.Bind();

        //Translate to camera window position
        Matrix4 fbomatrix = matrix * Matrix4.CreateTranslation(_window.x, _window.y, 0) * FBOMatrix;            

        //Bind shader 
        shader.Bind(ref fbomatrix, DrawType);

        //Some OpenGL setup nonsense, binding vertices and index buffer and telling OpenGL where in the vertex struct things are, pointers &c
        GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer);
        GL.EnableVertexAttribArray(shader.LocationPosition);
        GL.VertexAttribPointer(shader.LocationPosition, 2, VertexAttribPointerType.Float, false, Stride, 0);
        if (shader.LocationTexture != -1)
        {
            GL.EnableVertexAttribArray(shader.LocationTexture);
            GL.VertexAttribPointer(shader.LocationTexture, 2, VertexAttribPointerType.Float, false, Stride, 8);
        }
        GL.EnableVertexAttribArray(shader.LocationColour);
        GL.VertexAttribPointer(shader.LocationColour, 4, VertexAttribPointerType.UnsignedByte, true, Stride, 16);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer);

        //Draw the damn quad
        GL.DrawArrays(DrawType, 0, Vertices.Length);

        //Cleanup
        GL.DisableVertexAttribArray(shader.LocationPosition);
        if (shader.LocationTexture != -1)
            GL.DisableVertexAttribArray(shader.LocationTexture);
        GL.DisableVertexAttribArray(shader.LocationColour);
    }

好的,@Andon 对此表示赞赏 - 如果您将其写为答案,我会将其标记为解决方案。我确实在用 0 个样本进行抗锯齿处理!

我正在将有效的抗锯齿绘图发布到多个 FBOS 代码,供未来的 OpenTK 谷歌搜索者使用。

private void SetUpFBOTex()
    {
        _frameBufferTexture = new Texture(GL.GenTexture(), Window.W, Window.H);
        GL.BindTexture(TextureTarget.Texture2DMultisample, _frameBufferTexture.ID);
        GL.TexImage2DMultisample(TextureTargetMultisample.Texture2DMultisample, 8, PixelInternalFormat.Rgba8, Window.W, Window.H, false);

        _frameBufferID = GL.GenFramebuffer();
    }

public void Render(Matrix4 matrix)
    {
        //Bind FBO to be the draw destination and clear it
        GL.BindFramebuffer(FramebufferTarget.Framebuffer, _frameBufferID);
        GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2DMultisample, _frameBufferTexture.ID, 0);
        GL.ClearColor(new Color4(0,0,0,0));
        GL.Clear(ClearBufferMask.ColorBufferBit);

        //draw stuff here 
        foreach (Layer l in Layers)
            l.Render(Matrix);

        //unbind FBO to allow drawing to screen again
        GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);


        //Bind the FBO to be drawn
        GL.BindTexture(TextureTarget.Texture2DMultisample, _frameBufferTexture.ID);

        //Translate to camera window position
        Matrix4 fbomatrix = matrix * Matrix4.CreateTranslation(_window.x, _window.y, 0) * FBOMatrix;

        //Rotate camera FBO texture
        if (_rotationAngle != 0f)
        {
            fbomatrix = Matrix4.CreateTranslation(RotationCentre.x, RotationCentre.y, 0) * fbomatrix;
            fbomatrix = Matrix4.CreateRotationZ(_rotationAngle) * fbomatrix;
            fbomatrix = Matrix4.CreateTranslation(-RotationCentre.x, -RotationCentre.y, 0) * fbomatrix;
        }


        shader.Bind(ref fbomatrix, DrawType);

        //Some OpenGL setup nonsense, binding vertices and index buffer and telling OpenGL where in the vertex struct things are, pointers &c
        GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer);
        GL.EnableVertexAttribArray(shader.LocationPosition);
        GL.VertexAttribPointer(shader.LocationPosition, 2, VertexAttribPointerType.Float, false, Stride, 0);
        if (shader.LocationTexture != -1)
        {
            GL.EnableVertexAttribArray(shader.LocationTexture);
            GL.VertexAttribPointer(shader.LocationTexture, 2, VertexAttribPointerType.Float, false, Stride, 8);
        }
        GL.EnableVertexAttribArray(shader.LocationColour);
        GL.VertexAttribPointer(shader.LocationColour, 4, VertexAttribPointerType.UnsignedByte, true, Stride, 16);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer);

        //Draw the damn quad
        GL.DrawArrays(DrawType, 0, Vertices.Length);

        //Cleanup
        GL.DisableVertexAttribArray(shader.LocationPosition);
        if (shader.LocationTexture != -1)
            GL.DisableVertexAttribArray(shader.LocationTexture);
        GL.DisableVertexAttribArray(shader.LocationColour);

    }

我有一个包装器 class 来控制着色器代码,这里是绑定调用:

internal void Bind(ref Matrix4 matrixMVP)
        {
            //Set this shader as active shader
            GL.UseProgram(programID);

            //Load position matrix into vertex shaders
            GL.UniformMatrix4(LocationMVPMatrix, false, ref matrixMVP);

            //Load active texture into fragment shaders
            GL.Uniform1(LocationSampler, 0);
        }

片段着色器:

/// <summary>
    /// Test for a Multisampled fragment shader - http://www.opentk.com/node/2251
    /// </summary>
    public const string fragmentShaderTestSrc =
    @"
    #version 330

    uniform sampler2DMS Sampler;

    in vec2 InTexture;
    in vec4 OutColour;

    out vec4 OutFragColor;

    int samples = 16;
    float div= 1.0/samples;

    void main()
    {
        OutFragColor = vec4(0.0);
        ivec2 texcoord = ivec2(textureSize(Sampler) * InTexture); // used to fetch msaa texel location
        for (int i=0;i<samples;i++)
        {
            OutFragColor += texelFetch(Sampler, texcoord, i) * OutColour;  // add  color samples together
        }

        OutFragColor*= div; //devide by num of samples to get color avg.
    }
    ";

顶点着色器:

/// <summary>
    /// Default vertex shader that only applies specified matrix transformation
    /// </summary>
    public const string vertexShaderDefaultSrc =
        @"
        #version 330

        uniform mat4 MVPMatrix;

        layout (location = 0) in vec2 Position;
        layout (location = 1) in vec2 Texture;
        layout (location = 2) in vec4 Colour;

        out vec2 InVTexture;
        out vec4 vFragColorVs;

        void main()
        {
            gl_Position = MVPMatrix * vec4(Position, 0, 1);
            InVTexture = Texture;
            vFragColorVs = Colour;
        }";