2015-09-21 3 views
0

Я делаю 2D-игры в OpenTK (оболочка C# для OpenGL 4), и все было хорошо, за исключением зубчатых краев многоугольников и вещей, прыгающих и заикающихся, вместо того чтобы двигаться плавно - так что я Я пытаюсь добавить в multisampling к antialias свои текстуры.OpenGL 4 мультисэмплинг с FBO - FBO неполным

У меня есть несколько камер, которые отображают все их объекты сцены на текстуру FrameBufferObject (я бы хотел, чтобы это был MSAA), которые затем все нарисованы на экране (без необходимости мультисэмплирования), один поверх другого.

Без мультисэмплинга он работал нормально, но теперь я попытался изменить все мои вызовы Texture2D на Texture2DMultisample и т. Д., Но теперь я получаю ошибки FBO Not Complete, и это неправильно. Я считаю, что мне тоже нужно изменить свои шейдеры, но я хочу сначала решить эту проблему.

В приведенном ниже коде приведено несколько классов, таких как текстура, которые я создал, но я не думаю, что это должно повлиять на это, и я не хочу загромождать сообщение - при необходимости предоставит детали 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

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

    } 

У меня есть класс-оболочку для управления код шейдера, вот привязывать вызов:

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

Vertex шейдеров:

/// <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; 
     }"; 
Смежные вопросы