Пример #1
0
        /// <summary>
        /// Attaches a <see cref="RenderbufferObject"/> to this <see cref="FramebufferObject"/> in a specified attachment point.
        /// </summary>
        /// <param name="renderbuffer">The <see cref="RenderbufferObject"/> to attach.</param>
        /// <param name="attachmentPoint">The attachment point to attach the <see cref="RenderbufferObject"/> to.</param>
        public void Attach(RenderbufferObject renderbuffer, FramebufferAttachmentPoint attachmentPoint)
        {
            if (renderbuffer == null)
            {
                throw new ArgumentNullException(nameof(renderbuffer));
            }

            ValidateAttachmentTypeExists(attachmentPoint);
            ValidateAttachmentTypeNotUsed(attachmentPoint);

            if (attachmentPoint == FramebufferAttachmentPoint.Depth && !renderbuffer.IsDepthOnly)
            {
                throw new InvalidFramebufferAttachmentException("When attaching a renderbuffer to a depth attachment point, the renderbuffer's format must be depth-only");
            }

            if (attachmentPoint == FramebufferAttachmentPoint.DepthStencil && !renderbuffer.IsDepthStencil)
            {
                throw new InvalidFramebufferAttachmentException("When attaching a renderbuffer to a depth-stencil attachment point, the renderbuffer's format must be depth-stencil");
            }

            if (attachmentPoint == FramebufferAttachmentPoint.Stencil && !renderbuffer.IsStencilOnly)
            {
                throw new InvalidFramebufferAttachmentException("When attaching a renderbuffer to a stencil attachment point, the renderbuffer's format must be stencil-only");
            }

            if (TrippyUtils.IsFramebufferAttachmentPointColor(attachmentPoint) && !renderbuffer.IsColorRenderableFormat)
            {
                throw new InvalidFramebufferAttachmentException("When attaching a renderbuffer to a color attachment point, the renderbuffer's format must be color-renderable");
            }

            GraphicsDevice.Framebuffer = this;
            GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, (FramebufferAttachment)attachmentPoint, RenderbufferTarget.Renderbuffer, renderbuffer.Handle);
            renderbufferAttachments.Add(new FramebufferRenderbufferAttachment(renderbuffer, attachmentPoint));
        }
Пример #2
0
        /// <summary>
        /// Creates a <see cref="Framebuffer2D"/> with the given width, height, and other optional parameters.
        /// </summary>
        /// <param name="graphicsDevice">The <see cref="GraphicsDevice"/> this <see cref="Framebuffer2D"/> will use.</param>
        /// <param name="width">The width of the <see cref="Framebuffer2D"/>'s image.</param>
        /// <param name="height">The height of the <see cref="Framebuffer2D"/>'s image.</param>
        /// <param name="depthStencilFormat">The depth-stencil format for an optional renderbuffer attachment.</param>
        /// <param name="samples">The amount of samples for the <see cref="Framebuffer2D"/>'s image.</param>
        /// <param name="imageFormat">The format of the <see cref="Framebuffer2D"/>'s image.</param>
        /// <param name="useDepthStencilTexture">Whether to use a texture for the depth-stencil buffer instead of a renderbuffer.</param>
        public Framebuffer2D(GraphicsDevice graphicsDevice, uint width, uint height,
                             DepthStencilFormat depthStencilFormat, uint samples = 0,
                             TextureImageFormat imageFormat = TextureImageFormat.Color4b, bool useDepthStencilTexture = false)
        {
            Framebuffer = new FramebufferObject(graphicsDevice);
            Texture     = new Texture2D(graphicsDevice, width, height, false, samples, imageFormat);

            if (depthStencilFormat != DepthStencilFormat.None)
            {
                if (useDepthStencilTexture)
                {
                    TextureImageFormat dsFormat  = TrippyUtils.DepthStencilFormatToTextureFormat(depthStencilFormat);
                    Texture2D          dsTexture = new Texture2D(graphicsDevice, width, height, false, samples, dsFormat);
                    Framebuffer.Attach(dsTexture, TrippyUtils.GetCorrespondingTextureFramebufferAttachmentPoint(dsFormat));
                }
                else
                {
                    RenderbufferObject rbo = new RenderbufferObject(graphicsDevice, width, height, (RenderbufferFormat)depthStencilFormat, samples);
                    Framebuffer.Attach(rbo, TrippyUtils.GetCorrespondingRenderbufferFramebufferAttachmentPoint(rbo.Format));
                }
            }

            Framebuffer.Attach(Texture, FramebufferAttachmentPoint.Color0);
            Framebuffer.UpdateFramebufferData();
        }
 /// <summary>
 /// Creates a <see cref="FramebufferRenderbufferAttachment"/>.
 /// </summary>
 /// <param name="renderbuffer">The <see cref="RenderbufferObject"/> to attach in this attachment.</param>
 /// <param name="attachmentPoint">The attachment point to which this attachment attaches to.</param>
 public FramebufferRenderbufferAttachment(RenderbufferObject renderbuffer, FramebufferAttachmentPoint attachmentPoint)
 {
     Renderbuffer    = renderbuffer;
     AttachmentPoint = attachmentPoint;
 }
Пример #4
0
        /// <summary>
        /// Updates the <see cref="FramebufferObject"/>'s parameters and checks that the framebuffer is valid.
        /// This should always be called after being done attaching or detaching resources.
        /// </summary>
        public void UpdateFramebufferData()
        {
            uint width   = uint.MaxValue;
            uint height  = uint.MaxValue;
            uint samples = uint.MaxValue;

            for (int i = 0; i < textureAttachments.Count; i++)
            {
                Texture tex = textureAttachments[i].Texture;
                if (tex is Texture1D tex1d)
                {
                    ValidateSize(tex1d.Width, 1);
                }
                else if (tex is Texture2D tex2d)
                {
                    ValidateSize(tex2d.Width, tex2d.Height);
                }
                else
                {
                    throw new FramebufferException("The texture format cannot be attached: " + tex.TextureType);
                }

                ValidateSamples(tex is TextureMultisamplable ms ? ms.Samples : 0);
            }

            for (int i = 0; i < renderbufferAttachments.Count; i++)
            {
                RenderbufferObject rend = renderbufferAttachments[i].Renderbuffer;
                ValidateSize(rend.Width, rend.Height);
                ValidateSamples(rend.Samples);
            }

            Width   = width;
            Height  = height;
            Samples = samples;

            void ValidateSize(uint w, uint h)
            {
                if (width == uint.MaxValue)
                {
                    width = w;
                }
                else if (width != w)
                {
                    throw new FramebufferException("All the attachments must be the same size");
                }

                if (height == uint.MaxValue)
                {
                    height = h;
                }
                else if (height != h)
                {
                    throw new FramebufferException("All the attachments must be the same size");
                }
            }

            void ValidateSamples(uint s)
            {
                if (samples == uint.MaxValue)
                {
                    samples = s;
                }
                else if (samples != s)
                {
                    throw new FramebufferException("All the attachments must have the same amount of samples");
                }
            }

            FramebufferStatus c = GetStatus();

            if (c != FramebufferStatus.FramebufferComplete)
            {
                throw new FramebufferException("The " + nameof(FramebufferObject) + " is not complete: " + c);
            }
        }