private static void DoCreateSpriteTexture(Bitmap SpriteTextureBitmap, SpriteTexture SpriteTexture, Color Transparent, bool DisposePrevious) { int Width = SpriteTextureBitmap.Width; int Height = SpriteTextureBitmap.Height; if (DisposePrevious) GL.DeleteTexture(SpriteTexture.Handle); SpriteTexture.Handle = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, SpriteTexture.Handle); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); // Sprite textures should not wrap. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); // Sprite textures should not wrap. // Correct anti-aliased image to better work with the OpenGL blending process, that only uses the alpha-channel to blend. BitmapData data = SpriteTextureBitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); if (Transparent != Color.Empty) { int j; byte R, G, B, A; R = Transparent.R; G = Transparent.G; B = Transparent.B; A = Transparent.A; int BmpSize = data.Stride * Height; byte[] Rgb = new byte[BmpSize]; Marshal.Copy(data.Scan0, Rgb, 0, BmpSize); for (j = 0; j < BmpSize; j += 4) { if (Rgb[j] == B && Rgb[j + 1] == G && Rgb[j + 2] == R && Rgb[j + 3] == A) { Rgb[j] = 0; Rgb[j + 1] = 0; Rgb[j + 2] = 0; Rgb[j + 3] = 0; } } Marshal.Copy(Rgb, 0, data.Scan0, BmpSize); } GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Width, Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); SpriteTextureBitmap.UnlockBits(data); SpriteTextureBitmap.Dispose(); }
/// <summary> /// Defines a new sprite texture. /// </summary> /// <param name="SpriteTextureBitmap">Sprite texture.</param> /// <param name="Offset">Offset to sprite anchor point.</param> /// <param name="Transparent">Color to be interpreted as transparent, in case transparency is not encoded using the alpha-channel.</param> /// <param name="DisposeBitmap">If bitmap is to be disposed after the sprite texture has been created.</param> /// <returns>Sprite texture index. Use this index when defining what texture to display for a sprite.</returns> public static int AddSpriteTexture(Bitmap SpriteTextureBitmap, Point Offset, Color Transparent, bool DisposeBitmap) { Bitmap Bmp = DisposeBitmap ? SpriteTextureBitmap : (Bitmap)SpriteTextureBitmap.Clone(); SpriteTexture SpriteTexture = new SpriteTexture(-1, new Size(SpriteTextureBitmap.Width, SpriteTextureBitmap.Height), Offset); int Result; lock (spriteTexturesDynamic) { Result = spriteTexturesDynamic.Count; spriteTexturesDynamic.Add(SpriteTexture); spriteTexturesStatic = spriteTexturesDynamic.ToArray(); } lock (openGLTasks) { openGLTasks.AddLast((sender, e) => DoCreateSpriteTexture(Bmp, SpriteTexture, Transparent, false)); } return Result; }