コード例 #1
0
        /// <summary>
        /// Given a bitmap (GDI+), create for it an OpenGL texture and return its ID
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns>the OGL texture id</returns>
        /// <remarks>in order to allow hardware acceleration, texture size must be power of two.</remarks>
        private uint CreateTexture(Bitmap bitmap)
        {
            try
            {
                //get the bitmap's dimensions
                int h = bitmap.Height;
                int w = bitmap.Width;
                int s = Math.Max(h, w);

                //calculate the closest power of two to match the bitmap's size
                //(thank god for high-school math...)
                double x = Math.Log(Convert.ToDouble(s)) / Math.Log(2.0);
                s = Convert.ToInt32(Math.Pow(2.0, Convert.ToDouble(Math.Ceiling(x))));

                int bufferSizeInPixels = s * s;

                //get the bitmap's raw data
                Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
                bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
                System.Drawing.Imaging.BitmapData bitmapData;
                bitmapData = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);



                byte[] bgrBuffer = new byte[bufferSizeInPixels * 3];

                //scale the bitmap to be a power of two
                unsafe
                {
                    fixed(byte *pBgrBuffer = bgrBuffer)
                    {
                        GLU.gluScaleImage(GL.GL_BGR_EXT, bitmap.Size.Width, bitmap.Size.Height, GL.GL_UNSIGNED_BYTE, bitmapData.Scan0.ToPointer(), s, s, GL.GL_UNSIGNED_BYTE, pBgrBuffer);
                    }
                }

                //create a new buffer to store the raw data and set the transparency color (alpha = 0)
                byte[] bgraBuffer = new byte[bufferSizeInPixels * 4];

                int posBgr  = 0;
                int posBgra = 0;
                for (int i = 0; i < bufferSizeInPixels; i++)
                {
                    bgraBuffer[posBgra]     = bgrBuffer[posBgr];     //B
                    bgraBuffer[posBgra + 1] = bgrBuffer[posBgr + 1]; //G
                    bgraBuffer[posBgra + 2] = bgrBuffer[posBgr + 2]; //R

                    //take care of the alpha
                    if (255 == bgrBuffer[posBgr] && 255 == bgrBuffer[posBgr + 1] && 255 == bgrBuffer[posBgr + 2])
                    {
                        bgraBuffer[posBgra + 3] = 0;
                    }
                    else
                    {
                        bgraBuffer[posBgra + 3] = 255;
                    }
                    posBgr  += 3;
                    posBgra += 4;
                }

                //create the texture
                uint[] texture = new uint[1];
                GL.glEnable(GL.GL_TEXTURE_2D);
                GL.glGenTextures(1, texture);
                GL.glBindTexture(GL.GL_TEXTURE_2D, texture[0]);

                //set the texture parameters
                GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, (int)GL.GL_LINEAR);
                GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, (int)GL.GL_LINEAR);
                GL.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, (int)GL.GL_MODULATE);

                unsafe
                {
                    fixed(byte *pBgraBuffer = bgraBuffer)
                    {
                        GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, (int)GL.GL_RGBA, s, s, 0, GL.GL_BGRA_EXT, GL.GL_UNSIGNED_BYTE, pBgraBuffer);
                    }
                }

                //unlock the bitmap from memory
                bitmap.UnlockBits(bitmapData);

                //return the newly created texture id
                return(texture[0]);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.Message);
            }
            return((uint)0);
        }