opengl4多采样与FBO - FBO不完全

本文关键字:FBO 不完全 采样 opengl4 | 更新日期: 2023-09-27 18:13:53

我在OpenTK (opengl4的c#包装器)中制作2D游戏,除了多边形的锯齿状边缘和东西跳跃和口吃而不是顺利移动之外,一切都很好-所以我试图添加多重采样来抗混叠我的纹理。

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

没有多重采样,它工作得很好,但现在我试图改变我所有的Texture2D调用Texture2DMultisample等,但现在我得到FBO不完整的错误,它画错了。我相信我也需要改变我的着色器,但我想先解决这个问题。

下面的代码引用了一些类,如纹理,我已经做了,但我不认为这应该影响这一点,我不想混乱的帖子-将提供更多的细节,如果需要。

我为每个相机设置了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();
    }

和draw with:

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

opengl4多采样与FBO - FBO不完全

好的@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);
    }

我有一个包装类来控制Shader代码,这是bind调用:

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