2016-12-26 152 views
0

我的问题是OpenGL渲染到主窗口,虽然我绑定了我想使用的Framebuffer。OpenGL不渲染到Framebuffer而是渲染到窗口

这是我的主要渲染法

protected override void OnRenderFrame(FrameEventArgs e) 
{ 
    base.OnRenderFrame(e); 

    renderer.BeginFrame(); 
    renderer.RenderEntity(testEntity); 
    renderer.EndFrame(); 

    SwapBuffers(); 
} 

这是我的渲染

class Renderer 
{ 
    List<Vertex> screenQuadVertecies = new List<Vertex> 
    { 
     new Vertex(new Vector3(-1, 1, 0), new Vector3()), 
     new Vertex(new Vector3(1, 1, 0), new Vector3()), 
     new Vertex(new Vector3(-1, -1, 0), new Vector3()), 
     new Vertex(new Vector3(1, -1, 0), new Vector3()) 
    }; 

    List<int> screenQuadIndices = new List<int> 
    { 
     0, 1, 2, 
     1, 2, 3 
    }; 

    List<Vector2> screenQuadUVs = new List<Vector2> 
    { 
     new Vector2(0, 0), 
     new Vector2(1, 0), 
     new Vector2(0, 1), 
     new Vector2(1, 1) 
    }; 

    TexturedMesh screenQuad; 

    Framebuffer mainPassFramebuffer; 

    Camera activeCamera; 
    Shader ModelShader; 
    Shader PostProcessingShader; 

    int width, height; 

    public Renderer(int width, int height) 
    { 
     this.width = width; 
     this.height = height; 

     ModelShader = new MainShader(); 
     PostProcessingShader = new PostProcessingShader(); 
     mainPassFramebuffer = new Framebuffer(width, height); 
     screenQuad = new TexturedMesh(screenQuadVertecies, screenQuadIndices, screenQuadUVs); 
    } 

    public void BeginFrame() 
    { 
     mainPassFramebuffer.EndRendering(); 
     GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); 
     mainPassFramebuffer.ClearBuffer(); 
     mainPassFramebuffer.BeginRendering(); 
    } 

    public void EndFrame() 
    { 
     mainPassFramebuffer.EndRendering(); 
     mainPassFramebuffer.BindTexture(); 
     PostProcessingShader.UseShader(); 
     screenQuad.PrepareRendering(); 
     GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, 0); 
     screenQuad.EndRendering(); 
     PostProcessingShader.UnuseShader(); 
    } 

    public void RenderEntity(Entity e) 
    { 
     e.Mesh.PrepareRendering(); 
     ModelShader.UseShader(); 
     ModelShader.LoadCamera(activeCamera); 
     ModelShader.LoadModel(e.GetModelMatrix()); 
     GL.DrawElements(PrimitiveType.Triangles, e.Mesh.GetSize(), DrawElementsType.UnsignedInt, 0); 
     ModelShader.UnuseShader(); 
    } 

    public void RenderTerrain(Terrain t) 
    { 
     foreach (var chunk in t.chunks) 
     { 
      RenderEntity(chunk.GetEntity()); 
     } 
    } 

    public void SetActiveCamera(Camera camera) 
    { 
     activeCamera = camera; 
    } 

} 

这是我的帧缓冲级

class Framebuffer 
{ 
    int frameBufferID; 
    int textureID; 

    int width, height; 

    public Framebuffer(int width, int height) 
    { 
     this.width = width; 
     this.height = height; 

     frameBufferID = GL.GenRenderbuffer(); 
     GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferID); 
     textureID = CreateTexture(); 
     GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, textureID, 0); 
     GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); 
    } 

    protected int CreateTexture() 
    { 
     int returnID; 

     returnID = GL.GenTexture(); 
     GL.BindTexture(TextureTarget.Texture2D, returnID); 

     GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, width, height, 0, PixelFormat.Rgb, PixelType.UnsignedByte, (IntPtr)0); 

     int nearest = (int)TextureMagFilter.Nearest; 
     GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, ref nearest); 
     GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, ref nearest); 

     return returnID; 
    } 

    public void BeginRendering() 
    { 
     GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferID); 
     GL.Viewport(new System.Drawing.Point(0, 0), new System.Drawing.Size(width, height)); 
    } 

    public void EndRendering() 
    { 
     GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); 
    } 

    public void BindTexture() 
    { 
     GL.BindTexture(TextureTarget.Texture2D, textureID); 
    } 

    public void ClearBuffer() 
    { 
     GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferID); 
     GL.Viewport(new System.Drawing.Point(0, 0), new System.Drawing.Size(width, height)); 
     GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); 
     GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); 
    } 
} 

预期的结果是一个黑色的四因当我发现我的模型仍然渲染到scre时,我一直在实现纹理恩。我发现,当我在EndRendering()中调用GL.DrawElements调用时,应该将四元组渲染到屏幕上。当我现在不画这个四边形时,图像仍然出现。

我在做什么错?

回答

1

渲染缓冲器不是帧缓冲区对象:

frameBufferID = GL.GenRenderbuffer();

当您尝试绑定您glGenRenderbuffers得到的帧缓冲区的ID,你会从glBindFramebuffer()得到GL_INVALID_OPERATION错误,并且该命令将不再起作用(离开绑定的默认帧缓存)。

新的FBO名称通过glGenFramebuffers生成,因此您应该使用该名称。

+0

哦,我的上帝愚蠢的错误...我刚刚关闭我的电脑,所以我明天会尝试。感谢您阅读Code的混乱! –