Esempio n. 1
0
        private void LoadBitmap(Bitmap BitmapImage, bool FlipY = true)
        {
            /* .net library has methods for converting many image formats so I exploit that by using
             * .net to convert any filetype to a bitmap.  Then the bitmap is locked into memory so
             * that the garbage collector doesn't touch it, and it is read via OpenGL glTexImage2D. */
            if (FlipY)
            {
                BitmapImage.RotateFlip(RotateFlipType.RotateNoneFlipY);                        // bitmaps read from bottom up, so flip it
            }
            Size = BitmapImage.Size;

            // must be Format32bppArgb file format, so convert it if it isn't in that format
            BitmapData bitmapData = BitmapImage.LockBits(new Rectangle(0, 0, BitmapImage.Width, BitmapImage.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            // set the texture target and then generate the texture ID
            TextureTarget = TextureTarget.Texture2D;
            TextureID     = GlUtility.GenTexture();

            GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);    // set pixel alignment
            GL.BindTexture(TextureTarget, TextureID);                 // bind the texture to memory in OpenGL

            GL.TexImage2D(TextureTarget, 0, PixelInternalFormat.Rgba8, BitmapImage.Width, BitmapImage.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, bitmapData.Scan0);
            GL.TexParameter(TextureTarget, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(TextureTarget, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
            GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);

            BitmapImage.UnlockBits(bitmapData);
            BitmapImage.Dispose();
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a buffer object of type T.
        /// </summary>
        /// <param name="data">Specifies a pointer to data that will be copied into the data store for initialization.</param>
        /// <param name="target">Specifies the target buffer object.</param>
        /// <param name="hint">Specifies the expected usage of the data store.</param>
        public VBO(T[] data, BufferTarget target = BufferTarget.ArrayBuffer, BufferUsageHint hint = BufferUsageHint.StaticDraw)
        {
            vboID = GlUtility.CreateVBO <T>(BufferTarget = target, data, hint);

            Size        = (data is int[] || data is float[] ? 1 : (data is Vector2[] ? 2 : (data is Vector3[] ? 3 : (data is Vector4[] ? 4 : 0))));
            PointerType = (data is int[] ? VertexAttribPointerType.Int : VertexAttribPointerType.Float);
            Count       = data.Length;
        }
Esempio n. 3
0
        /// <summary>
        /// Creates a buffer object of type T with a specified length.
        /// This allows the array T[] to be larger than the actual size necessary to buffer.
        /// Useful for reusing resources and avoiding unnecessary GC action.
        /// </summary>
        /// <param name="data">An array of data of type T (which must be a struct) that will be buffered to the GPU.</param>
        /// <param name="position"></param>
        /// <param name="length">The length of the valid data in the data array.</param>
        /// <param name="target">Specifies the target buffer object.</param>
        /// <param name="hint">Specifies the expected usage of the data store.</param>
        public VBO(T[] data, int position, int length, BufferTarget target = BufferTarget.ArrayBuffer, BufferUsageHint hint = BufferUsageHint.StaticDraw)
        {
            length = Math.Max(0, Math.Min(length, data.Length));

            vboID = GlUtility.CreateVBO <T>(BufferTarget = target, data, hint, position, length);

            this.Size        = (data is int[] || data is float[] ? 1 : (data is Vector2[] ? 2 : (data is Vector3[] ? 3 : (data is Vector4[] ? 4 : 0))));
            this.PointerType = (data is int[] ? VertexAttribPointerType.Int : VertexAttribPointerType.Float);
            this.Count       = length;
        }
Esempio n. 4
0
        public void Draw(Matrix4 fov, Matrix4 cameraView)
        {
            //Logging.Debug("Entering background draw.");
            if (!HasBackground)
            {
                return;
            }
            //Logging.Debug("We have a background.");
            _backgroundProgram.Use();
            //Logging.Debug("Set background program.");
            GL.ActiveTexture(TextureUnit.Texture0);
            //Logging.Debug("Set active texture.");
            GlUtility.BindTexture(_backgroundTexture);

            //Logging.Debug("Bound background texture.");

            _backgroundProgram["projection_matrix"].SetValue(fov);
            _backgroundProgram["view_matrix"].SetValue(cameraView);

            //Logging.Debug("Bound background uniforms.");

            GlUtility.BindBuffer(_points);

            //Logging.Debug("Bound background points.");

            //vertexPosition
            GL.VertexAttribPointer(ShaderProgram.VertexPosition, 3, _points.PointerType, false, 5 * Marshal.SizeOf(typeof(float)), IntPtr.Zero);
            GL.EnableVertexAttribArray(ShaderProgram.VertexPosition);

            //Logging.Debug("Bound background positions to array.");

            GL.DisableVertexAttribArray(ShaderProgram.VertexColor);

            //Logging.Debug("Disabled VertexColor array.");

            GL.DisableVertexAttribArray(ShaderProgram.VertexSize);

            //textureCoords
            GL.VertexAttribPointer(ShaderProgram.TextureCoords, 2, _points.PointerType, false, 5 * Marshal.SizeOf(typeof(float)), Vector3.SizeInBytes);
            GL.EnableVertexAttribArray(ShaderProgram.TextureCoords);

            //Logging.Debug("Bound background texture coords to array.");

            GlUtility.BindBuffer(_backgroundElements);
            GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, IntPtr.Zero);

            //Logging.Debug("Exit background draw.");
        }
Esempio n. 5
0
        public void Draw(ShaderProgram program)
        {
            //Logging.Debug("Entering Draw.");
            if (_points.Count == 0)
            {
                //Logging.Debug("Exiting Draw.");
                return;
            }

            //program["pointSize"].SetValue((float)PixelSize);
            VBO <float> points = new VBO <float>(_points.ToArray());

            //Logging.Debug("Created VBO.");

            GlUtility.BindBuffer(points);

            //Logging.Debug("Buffer Bound.");
            GL.VertexAttribPointer(ShaderProgram.VertexPosition, 3, VertexAttribPointerType.Float, false, EightFloatDataSize, IntPtr.Zero);
            GL.EnableVertexAttribArray(ShaderProgram.VertexPosition);

            //Logging.Debug("Point pointer set.");

            GL.VertexAttribPointer(ShaderProgram.VertexColor, 4, VertexAttribPointerType.Float, false, EightFloatDataSize, Vector3.SizeInBytes);
            GL.EnableVertexAttribArray(ShaderProgram.VertexColor);

            GL.VertexAttribPointer(ShaderProgram.VertexSize, 1, VertexAttribPointerType.Float, false, EightFloatDataSize, Vector3.SizeInBytes + Vector4.SizeInBytes);
            GL.EnableVertexAttribArray(ShaderProgram.VertexSize);

            GL.DisableVertexAttribArray(ShaderProgram.TextureCoords);

            //Logging.Debug("Color pointer set.");

            //Logging.Debug("Beginning draw.");

            // draw the points
            GL.DrawArrays(PrimitiveType.Points, 0, points.Count / 8);

            //Logging.Debug("Draw completed for shape.");
            points.Dispose();

            //Logging.Debug("VBO Disposed.");
            //Logging.Debug("Exiting Draw.");
        }
Esempio n. 6
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 = DDS.DDSURFACEDESC2.FromBinaryReader(stream);                //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;
                InternalFormat      format;
                PixelInternalFormat pixelFormat;
                switch (imageData.PixelFormat.FourCC)   // check the compression type
                {
                case "DXT1":                            // DXT1 compression ratio is 8:1
                    format      = InternalFormat.CompressedRgbaS3tcDxt1Ext;
                    pixelFormat = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
                    factor      = 2;
                    blocksize   = 8;
                    break;

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

                case "DXT5":                            // DXT5 compression ratio is 4:1
                    format      = InternalFormat.CompressedRgbaS3tcDxt5Ext;
                    pixelFormat = 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      = InternalFormat.Rgba;
                        pixelFormat = PixelInternalFormat.Rgba;
                    }
                    else if (imageData.PixelFormat.ABitMask == unchecked ((int)0xff000000) &&
                             imageData.PixelFormat.RBitMask == 0x00ff0000 &&
                             imageData.PixelFormat.GBitMask == 0x0000ff00 &&
                             imageData.PixelFormat.BBitMask == 0x000000ff &&
                             imageData.PixelFormat.RGBBitCount == 32)
                    {
                        format      = InternalFormat.Rgba;
                        pixelFormat = PixelInternalFormat.Rgba;
                    }
                    else
                    {
                        throw new Exception(string.Format("File compression \"{0}\" is not supported.", imageData.PixelFormat.FourCC));
                    }
                    break;
                }

                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
                {
                    TextureTarget = (imageData.Height == 1 || imageData.Width == 1) ? TextureTarget.Texture1D : TextureTarget.Texture2D;
                    TextureID     = GlUtility.GenTexture();

                    GL.BindTexture(TextureTarget, TextureID);
                    GL.TexParameter(TextureTarget, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                    GL.TexParameter(TextureTarget, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.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
                        {
                            PixelType pixelType = imageData.PixelFormat.RGBBitCount == 16 ? PixelType.UnsignedShort4444Reversed : PixelType.UnsignedInt8888Reversed;

                            nSize = nWidth * nHeight * imageData.PixelFormat.RGBBitCount / 8;
                            GL.TexImage2D(TextureTarget, i, pixelFormat, nWidth, nHeight, 0, PixelFormat.Bgra, pixelType, (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();
                }
            }
        }