/// <summary> /// Binds the framebuffer and all of the renderbuffers. /// Clears the buffer bits and sets viewport size. /// Perform all rendering after this call. /// </summary> public void Enable() { Gl.BindFramebuffer(FramebufferTarget.Framebuffer, BufferID); if (Attachments.Length == 1) { Gl.BindTexture(TextureTarget.Texture2D, TextureID[0]); Gl.FramebufferTexture(FramebufferTarget.Framebuffer, Attachments[0], TextureID[0], 0); } else { DrawBuffersEnum[] buffers = new DrawBuffersEnum[Attachments.Length]; for (int i = 0; i < Attachments.Length; i++) { Gl.BindTexture(TextureTarget.Texture2D, TextureID[i]); Gl.FramebufferTexture(FramebufferTarget.Framebuffer, Attachments[i], TextureID[i], 0); buffers[i] = (DrawBuffersEnum)Attachments[i]; } if (Attachments.Length > 1) { Gl.DrawBuffers(Attachments.Length, buffers); } } Gl.Viewport(0, 0, Size.Width, Size.Height); if (Attachments.Length == 1 && Attachments[0] == FramebufferAttachment.DepthAttachment) { Gl.Clear(ClearBufferMask.DepthBufferBit); } else { Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); } }
/// <summary> /// Bind this GraphicsSurface for drawing. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> to wich associate its rendering result to this GraphicsSurface. /// </param> public override void BindDraw(GraphicsContext ctx) { // Bind this framebuffer Gl.BindFramebuffer(Gl.DRAW_FRAMEBUFFER, ObjectName); List <int> drawBuffers = new List <int>(); for (uint i = 0; i < GraphicsContext.CurrentCaps.Limits.MaxColorAttachments; i++) { // Reset dirty binding points if ((_ColorBuffers[i] != null) && _ColorBuffers[i].Dirty) { // Ensure created buffer _ColorBuffers[i].Create(ctx); // Ensure attached buffer _ColorBuffers[i].Attach(Gl.DRAW_FRAMEBUFFER, Gl.COLOR_ATTACHMENT0 + (int)i); _ColorBuffers[i].Dirty = false; } // Collect draw buffers if (_ColorBuffers[i] != null) { drawBuffers.Add(Gl.COLOR_ATTACHMENT0 + (int)i); } } // Validate completeness status Validate(ctx); // Update draw buffers Gl.DrawBuffers(drawBuffers.ToArray()); }
/// <summary> /// Bind this RenderSurface for reading. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> to wich associate its read result to this RenderSurface. /// </param> public override void BindRead(GraphicsContext ctx) { // Eventually unbind a framebuffer if (ctx.Caps.GlExtensions.FramebufferObject_ARB) { Gl.BindFramebuffer(Gl.READ_FRAMEBUFFER, InvalidObjectName); } }
/// <summary> /// Actually create this GraphicsResource resources. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for allocating resources. /// </param> protected override void CreateObject(GraphicsContext ctx) { int currentBinding; Gl.Get(Gl.READ_FRAMEBUFFER_BINDING, out currentBinding); Gl.BindFramebuffer(Gl.READ_FRAMEBUFFER, ObjectName); // Restore previous Framebuffer bound Gl.BindFramebuffer(Gl.READ_FRAMEBUFFER, (uint)currentBinding); }
/// <summary> /// Unbinds the framebuffer and then generates the mipmaps of each renderbuffer. /// </summary> public void Disable() { Gl.BindFramebuffer(FramebufferTarget.Framebuffer, 0); // have to generate mipmaps here for (int i = 0; i < Attachments.Length && mipmaps; i++) { Gl.BindTexture(TextureTarget.Texture2D, TextureID[i]); Gl.GenerateMipmap(GenerateMipmapTarget.Texture2D); } }
/// <summary> /// Unbinds the framebuffer and then generates the mipmaps of each renderbuffer. /// </summary> public void Disable() { // unbind this framebuffer (does not guarantee the correct framebuffer is bound) Gl.BindFramebuffer(FramebufferTarget.Framebuffer, 0); // have to generate mipmaps here for (int i = 0; i < Attachments.Length && MipMaps; i++) { Gl.BindTexture(TextureTarget.Texture2D, TextureID[i]); Gl.GenerateMipmap(GenerateMipmapTarget.Texture2D); } }
/// <summary> /// Bind this GraphicsSurface for reading. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> to wich associate its read result to this GraphicsSurface. /// </param> public override void BindRead(GraphicsContext ctx) { // Bind this framebuffer Gl.BindFramebuffer(Gl.READ_FRAMEBUFFER, ObjectName); // Reset dirty binding points for (uint i = 0; i < GraphicsContext.CurrentCaps.Limits.MaxColorAttachments; i++) { if ((_ColorBuffers[i] != null) && _ColorBuffers[i].Dirty) { // Ensure created buffer _ColorBuffers[i].Create(ctx); // Ensure attached buffer _ColorBuffers[i].Attach(Gl.DRAW_FRAMEBUFFER, Gl.COLOR_ATTACHMENT0 + (int)i); _ColorBuffers[i].Dirty = false; } } }
/// <summary> /// Unbind this GraphicsSurface for drawing. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> to wich disassociate its rendering result from this GraphicsSurface. /// </param> public override void UnbindDraw(GraphicsContext ctx) { // Switch to default framebuffer Gl.BindFramebuffer(Gl.DRAW_FRAMEBUFFER, InvalidObjectName); }
/// <summary> /// Creates a framebuffer object and its associated resources (depth and pbuffers). /// </summary> /// <param name="Size">Specifies the size (in pixels) of the framebuffer and it's associated buffers.</param> /// <param name="Attachments">Specifies the attachments to use for the frame buffer.</param> /// <param name="Format">Specifies the internal pixel format for the frame buffer.</param> /// <param name="Mipmaps">Specified whether to build mipmaps after the frame buffer is unbound.</param> public FBO(Size Size, FramebufferAttachment[] Attachments, PixelInternalFormat Format, bool Mipmaps) { this.Size = Size; this.Attachments = Attachments; this.Format = Format; this.mipmaps = Mipmaps; // First create the framebuffer BufferID = Gl.GenFramebuffer(); Gl.BindFramebuffer(FramebufferTarget.Framebuffer, BufferID); if (Attachments.Length == 1 && Attachments[0] == FramebufferAttachment.DepthAttachment) { TextureID = new uint[] { Gl.GenTexture() }; Gl.BindTexture(TextureTarget.Texture2D, TextureID[0]); Gl.TexImage2D(TextureTarget.Texture2D, 0, Format, Size.Width, Size.Height, 0, PixelFormat.DepthComponent, PixelType.Float, IntPtr.Zero); Gl.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, TextureParameter.Nearest); Gl.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, TextureParameter.Nearest); Gl.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, TextureParameter.ClampToEdge); Gl.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, TextureParameter.ClampToEdge); Gl.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureID[0], 0); Gl.DrawBuffer(DrawBufferMode.None); Gl.ReadBuffer(ReadBufferMode.None); } else { // Create and attach a 24-bit depth buffer to the framebuffer DepthID = Gl.GenRenderbuffer(); Gl.BindRenderbuffer(RenderbufferTarget.Renderbuffer, DepthID); Gl.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent24, Size.Width, Size.Height); // Create n texture buffers (known by the number of attachments) TextureID = new uint[Attachments.Length]; Gl.GenTextures(Attachments.Length, TextureID); // Bind the n texture buffers to the framebuffer for (int i = 0; i < Attachments.Length; i++) { Gl.BindTexture(TextureTarget.Texture2D, TextureID[i]); Gl.TexImage2D(TextureTarget.Texture2D, 0, Format, Size.Width, Size.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); if (Mipmaps) { Gl.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, TextureParameter.Linear); Gl.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, TextureParameter.LinearMipMapLinear); Gl.GenerateMipmap(GenerateMipmapTarget.Texture2D); } Gl.FramebufferTexture(FramebufferTarget.Framebuffer, Attachments[i], TextureID[i], 0); } // Build the framebuffer and check for errors Gl.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, DepthID); } FramebufferErrorCode status = Gl.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (status != FramebufferErrorCode.FramebufferComplete) { Console.WriteLine("Frame buffer did not compile correctly. Returned {0}, glError: {1}", status.ToString(), Gl.GetError().ToString()); } Gl.BindFramebuffer(FramebufferTarget.Framebuffer, 0); }
public void Use() => Gl.BindFramebuffer(Gl.FrameBuffer, _hdc);
public static void UseDefault() => Gl.BindFramebuffer(Gl.FrameBuffer, 0);