【问题标题】:OpenGL 4 multisampling with FBO - FBO incomplete使用 FBO 进行 OpenGL 4 多重采样 - FBO 不完整
【发布时间】:2015-09-21 19:47:07
【问题描述】:

我正在使用 OpenTK(OpenGL 4 的 C# 包装器)制作 2D 游戏,除了多边形的锯齿状边缘以及跳跃和口吃而不是平滑移动之外,一切都很好 - 所以我正在尝试添加多重采样到抗锯齿我的纹理。

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

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

下面的代码引用了我制作的一些类,例如 Texture,但我认为这不会影响这一点,我不想让帖子混乱 - 如果需要,将提供 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);
    }

【问题讨论】:

  • FBO 有深度附件吗?我没有看到它附加在发布的代码中,但您正在清除深度缓冲区这一事实表明存在一个。
  • 我不相信它,我什至不确定我什至不知道它是什么..
  • 我真的不明白您希望通过创建具有 0 个样本的多重采样纹理来实现什么?这可能就是它不完整的原因。
  • 好的@Andon,这大概是我做错了什么?您能否解释一下如何使用 8 个样本创建多重采样纹理?我在这里超出了我的深度..
  • 这是您调用GL.TexImage2DMultisample的第二个参数

标签: c# opengl opentk


【解决方案1】:

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

我正在将工作抗锯齿绘图发布到多个 FBOS 代码中,以供未来的 OpenTK googlers 使用。

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

    }

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-27
    • 2010-12-18
    • 1970-01-01
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    相关资源
    最近更新 更多