예제 #1
0
        /// <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 pbuffers.</param>
        /// <param name="Format">Specifies the internal pixel format for the pbuffers.</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);
        }
예제 #2
0
 /// <summary>
 /// Bind a named texture to a texturing target
 /// </summary>
 /// <param name="Texture">Specifies the texture.</param>
 public static void BindTexture(Texture Texture)
 {
     Gl.BindTexture(Texture.TextureTarget, Texture.TextureID);
 }
예제 #3
0
 /// <summary>
 /// Create a texture from a supplie bitmap.
 /// </summary>
 /// <param name="BitmapImage">The already decoded bitmap image.</param>
 /// <param name="FlipY">True if the bitmap should be flipped.</param>
 public Texture(Bitmap BitmapImage, bool FlipY = true)
 {
     this.Filename = BitmapImage.GetHashCode().ToString();
     LoadBitmap(BitmapImage, FlipY);
     Gl.BindTexture(TextureTarget, 0);
 }
예제 #4
0
        /// <summary>
        /// Loads a compressed DDS file into an OpenGL texture.
        /// </summary>
        /// <param name="ResourceFile">The path to the DDS file.</param>
        private void LoadDDS(string ResourceFile)
        {
            using (BinaryReader stream = new BinaryReader(new FileStream(ResourceFile, FileMode.Open)))
            {
                string filecode = new string(stream.ReadChars(4));
                if (filecode != "DDS ")                                 // first 4 chars should be "DDS "
                {
                    throw new Exception("File was not a DDS file format.");
                }

                DDS.DDSURFACEDESC2 imageData = new DDS.DDSURFACEDESC2(stream);  // read the DirectDraw surface descriptor
                this.Size = new Size((int)imageData.Width, (int)imageData.Height);

                if (imageData.LinearSize == 0)
                {
                    throw new Exception("The linear scan line size was zero.");
                }

                bool compressed = true;
                int  factor = 0, buffersize = 0, blocksize = 0;
                PixelInternalFormat format;
                switch (imageData.PixelFormat.FourCC) // check the compression type
                {
                case "DXT1":                          // DXT1 compression ratio is 8:1
                    format    = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
                    factor    = 2;
                    blocksize = 8;
                    break;

                case "DXT3":        // DXT3 compression ratio is 4:1
                    format    = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext;
                    factor    = 4;
                    blocksize = 16;
                    break;

                case "DXT5":        // DXT5 compression ratio is 4:1
                    format    = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
                    factor    = 4;
                    blocksize = 16;
                    break;

                default:
                    compressed = false;
                    if (imageData.PixelFormat.ABitMask == 0xf000 && imageData.PixelFormat.RBitMask == 0x0f00 &&
                        imageData.PixelFormat.GBitMask == 0x00f0 && imageData.PixelFormat.BBitMask == 0x000f &&
                        imageData.PixelFormat.RGBBitCount == 16)
                    {
                        format = PixelInternalFormat.Rgba;
                    }
                    throw new Exception(string.Format("File compression \"{0}\" is not supported.", imageData.PixelFormat.FourCC));
                }

                if (imageData.LinearSize != 0)
                {
                    buffersize = (int)((imageData.MipmapCount > 1) ? imageData.LinearSize * factor : imageData.LinearSize);
                }
                else
                {
                    buffersize = (int)(stream.BaseStream.Length - stream.BaseStream.Position);
                }

                // read the pixel data and then pin it to memory so that the garbage collector
                // doesn't shuffle the data around while OpenGL is decompressing it
                byte[]   pixels = stream.ReadBytes(buffersize);
                GCHandle pinned = GCHandle.Alloc(pixels, GCHandleType.Pinned);

                try
                {
                    this.TextureTarget = (imageData.Height == 1 || imageData.Width == 1) ? TextureTarget.Texture1D : TextureTarget.Texture2D;
                    this.TextureID     = Gl.GenTexture();
                    Gl.BindTexture(TextureTarget, TextureID);
                    Gl.TexParameteri(TextureTarget, TextureParameterName.TextureMinFilter, TextureParameter.Linear);
                    Gl.TexParameteri(TextureTarget, TextureParameterName.TextureMagFilter, TextureParameter.Linear);

                    int nOffset = 0, nWidth = (int)imageData.Width, nHeight = (int)imageData.Height;

                    for (int i = 0; i < (imageData.MipmapCount == 0 ? 1 : imageData.MipmapCount); ++i)
                    {
                        if (nWidth == 0)
                        {
                            nWidth = 1;                     // smallest mipmap is 1x1 pixels
                        }
                        if (nHeight == 0)
                        {
                            nHeight = 1;
                        }
                        int nSize = 0;

                        if (compressed)
                        {
                            nSize = ((nWidth + 3) / 4) * ((nHeight + 3) / 4) * blocksize;
                            Gl.CompressedTexImage2D(TextureTarget, i, format, nWidth, nHeight, 0, nSize, (IntPtr)(pinned.AddrOfPinnedObject().ToInt64() + nOffset));
                        }
                        else
                        {
                            nSize = nWidth * nHeight * 4 * ((int)imageData.PixelFormat.RGBBitCount / 8);
                            Gl.TexImage2D(TextureTarget, i, format, nWidth, nHeight, 0, PixelFormat.Bgra, PixelType.UnsignedShort4444, (IntPtr)(pinned.AddrOfPinnedObject().ToInt64() + nOffset));
                        }

                        nOffset += nSize;
                        nWidth  /= 2;
                        nHeight /= 2;
                    }
                }
                catch (Exception)
                {   // There was some sort of Dll related error, or the target GPU does not support glCompressedTexImage2DARB
                    throw;
                }
                finally
                {
                    pinned.Free();
                }
            }
        }
예제 #5
0
 /// <summary>
 /// Unbind this Texture on specific target.
 /// </summary>
 /// <param name="ctx">
 /// A <see cref="GraphicsContext"/> used for binding this Texture.
 /// </param>
 /// <param name="target">
 /// A <see cref="TextureTarget"/> that specify the texture target.
 /// </param>
 protected void Unbind(GraphicsContext ctx, TextureTarget target)
 {
     // Unbind this Texture on specified target
     Gl.BindTexture(target, 0);
 }
예제 #6
0
 /// <summary>
 /// Bind this Texture on specific target.
 /// </summary>
 /// <param name="ctx">
 /// A <see cref="GraphicsContext"/> used for binding this Texture.
 /// </param>
 /// <param name="target">
 /// A <see cref="TextureTarget"/> that specify the texture target.
 /// </param>
 protected void Bind(GraphicsContext ctx, TextureTarget target)
 {
     // Bind this Texture on specified target
     Gl.BindTexture(target, ObjectName);
 }