2015-09-21 51 views
0

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

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

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

下面的代码引用了几类,比如我做了纹理,但我不认为应该影响到这一点,我不想扰乱后 - 如果需要会给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); 
    } 
+1

请问FBO有深度附件?我没有看到它被附加在发布的代码中,但是您清除深度缓冲区的事实表明存在一个。 –

+0

我不相信它,我不知道我知道一个是什么.. –

+0

我真的不明白你希望通过什么建立一个多重采样纹理0样品来完成?这可能是因为它不完整。 –

回答

1

好@Andon的功劳归于这一点 - 如果你写它作为一个答案,我会将其标记为解决方案。我确实在做0个样本的抗锯齿!

我张贴工作抗锯齿绘图到多个FBOS代码为将来的Google 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); 

    } 

我有一个包装类来控制着色器代码,这里的绑定电话:

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