/// <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); }